|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [edk2] [PATCH v3 02/19] OvmfPkg: Add public headers from Xen Project.
On 2014-10-17 10:03:45, Anthony PERARD wrote:
> This patch imports publics headers in order to use features from Xen
> like XenStore, PV Block... There is only the necessary header files and
> there are only a few modifications in order to facilitate future merge of
> more recent header (that would be necessary to access new features).
>
> There is little modification compared to the original files:
> - Removed most of the unused part of the headers
> - Use of ZeroMem() instead of memset()
> - using #pragma pack(4) for IA32 compilation.
Usually EDK II uses pack(1) when concerned about structure layout. I'm
not saying you need to change this, but it does stand out.
> - Replace types to be more UEFI compliant using a script.
>
> OVMF, when built for IA32 arch, uses the gcc switch -malign-double. This
> change the alignment of fields in some struct compare to what is
> espected by Xen and any backends. To fix the alignment, the #pragma pack(4)
> directive is used around the struct that need it.
>
> Command to run to change types:
> find OvmfPkg/Include/IndustryStandard/Xen -type f -name '*.h' -exec sed
> --regexp-extended --file=fix_type_in_xen_includes.sed --in-place {} \;
Did you intend to include fix_type_in_xen_includes.sed?
Maybe you could mention the source (url, version) for the files? Was
it a direct copy into OvmfPkg/Include/IndustryStandard/Xen before
using the script?
How easy do you think someone could 'update' the files from Xen based
on the information you provided here?
> This line is commented instead of been change as I'm not sure why it
> does not compile (when s/char/CHAR8/), and it does not seems necessary
> so far.
> /* __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); */
Could 'unsigned char' => 'UINT8' help?
-Jordan
> in OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
>
> Avoid changing the 'long' that is not a type (with the first line).
> $ cat fix_type_in_xen_includes.sed
> /as long as/b
>
> s/([^a-zA-Z0-9_]|^)uint8_t([^a-zA-Z0-9_]|$)/\1UINT8\2/g
> s/([^a-zA-Z0-9_]|^)uint16_t([^a-zA-Z0-9_]|$)/\1UINT16\2/g
> s/([^a-zA-Z0-9_]|^)uint32_t([^a-zA-Z0-9_]|$)/\1UINT32\2/g
> s/([^a-zA-Z0-9_]|^)uint64_t([^a-zA-Z0-9_]|$)/\1UINT64\2/g
>
> s/([^a-zA-Z0-9_]|^)int8_t([^a-zA-Z0-9_]|$)/\1INT8\2/g
> s/([^a-zA-Z0-9_]|^)int16_t([^a-zA-Z0-9_]|$)/\1INT16\2/g
> s/([^a-zA-Z0-9_]|^)int32_t([^a-zA-Z0-9_]|$)/\1INT32\2/g
> s/([^a-zA-Z0-9_]|^)int64_t([^a-zA-Z0-9_]|$)/\1INT64\2/g
>
> s/([^a-zA-Z0-9_]|^)void([^a-zA-Z0-9_]|$)/\1VOID\2/g
> s/([^a-zA-Z0-9_]|^)unsigned int([^a-zA-Z0-9_]|$)/\1UINT32\2/g
> s/([^a-zA-Z0-9_]|^)int([^a-zA-Z0-9_]|$)/\1INT32\2/g
> s/([^a-zA-Z0-9_]|^)char([^a-zA-Z0-9_]|$)/\1CHAR8\2/g
> s/([^a-zA-Z0-9_]|^)unsigned long([^a-zA-Z0-9_]|$)/\1UINTN\2/g
> s/([^a-zA-Z0-9_]|^)long([^a-zA-Z0-9_]|$)/\1INTN\2/g
>
> License: This patch adds many files under the MIT licence.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
>
> ---
> Change in V3:
> - Remove unused header sched.h
> - moving xs_wire.h in a later patch, where it's first needed
> - moving io/blkif.h in a later patch (XenPvBlkDxe: Add BlockFront client)
> - moving event_channel.h in a later patch (XenBusDxe: Add Event Channel
> Notify)
> - using #pragma pack(4) for IA32
> - headers trimed down, removed most of the unused struct/define/...
> ---
> .../IndustryStandard/Xen/arch-x86/xen-x86_32.h | 59 +++
> .../IndustryStandard/Xen/arch-x86/xen-x86_64.h | 59 +++
> .../Include/IndustryStandard/Xen/arch-x86/xen.h | 112 ++++++
> OvmfPkg/Include/IndustryStandard/Xen/grant_table.h | 444
> +++++++++++++++++++++
> OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h | 37 ++
> OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h | 150 +++++++
> .../Include/IndustryStandard/Xen/io/protocols.h | 40 ++
> OvmfPkg/Include/IndustryStandard/Xen/io/ring.h | 312 +++++++++++++++
> OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h | 80 ++++
> OvmfPkg/Include/IndustryStandard/Xen/memory.h | 94 +++++
> OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h | 44 ++
> OvmfPkg/Include/IndustryStandard/Xen/xen.h | 341 ++++++++++++++++
> 12 files changed, 1772 insertions(+)
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/memory.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/xen.h
>
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
> b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
> new file mode 100644
> index 0000000..ed7e12b
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
> @@ -0,0 +1,59 @@
> +/******************************************************************************
> + * xen-x86_32.h
> + *
> + * Guest OS interface to x86 32-bit Xen.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2004-2007, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
> +#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
> +
> +/*
> + * Hypercall interface:
> + * Input: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6)
> + * Output: %eax
> + * Access is via hypercall page (set up by guest loader or via a Xen MSR):
> + * call hypercall_page + hypercall-number * 32
> + * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx)
> + */
> +
> +#ifndef __ASSEMBLY__
> +
> +struct arch_vcpu_info {
> + UINTN cr2;
> + UINTN pad[5]; /* sizeof(vcpu_info_t) == 64 */
> +};
> +typedef struct arch_vcpu_info arch_vcpu_info_t;
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
> b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
> new file mode 100644
> index 0000000..c5ef5d4
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
> @@ -0,0 +1,59 @@
> +/******************************************************************************
> + * xen-x86_64.h
> + *
> + * Guest OS interface to x86 64-bit Xen.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2004-2006, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
> +#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
> +
> +/*
> + * Hypercall interface:
> + * Input: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
> + * Output: %rax
> + * Access is via hypercall page (set up by guest loader or via a Xen MSR):
> + * call hypercall_page + hypercall-number * 32
> + * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi)
> + */
> +
> +#ifndef __ASSEMBLY__
> +
> +struct arch_vcpu_info {
> + UINTN cr2;
> + UINTN pad; /* sizeof(vcpu_info_t) == 64 */
> +};
> +typedef struct arch_vcpu_info arch_vcpu_info_t;
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> new file mode 100644
> index 0000000..951d57b
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> @@ -0,0 +1,112 @@
> +/******************************************************************************
> + * arch-x86/xen.h
> + *
> + * Guest OS interface to x86 Xen.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2004-2006, K A Fraser
> + */
> +
> +#include "../xen.h"
> +
> +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__
> +#define __XEN_PUBLIC_ARCH_X86_XEN_H__
> +
> +/* Structural guest handles introduced in 0x00030201. */
> +#if __XEN_INTERFACE_VERSION__ >= 0x00030201
> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
> + typedef struct { type *p; } __guest_handle_ ## name
> +#else
> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
> + typedef type * __guest_handle_ ## name
> +#endif
> +
> +/*
> + * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
> + * in a struct in memory.
> + * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
> + * hypercall argument.
> + * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but
> + * they might not be on other architectures.
> + */
> +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
> + ___DEFINE_XEN_GUEST_HANDLE(name, type); \
> + ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
> +#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
> +#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name
> +#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
> +#define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name)
> +#define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0)
> +#ifdef __XEN_TOOLS__
> +#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
> +#endif
> +#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
> +
> +#if defined(__i386__)
> +#include "xen-x86_32.h"
> +#elif defined(__x86_64__)
> +#include "xen-x86_64.h"
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +typedef UINTN xen_pfn_t;
> +#define PRI_xen_pfn "lx"
> +#endif
> +
> +#define XEN_HAVE_PV_UPCALL_MASK 1
> +
> +/* Maximum number of virtual CPUs in legacy multi-processor guests. */
> +#define XEN_LEGACY_MAX_VCPUS 32
> +
> +#ifndef __ASSEMBLY__
> +
> +typedef UINTN xen_ulong_t;
> +#define PRI_xen_ulong "lx"
> +
> +typedef UINT64 tsc_timestamp_t; /* RDTSC timestamp */
> +
> +#ifdef __i386__
> +#pragma pack(4)
> +#endif
> +struct arch_shared_info {
> + UINTN max_pfn; /* max pfn that appears in table */
> + /* Frame containing list of mfns containing list of mfns containing p2m.
> */
> + xen_pfn_t pfn_to_mfn_frame_list_list;
> + UINTN nmi_reason;
> + UINT64 pad[32];
> +};
> +typedef struct arch_shared_info arch_shared_info_t;
> +#ifdef __i386__
> +#pragma pack()
> +#endif
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
> b/OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
> new file mode 100644
> index 0000000..8725931
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
> @@ -0,0 +1,444 @@
> +/******************************************************************************
> + * grant_table.h
> + *
> + * Interface for granting foreign access to page frames, and receiving
> + * page-ownership transfers.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2004, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_GRANT_TABLE_H__
> +#define __XEN_PUBLIC_GRANT_TABLE_H__
> +
> +#include "xen.h"
> +
> +/*
> + * `incontents 150 gnttab Grant Tables
> + *
> + * Xen's grant tables provide a generic mechanism to memory sharing
> + * between domains. This shared memory interface underpins the split
> + * device drivers for block and network IO.
> + *
> + * Each domain has its own grant table. This is a data structure that
> + * is shared with Xen; it allows the domain to tell Xen what kind of
> + * permissions other domains have on its pages. Entries in the grant
> + * table are identified by grant references. A grant reference is an
> + * integer, which indexes into the grant table. It acts as a
> + * capability which the grantee can use to perform operations on the
> + * granterâs memory.
> + *
> + * This capability-based system allows shared-memory communications
> + * between unprivileged domains. A grant reference also encapsulates
> + * the details of a shared page, removing the need for a domain to
> + * know the real machine address of a page it is sharing. This makes
> + * it possible to share memory correctly with domains running in
> + * fully virtualised memory.
> + */
> +
> +/***********************************
> + * GRANT TABLE REPRESENTATION
> + */
> +
> +/* Some rough guidelines on accessing and updating grant-table entries
> + * in a concurrency-safe manner. For more information, Linux contains a
> + * reference implementation for guest OSes (drivers/xen/grant_table.c, see
> + *
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD
> + *
> + * NB. WMB is a no-op on current-generation x86 processors. However, a
> + * compiler barrier will still be required.
> + *
> + * Introducing a valid entry into the grant table:
> + * 1. Write ent->domid.
> + * 2. Write ent->frame:
> + * GTF_permit_access: Frame to which access is permitted.
> + * GTF_accept_transfer: Pseudo-phys frame slot being filled by new
> + * frame, or zero if none.
> + * 3. Write memory barrier (WMB).
> + * 4. Write ent->flags, inc. valid type.
> + *
> + * Invalidating an unused GTF_permit_access entry:
> + * 1. flags = ent->flags.
> + * 2. Observe that !(flags & (GTF_reading|GTF_writing)).
> + * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
> + * NB. No need for WMB as reuse of entry is control-dependent on success of
> + * step 3, and all architectures guarantee ordering of ctrl-dep writes.
> + *
> + * Invalidating an in-use GTF_permit_access entry:
> + * This cannot be done directly. Request assistance from the domain
> controller
> + * which can set a timeout on the use of a grant entry and take necessary
> + * action. (NB. This is not yet implemented!).
> + *
> + * Invalidating an unused GTF_accept_transfer entry:
> + * 1. flags = ent->flags.
> + * 2. Observe that !(flags & GTF_transfer_committed). [*]
> + * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
> + * NB. No need for WMB as reuse of entry is control-dependent on success of
> + * step 3, and all architectures guarantee ordering of ctrl-dep writes.
> + * [*] If GTF_transfer_committed is set then the grant entry is 'committed'.
> + * The guest must /not/ modify the grant entry until the address of the
> + * transferred frame is written. It is safe for the guest to spin
> waiting
> + * for this to occur (detect by observing GTF_transfer_completed in
> + * ent->flags).
> + *
> + * Invalidating a committed GTF_accept_transfer entry:
> + * 1. Wait for (ent->flags & GTF_transfer_completed).
> + *
> + * Changing a GTF_permit_access from writable to read-only:
> + * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing.
> + *
> + * Changing a GTF_permit_access from read-only to writable:
> + * Use SMP-safe bit-setting instruction.
> + */
> +
> +/*
> + * Reference to a grant entry in a specified domain's grant table.
> + */
> +typedef UINT32 grant_ref_t;
> +
> +/*
> + * A grant table comprises a packed array of grant entries in one or more
> + * page frames shared between Xen and a guest.
> + * [XEN]: This field is written by Xen and read by the sharing guest.
> + * [GST]: This field is written by the guest and read by Xen.
> + */
> +
> +/*
> + * Version 1 of the grant table entry structure is maintained purely
> + * for backwards compatibility. New guests should use version 2.
> + */
> +#if __XEN_INTERFACE_VERSION__ < 0x0003020a
> +#define grant_entry_v1 grant_entry
> +#define grant_entry_v1_t grant_entry_t
> +#endif
> +struct grant_entry_v1 {
> + /* GTF_xxx: various type and flag information. [XEN,GST] */
> + UINT16 flags;
> + /* The domain being granted foreign privileges. [GST] */
> + domid_t domid;
> + /*
> + * GTF_permit_access: Frame that @domid is allowed to map and access.
> [GST]
> + * GTF_accept_transfer: Frame whose ownership transferred by @domid.
> [XEN]
> + */
> + UINT32 frame;
> +};
> +typedef struct grant_entry_v1 grant_entry_v1_t;
> +
> +/* The first few grant table entries will be preserved across grant table
> + * version changes and may be pre-populated at domain creation by tools.
> + */
> +#define GNTTAB_NR_RESERVED_ENTRIES 8
> +#define GNTTAB_RESERVED_CONSOLE 0
> +#define GNTTAB_RESERVED_XENSTORE 1
> +
> +/*
> + * Type of grant entry.
> + * GTF_invalid: This grant entry grants no privileges.
> + * GTF_permit_access: Allow @domid to map/access @frame.
> + * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame
> + * to this guest. Xen writes the page number to @frame.
> + * GTF_transitive: Allow @domid to transitively access a subrange of
> + * @trans_grant in @trans_domid. No mappings are allowed.
> + */
> +#define GTF_invalid (0U<<0)
> +#define GTF_permit_access (1U<<0)
> +#define GTF_accept_transfer (2U<<0)
> +#define GTF_transitive (3U<<0)
> +#define GTF_type_mask (3U<<0)
> +
> +/*
> + * Subflags for GTF_permit_access.
> + * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
> + * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
> + * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
> + * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant
> [GST]
> + * GTF_sub_page: Grant access to only a subrange of the page. @domid
> + * will only be allowed to copy from the grant, and not
> + * map it. [GST]
> + */
> +#define _GTF_readonly (2)
> +#define GTF_readonly (1U<<_GTF_readonly)
> +#define _GTF_reading (3)
> +#define GTF_reading (1U<<_GTF_reading)
> +#define _GTF_writing (4)
> +#define GTF_writing (1U<<_GTF_writing)
> +#define _GTF_PWT (5)
> +#define GTF_PWT (1U<<_GTF_PWT)
> +#define _GTF_PCD (6)
> +#define GTF_PCD (1U<<_GTF_PCD)
> +#define _GTF_PAT (7)
> +#define GTF_PAT (1U<<_GTF_PAT)
> +#define _GTF_sub_page (8)
> +#define GTF_sub_page (1U<<_GTF_sub_page)
> +
> +/*
> + * Subflags for GTF_accept_transfer:
> + * GTF_transfer_committed: Xen sets this flag to indicate that it is
> committed
> + * to transferring ownership of a page frame. When a guest sees this
> flag
> + * it must /not/ modify the grant entry until GTF_transfer_completed is
> + * set by Xen.
> + * GTF_transfer_completed: It is safe for the guest to spin-wait on this
> flag
> + * after reading GTF_transfer_committed. Xen will always write the frame
> + * address, followed by ORing this flag, in a timely manner.
> + */
> +#define _GTF_transfer_committed (2)
> +#define GTF_transfer_committed (1U<<_GTF_transfer_committed)
> +#define _GTF_transfer_completed (3)
> +#define GTF_transfer_completed (1U<<_GTF_transfer_completed)
> +
> +/*
> + * Version 2 grant table entries. These fulfil the same role as
> + * version 1 entries, but can represent more complicated operations.
> + * Any given domain will have either a version 1 or a version 2 table,
> + * and every entry in the table will be the same version.
> + *
> + * The interface by which domains use grant references does not depend
> + * on the grant table version in use by the other domain.
> + */
> +#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
> +/*
> + * Version 1 and version 2 grant entries share a common prefix. The
> + * fields of the prefix are documented as part of struct
> + * grant_entry_v1.
> + */
> +struct grant_entry_header {
> + UINT16 flags;
> + domid_t domid;
> +};
> +typedef struct grant_entry_header grant_entry_header_t;
> +
> +/*
> + * Version 2 of the grant entry structure.
> + */
> +union grant_entry_v2 {
> + grant_entry_header_t hdr;
> +
> + /*
> + * This member is used for V1-style full page grants, where either:
> + *
> + * -- hdr.type is GTF_accept_transfer, or
> + * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.
> + *
> + * In that case, the frame field has the same semantics as the
> + * field of the same name in the V1 entry structure.
> + */
> + struct {
> + grant_entry_header_t hdr;
> + UINT32 pad0;
> + UINT64 frame;
> + } full_page;
> +
> + /*
> + * If the grant type is GTF_grant_access and GTF_sub_page is set,
> + * @domid is allowed to access bytes [@page_off,@page_off+@length)
> + * in frame @frame.
> + */
> + struct {
> + grant_entry_header_t hdr;
> + UINT16 page_off;
> + UINT16 length;
> + UINT64 frame;
> + } sub_page;
> +
> + /*
> + * If the grant is GTF_transitive, @domid is allowed to use the
> + * grant @gref in domain @trans_domid, as if it was the local
> + * domain. Obviously, the transitive access must be compatible
> + * with the original grant.
> + *
> + * The current version of Xen does not allow transitive grants
> + * to be mapped.
> + */
> + struct {
> + grant_entry_header_t hdr;
> + domid_t trans_domid;
> + UINT16 pad0;
> + grant_ref_t gref;
> + } transitive;
> +
> + UINT32 __spacer[4]; /* Pad to a power of two */
> +};
> +typedef union grant_entry_v2 grant_entry_v2_t;
> +
> +typedef UINT16 grant_status_t;
> +
> +#endif /* __XEN_INTERFACE_VERSION__ */
> +
> +/***********************************
> + * GRANT TABLE QUERIES AND USES
> + */
> +
> +/* ` enum neg_errnoval
> + * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd,
> + * ` VOID *args,
> + * ` UINT32 count)
> + * `
> + *
> + * @args points to an array of a per-command data structure. The array
> + * has @count members
> + */
> +
> +/* ` enum grant_table_op { // GNTTABOP_* => struct gnttab_* */
> +#define GNTTABOP_map_grant_ref 0
> +#define GNTTABOP_unmap_grant_ref 1
> +/* ` } */
> +
> +/*
> + * Handle to track a mapping created via a grant reference.
> + */
> +typedef UINT32 grant_handle_t;
> +
> +/*
> + * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access
> + * by devices and/or host CPUs. If successful, <handle> is a tracking number
> + * that must be presented later to destroy the mapping(s). On error, <handle>
> + * is a negative status code.
> + * NOTES:
> + * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address
> + * via which I/O devices may access the granted frame.
> + * 2. If GNTMAP_host_map is specified then a mapping will be added at
> + * either a host virtual address in the current address space, or at
> + * a PTE at the specified machine address. The type of mapping to
> + * perform is selected through the GNTMAP_contains_pte flag, and the
> + * address is specified in <host_addr>.
> + * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a
> + * host mapping is destroyed by other means then it is *NOT* guaranteed
> + * to be accounted to the correct grant reference!
> + */
> +struct gnttab_map_grant_ref {
> + /* IN parameters. */
> + UINT64 host_addr;
> + UINT32 flags; /* GNTMAP_* */
> + grant_ref_t ref;
> + domid_t dom;
> + /* OUT parameters. */
> + INT16 status; /* => enum grant_status */
> + grant_handle_t handle;
> + UINT64 dev_bus_addr;
> +};
> +typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;
> +DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);
> +
> +/*
> + * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
> + * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that
> + * field is ignored. If non-zero, they must refer to a device/host mapping
> + * that is tracked by <handle>
> + * NOTES:
> + * 1. The call may fail in an undefined manner if either mapping is not
> + * tracked by <handle>.
> + * 3. After executing a batch of unmaps, it is guaranteed that no stale
> + * mappings will remain in the device or host TLBs.
> + */
> +struct gnttab_unmap_grant_ref {
> + /* IN parameters. */
> + UINT64 host_addr;
> + UINT64 dev_bus_addr;
> + grant_handle_t handle;
> + /* OUT parameters. */
> + INT16 status; /* => enum grant_status */
> +};
> +typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;
> +DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);
> +
> +/*
> + * Bitfield values for gnttab_map_grant_ref.flags.
> + */
> + /* Map the grant entry for access by I/O devices. */
> +#define _GNTMAP_device_map (0)
> +#define GNTMAP_device_map (1<<_GNTMAP_device_map)
> + /* Map the grant entry for access by host CPUs. */
> +#define _GNTMAP_host_map (1)
> +#define GNTMAP_host_map (1<<_GNTMAP_host_map)
> + /* Accesses to the granted frame will be restricted to read-only access. */
> +#define _GNTMAP_readonly (2)
> +#define GNTMAP_readonly (1<<_GNTMAP_readonly)
> + /*
> + * GNTMAP_host_map subflag:
> + * 0 => The host mapping is usable only by the guest OS.
> + * 1 => The host mapping is usable by guest OS + current application.
> + */
> +#define _GNTMAP_application_map (3)
> +#define GNTMAP_application_map (1<<_GNTMAP_application_map)
> +
> + /*
> + * GNTMAP_contains_pte subflag:
> + * 0 => This map request contains a host virtual address.
> + * 1 => This map request contains the machine addess of the PTE to update.
> + */
> +#define _GNTMAP_contains_pte (4)
> +#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)
> +
> +#define _GNTMAP_can_fail (5)
> +#define GNTMAP_can_fail (1<<_GNTMAP_can_fail)
> +
> +/*
> + * Bits to be placed in guest kernel available PTE bits (architecture
> + * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).
> + */
> +#define _GNTMAP_guest_avail0 (16)
> +#define GNTMAP_guest_avail_mask ((UINT32)~0 << _GNTMAP_guest_avail0)
> +
> +/*
> + * Values for error status returns. All errors are -ve.
> + */
> +/* ` enum grant_status { */
> +#define GNTST_okay (0) /* Normal return.
> */
> +#define GNTST_general_error (-1) /* General undefined error.
> */
> +#define GNTST_bad_domain (-2) /* Unrecognsed domain id.
> */
> +#define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref.
> */
> +#define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle.
> */
> +#define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map.
> */
> +#define GNTST_bad_dev_addr (-6) /* Inappropriate device address to
> unmap.*/
> +#define GNTST_no_device_space (-7) /* Out of space in I/O MMU.
> */
> +#define GNTST_permission_denied (-8) /* Not enough privilege for operation.
> */
> +#define GNTST_bad_page (-9) /* Specified page was invalid for op.
> */
> +#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary.
> */
> +#define GNTST_address_too_big (-11) /* transfer page address too large.
> */
> +#define GNTST_eagain (-12) /* Operation not done; try again.
> */
> +/* ` } */
> +
> +#define GNTTABOP_error_msgs { \
> + "okay", \
> + "undefined error", \
> + "unrecognised domain id", \
> + "invalid grant reference", \
> + "invalid mapping handle", \
> + "invalid virtual address", \
> + "invalid device address", \
> + "no spare translation slot in the I/O MMU", \
> + "permission denied", \
> + "bad page", \
> + "copy arguments cross page boundary", \
> + "page address size too large", \
> + "operation not done; try again" \
> +}
> +
> +#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
> b/OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
> new file mode 100644
> index 0000000..120f62f
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
> @@ -0,0 +1,37 @@
> +/*
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
> +#define __XEN_PUBLIC_HVM_HVM_OP_H__
> +
> +#include "../xen.h"
> +
> +/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */
> +#define HVMOP_set_param 0
> +#define HVMOP_get_param 1
> +struct xen_hvm_param {
> + domid_t domid; /* IN */
> + UINT32 index; /* IN */
> + UINT64 value; /* IN/OUT */
> +};
> +typedef struct xen_hvm_param xen_hvm_param_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
> +
> +#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
> b/OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
> new file mode 100644
> index 0000000..517a184
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
> @@ -0,0 +1,150 @@
> +/*
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
> +#define __XEN_PUBLIC_HVM_PARAMS_H__
> +
> +#include "hvm_op.h"
> +
> +/*
> + * Parameter space for HVMOP_{set,get}_param.
> + */
> +
> +/*
> + * How should CPU0 event-channel notifications be delivered?
> + * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
> + * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
> + * Domain = val[47:32], Bus = val[31:16],
> + * DevFn = val[15: 8], IntX = val[ 1: 0]
> + * val[63:56] == 2: val[7:0] is a vector number, check for
> + * XENFEAT_hvm_callback_vector to know if this delivery
> + * method is available.
> + * If val == 0 then CPU0 event-channel notifications are not delivered.
> + */
> +#define HVM_PARAM_CALLBACK_IRQ 0
> +
> +/*
> + * These are not used by Xen. They are here for convenience of HVM-guest
> + * xenbus implementations.
> + */
> +#define HVM_PARAM_STORE_PFN 1
> +#define HVM_PARAM_STORE_EVTCHN 2
> +
> +#define HVM_PARAM_PAE_ENABLED 4
> +
> +#define HVM_PARAM_IOREQ_PFN 5
> +
> +#define HVM_PARAM_BUFIOREQ_PFN 6
> +#define HVM_PARAM_BUFIOREQ_EVTCHN 26
> +
> +#if defined(__i386__) || defined(__x86_64__)
> +
> +/* Expose Viridian interfaces to this HVM guest? */
> +#define HVM_PARAM_VIRIDIAN 9
> +
> +#endif
> +
> +/*
> + * Set mode for virtual timers (currently x86 only):
> + * delay_for_missed_ticks (default):
> + * Do not advance a vcpu's time beyond the correct delivery time for
> + * interrupts that have been missed due to preemption. Deliver missed
> + * interrupts when the vcpu is rescheduled and advance the vcpu's virtual
> + * time stepwise for each one.
> + * no_delay_for_missed_ticks:
> + * As above, missed interrupts are delivered, but guest time always tracks
> + * wallclock (i.e., real) time while doing so.
> + * no_missed_ticks_pending:
> + * No missed interrupts are held pending. Instead, to ensure ticks are
> + * delivered at some non-zero rate, if we detect missed ticks then the
> + * internal tick alarm is not disabled if the VCPU is preempted during the
> + * next tick period.
> + * one_missed_tick_pending:
> + * Missed interrupts are collapsed together and delivered as one 'late
> tick'.
> + * Guest time always tracks wallclock (i.e., real) time.
> + */
> +#define HVM_PARAM_TIMER_MODE 10
> +#define HVMPTM_delay_for_missed_ticks 0
> +#define HVMPTM_no_delay_for_missed_ticks 1
> +#define HVMPTM_no_missed_ticks_pending 2
> +#define HVMPTM_one_missed_tick_pending 3
> +
> +/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
> +#define HVM_PARAM_HPET_ENABLED 11
> +
> +/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
> +#define HVM_PARAM_IDENT_PT 12
> +
> +/* Device Model domain, defaults to 0. */
> +#define HVM_PARAM_DM_DOMAIN 13
> +
> +/* ACPI S state: currently support S0 and S3 on x86. */
> +#define HVM_PARAM_ACPI_S_STATE 14
> +
> +/* TSS used on Intel when CR0.PE=0. */
> +#define HVM_PARAM_VM86_TSS 15
> +
> +/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
> +#define HVM_PARAM_VPT_ALIGN 16
> +
> +/* Console debug shared memory ring and event channel */
> +#define HVM_PARAM_CONSOLE_PFN 17
> +#define HVM_PARAM_CONSOLE_EVTCHN 18
> +
> +/*
> + * Select location of ACPI PM1a and TMR control blocks. Currently two
> locations
> + * are supported, specified by version 0 or 1 in this parameter:
> + * - 0: default, use the old addresses
> + * PM1A_EVT == 0x1f40; PM1A_CNT == 0x1f44; PM_TMR == 0x1f48
> + * - 1: use the new default qemu addresses
> + * PM1A_EVT == 0xb000; PM1A_CNT == 0xb004; PM_TMR == 0xb008
> + * You can find these address definitions in <hvm/ioreq.h>
> + */
> +#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
> +
> +/* Enable blocking memory events, async or sync (pause vcpu until response)
> + * onchangeonly indicates messages only on a change of value */
> +#define HVM_PARAM_MEMORY_EVENT_CR0 20
> +#define HVM_PARAM_MEMORY_EVENT_CR3 21
> +#define HVM_PARAM_MEMORY_EVENT_CR4 22
> +#define HVM_PARAM_MEMORY_EVENT_INT3 23
> +#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25
> +#define HVM_PARAM_MEMORY_EVENT_MSR 30
> +
> +#define HVMPME_MODE_MASK (3 << 0)
> +#define HVMPME_mode_disabled 0
> +#define HVMPME_mode_async 1
> +#define HVMPME_mode_sync 2
> +#define HVMPME_onchangeonly (1 << 2)
> +
> +/* Boolean: Enable nestedhvm (hvm only) */
> +#define HVM_PARAM_NESTEDHVM 24
> +
> +/* Params for the mem event rings */
> +#define HVM_PARAM_PAGING_RING_PFN 27
> +#define HVM_PARAM_ACCESS_RING_PFN 28
> +#define HVM_PARAM_SHARING_RING_PFN 29
> +
> +/* SHUTDOWN_* action in case of a triple fault */
> +#define HVM_PARAM_TRIPLE_FAULT_REASON 31
> +
> +#define HVM_NR_PARAMS 32
> +
> +#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
> b/OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
> new file mode 100644
> index 0000000..80b196b
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
> @@ -0,0 +1,40 @@
> +/******************************************************************************
> + * protocols.h
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef __XEN_PROTOCOLS_H__
> +#define __XEN_PROTOCOLS_H__
> +
> +#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi"
> +#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi"
> +#define XEN_IO_PROTO_ABI_ARM "arm-abi"
> +
> +#if defined(__i386__)
> +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
> +#elif defined(__x86_64__)
> +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
> +#elif defined(__arm__) || defined(__aarch64__)
> +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM
> +#else
> +# error arch fixup needed here
> +#endif
> +
> +#endif
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
> b/OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
> new file mode 100644
> index 0000000..a8e9ea0
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
> @@ -0,0 +1,312 @@
> +/******************************************************************************
> + * ring.h
> + *
> + * Shared producer-consumer ring macros.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Tim Deegan and Andrew Warfield November 2004.
> + */
> +
> +#ifndef __XEN_PUBLIC_IO_RING_H__
> +#define __XEN_PUBLIC_IO_RING_H__
> +
> +#include "../xen-compat.h"
> +
> +#if __XEN_INTERFACE_VERSION__ < 0x00030208
> +#define xen_mb() mb()
> +#define xen_rmb() rmb()
> +#define xen_wmb() wmb()
> +#endif
> +
> +typedef UINT32 RING_IDX;
> +
> +/* Round a 32-bit unsigned constant down to the nearest power of two. */
> +#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) &
> 0x1))
> +#define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
> +#define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
> +#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
> +#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x))
> +
> +/*
> + * Calculate size of a shared ring, given the total available space for the
> + * ring and indexes (_sz), and the name tag of the request/response
> structure.
> + * A ring contains as many entries as will fit, rounded down to the nearest
> + * power of two (so we can mask with (size-1) to loop around).
> + */
> +#define __CONST_RING_SIZE(_s, _sz) \
> + (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
> + sizeof(((struct _s##_sring *)0)->ring[0])))
> +/*
> + * The same for passing in an actual pointer instead of a name tag.
> + */
> +#define __RING_SIZE(_s, _sz) \
> + (__RD32(((_sz) - (INTN)(_s)->ring + (INTN)(_s)) / sizeof((_s)->ring[0])))
> +
> +/*
> + * Macros to make the correct C datatypes for a new kind of ring.
> + *
> + * To make a new ring datatype, you need to have two message structures,
> + * let's say request_t, and response_t already defined.
> + *
> + * In a header where you want the ring datatype declared, you then do:
> + *
> + * DEFINE_RING_TYPES(mytag, request_t, response_t);
> + *
> + * These expand out to give you a set of types, as you can see below.
> + * The most important of these are:
> + *
> + * mytag_sring_t - The shared ring.
> + * mytag_front_ring_t - The 'front' half of the ring.
> + * mytag_back_ring_t - The 'back' half of the ring.
> + *
> + * To initialize a ring in your code you need to know the location and size
> + * of the shared memory area (PAGE_SIZE, for instance). To initialise
> + * the front half:
> + *
> + * mytag_front_ring_t front_ring;
> + * SHARED_RING_INIT((mytag_sring_t *)shared_page);
> + * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
> + *
> + * Initializing the back follows similarly (note that only the front
> + * initializes the shared ring):
> + *
> + * mytag_back_ring_t back_ring;
> + * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
> + */
> +
> +#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \
> + \
> +/* Shared ring entry */ \
> +union __name##_sring_entry { \
> + __req_t req; \
> + __rsp_t rsp; \
> +}; \
> + \
> +/* Shared ring page */ \
> +struct __name##_sring { \
> + RING_IDX req_prod, req_event; \
> + RING_IDX rsp_prod, rsp_event; \
> + union { \
> + struct { \
> + UINT8 smartpoll_active; \
> + } netif; \
> + struct { \
> + UINT8 msg; \
> + } tapif_user; \
> + UINT8 pvt_pad[4]; \
> + } private; \
> + UINT8 __pad[44]; \
> + union __name##_sring_entry ring[1]; /* variable-length */ \
> +}; \
> + \
> +/* "Front" end's private variables */ \
> +struct __name##_front_ring { \
> + RING_IDX req_prod_pvt; \
> + RING_IDX rsp_cons; \
> + UINT32 nr_ents; \
> + struct __name##_sring *sring; \
> +}; \
> + \
> +/* "Back" end's private variables */ \
> +struct __name##_back_ring { \
> + RING_IDX rsp_prod_pvt; \
> + RING_IDX req_cons; \
> + UINT32 nr_ents; \
> + struct __name##_sring *sring; \
> +}; \
> + \
> +/* Syntactic sugar */ \
> +typedef struct __name##_sring __name##_sring_t; \
> +typedef struct __name##_front_ring __name##_front_ring_t; \
> +typedef struct __name##_back_ring __name##_back_ring_t
> +
> +/*
> + * Macros for manipulating rings.
> + *
> + * FRONT_RING_whatever works on the "front end" of a ring: here
> + * requests are pushed on to the ring and responses taken off it.
> + *
> + * BACK_RING_whatever works on the "back end" of a ring: here
> + * requests are taken off the ring and responses put on.
> + *
> + * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.
> + * This is OK in 1-for-1 request-response situations where the
> + * requestor (front end) never has more than RING_SIZE()-1
> + * outstanding requests.
> + */
> +
> +/* Initialising empty rings */
> +#define SHARED_RING_INIT(_s) do { \
> + (_s)->req_prod = (_s)->rsp_prod = 0; \
> + (_s)->req_event = (_s)->rsp_event = 1; \
> + (VOID)ZeroMem((_s)->private.pvt_pad, sizeof((_s)->private.pvt_pad)); \
> + (VOID)ZeroMem((_s)->__pad, sizeof((_s)->__pad)); \
> +} while(0)
> +
> +#define FRONT_RING_INIT(_r, _s, __size) do { \
> + (_r)->req_prod_pvt = 0; \
> + (_r)->rsp_cons = 0; \
> + (_r)->nr_ents = __RING_SIZE(_s, __size); \
> + (_r)->sring = (_s); \
> +} while (0)
> +
> +#define BACK_RING_INIT(_r, _s, __size) do { \
> + (_r)->rsp_prod_pvt = 0; \
> + (_r)->req_cons = 0; \
> + (_r)->nr_ents = __RING_SIZE(_s, __size); \
> + (_r)->sring = (_s); \
> +} while (0)
> +
> +/* How big is this ring? */
> +#define RING_SIZE(_r) \
> + ((_r)->nr_ents)
> +
> +/* Number of free requests (for use on front side only). */
> +#define RING_FREE_REQUESTS(_r) \
> + (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
> +
> +/* Test if there is an empty slot available on the front ring.
> + * (This is only meaningful from the front. )
> + */
> +#define RING_FULL(_r) \
> + (RING_FREE_REQUESTS(_r) == 0)
> +
> +/* Test if there are outstanding messages to be processed on a ring. */
> +#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
> + ((_r)->sring->rsp_prod - (_r)->rsp_cons)
> +
> +#ifdef __GNUC__
> +#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
> + UINT32 req = (_r)->sring->req_prod - (_r)->req_cons; \
> + UINT32 rsp = RING_SIZE(_r) - \
> + ((_r)->req_cons - (_r)->rsp_prod_pvt); \
> + req < rsp ? req : rsp; \
> +})
> +#else
> +/* Same as above, but without the nice GCC ({ ... }) syntax. */
> +#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
> + ((((_r)->sring->req_prod - (_r)->req_cons) < \
> + (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
> + ((_r)->sring->req_prod - (_r)->req_cons) : \
> + (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
> +#endif
> +
> +/* Direct access to individual ring elements, by index. */
> +#define RING_GET_REQUEST(_r, _idx) \
> + (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
> +
> +#define RING_GET_RESPONSE(_r, _idx) \
> + (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
> +
> +/* Loop termination condition: Would the specified index overflow the ring?
> */
> +#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
> + (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
> +
> +/* Ill-behaved frontend determination: Can there be this many requests? */
> +#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \
> + (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
> +
> +#define RING_PUSH_REQUESTS(_r) do { \
> + xen_wmb(); /* back sees requests /before/ updated producer index */ \
> + (_r)->sring->req_prod = (_r)->req_prod_pvt; \
> +} while (0)
> +
> +#define RING_PUSH_RESPONSES(_r) do { \
> + xen_wmb(); /* front sees resps /before/ updated producer index */ \
> + (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
> +} while (0)
> +
> +/*
> + * Notification hold-off (req_event and rsp_event):
> + *
> + * When queueing requests or responses on a shared ring, it may not always be
> + * necessary to notify the remote end. For example, if requests are in flight
> + * in a backend, the front may be able to queue further requests without
> + * notifying the back (if the back checks for new requests when it queues
> + * responses).
> + *
> + * When enqueuing requests or responses:
> + *
> + * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second
> argument
> + * is a boolean return value. True indicates that the receiver requires an
> + * asynchronous notification.
> + *
> + * After dequeuing requests or responses (before sleeping the connection):
> + *
> + * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
> + * The second argument is a boolean return value. True indicates that there
> + * are pending messages on the ring (i.e., the connection should not be put
> + * to sleep).
> + *
> + * These macros will set the req_event/rsp_event field to trigger a
> + * notification on the very next message that is enqueued. If you want to
> + * create batches of work (i.e., only receive a notification after several
> + * messages have been enqueued) then you will need to create a customised
> + * version of the FINAL_CHECK macro in your own code, which sets the event
> + * field appropriately.
> + */
> +
> +#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \
> + RING_IDX __old = (_r)->sring->req_prod; \
> + RING_IDX __new = (_r)->req_prod_pvt; \
> + xen_wmb(); /* back sees requests /before/ updated producer index */ \
> + (_r)->sring->req_prod = __new; \
> + xen_mb(); /* back sees new requests /before/ we check req_event */ \
> + (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
> + (RING_IDX)(__new - __old)); \
> +} while (0)
> +
> +#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \
> + RING_IDX __old = (_r)->sring->rsp_prod; \
> + RING_IDX __new = (_r)->rsp_prod_pvt; \
> + xen_wmb(); /* front sees resps /before/ updated producer index */ \
> + (_r)->sring->rsp_prod = __new; \
> + xen_mb(); /* front sees new resps /before/ we check rsp_event */ \
> + (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
> + (RING_IDX)(__new - __old)); \
> +} while (0)
> +
> +#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \
> + (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
> + if (_work_to_do) break; \
> + (_r)->sring->req_event = (_r)->req_cons + 1; \
> + xen_mb(); \
> + (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
> +} while (0)
> +
> +#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \
> + (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
> + if (_work_to_do) break; \
> + (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
> + xen_mb(); \
> + (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
> +} while (0)
> +
> +#endif /* __XEN_PUBLIC_IO_RING_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
> b/OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
> new file mode 100644
> index 0000000..927f9db
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
> @@ -0,0 +1,80 @@
> +/*****************************************************************************
> + * xenbus.h
> + *
> + * Xenbus protocol details.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (C) 2005 XenSource Ltd.
> + */
> +
> +#ifndef _XEN_PUBLIC_IO_XENBUS_H
> +#define _XEN_PUBLIC_IO_XENBUS_H
> +
> +/*
> + * The state of either end of the Xenbus, i.e. the current communication
> + * status of initialisation across the bus. States here imply nothing about
> + * the state of the connection between the driver and the kernel's device
> + * layers.
> + */
> +enum xenbus_state {
> + XenbusStateUnknown = 0,
> +
> + XenbusStateInitialising = 1,
> +
> + /*
> + * InitWait: Finished early initialisation but waiting for information
> + * from the peer or hotplug scripts.
> + */
> + XenbusStateInitWait = 2,
> +
> + /*
> + * Initialised: Waiting for a connection from the peer.
> + */
> + XenbusStateInitialised = 3,
> +
> + XenbusStateConnected = 4,
> +
> + /*
> + * Closing: The device is being closed due to an error or an unplug
> event.
> + */
> + XenbusStateClosing = 5,
> +
> + XenbusStateClosed = 6,
> +
> + /*
> + * Reconfiguring: The device is being reconfigured.
> + */
> + XenbusStateReconfiguring = 7,
> +
> + XenbusStateReconfigured = 8
> +};
> +typedef enum xenbus_state XenbusState;
> +
> +#endif /* _XEN_PUBLIC_IO_XENBUS_H */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/memory.h
> b/OvmfPkg/Include/IndustryStandard/Xen/memory.h
> new file mode 100644
> index 0000000..00156a4
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/memory.h
> @@ -0,0 +1,94 @@
> +/******************************************************************************
> + * memory.h
> + *
> + * Memory reservation and information.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
> + */
> +
> +#ifndef __XEN_PUBLIC_MEMORY_H__
> +#define __XEN_PUBLIC_MEMORY_H__
> +
> +#include "xen.h"
> +
> +/* Source mapping space. */
> +/* ` enum phys_map_space { */
> +#define XENMAPSPACE_shared_info 0 /* shared info page */
> +#define XENMAPSPACE_grant_table 1 /* grant table page */
> +#define XENMAPSPACE_gmfn 2 /* GMFN */
> +#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap
> only. */
> +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
> + * XENMEM_add_to_physmap_batch only. */
> +/* ` } */
> +
> +/*
> + * Sets the GPFN at which a particular page appears in the specified guest's
> + * pseudophysical address space.
> + * arg == addr of xen_add_to_physmap_t.
> + */
> +#define XENMEM_add_to_physmap 7
> +struct xen_add_to_physmap {
> + /* Which domain to change the mapping for. */
> + domid_t domid;
> +
> + /* Number of pages to go through for gmfn_range */
> + UINT16 size;
> +
> + UINT32 space; /* => enum phys_map_space */
> +
> +#define XENMAPIDX_grant_table_status 0x80000000
> +
> + /* Index into space being mapped. */
> + xen_ulong_t idx;
> +
> + /* GPFN in domid where the source mapping page should appear. */
> + xen_pfn_t gpfn;
> +};
> +typedef struct xen_add_to_physmap xen_add_to_physmap_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
> +
> +/*
> + * Unmaps the page appearing at a particular GPFN from the specified guest's
> + * pseudophysical address space.
> + * arg == addr of xen_remove_from_physmap_t.
> + */
> +#define XENMEM_remove_from_physmap 15
> +struct xen_remove_from_physmap {
> + /* Which domain to change the mapping for. */
> + domid_t domid;
> +
> + /* GPFN of the current mapping of the page. */
> + xen_pfn_t gpfn;
> +};
> +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
> +
> +#endif /* __XEN_PUBLIC_MEMORY_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
> b/OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
> new file mode 100644
> index 0000000..3eb80a0
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
> @@ -0,0 +1,44 @@
> +/******************************************************************************
> + * xen-compat.h
> + *
> + * Guest OS interface to Xen. Compatibility layer.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2006, Christian Limpach
> + */
> +
> +#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
> +#define __XEN_PUBLIC_XEN_COMPAT_H__
> +
> +#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040400
> +
> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
> +/* Xen is built with matching headers and implements the latest interface. */
> +#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__
> +#elif !defined(__XEN_INTERFACE_VERSION__)
> +/* Guests which do not specify a version get the legacy interface. */
> +#define __XEN_INTERFACE_VERSION__ 0x00000000
> +#endif
> +
> +#if __XEN_INTERFACE_VERSION__ > __XEN_LATEST_INTERFACE_VERSION__
> +#error "These header files do not support the requested interface version."
> +#endif
> +
> +#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> new file mode 100644
> index 0000000..b93bd47
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> @@ -0,0 +1,341 @@
> +/******************************************************************************
> + * xen.h
> + *
> + * Guest OS interface to Xen.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
> and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2004, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_XEN_H__
> +#define __XEN_PUBLIC_XEN_H__
> +
> +#include "xen-compat.h"
> +
> +#if defined(__i386__) || defined(__x86_64__)
> +#include "arch-x86/xen.h"
> +#elif defined(__arm__) || defined (__aarch64__)
> +#include "arch-arm.h"
> +#else
> +#error "Unsupported architecture"
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +/* Guest handles for primitive C types. */
> +DEFINE_XEN_GUEST_HANDLE(CHAR8);
> +/* __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); */
> +DEFINE_XEN_GUEST_HANDLE(INT32);
> +__DEFINE_XEN_GUEST_HANDLE(uint, UINT32);
> +#if __XEN_INTERFACE_VERSION__ < 0x00040300
> +DEFINE_XEN_GUEST_HANDLE(INTN);
> +__DEFINE_XEN_GUEST_HANDLE(ulong, UINTN);
> +#endif
> +DEFINE_XEN_GUEST_HANDLE(VOID);
> +
> +DEFINE_XEN_GUEST_HANDLE(UINT64);
> +DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
> +DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
> +#endif
> +
> +/*
> + * HYPERCALLS
> + */
> +
> +/* `incontents 100 hcalls List of hypercalls
> + * ` enum hypercall_num { // __HYPERVISOR_* => HYPERVISOR_*()
> + */
> +
> +#define __HYPERVISOR_set_trap_table 0
> +#define __HYPERVISOR_mmu_update 1
> +#define __HYPERVISOR_set_gdt 2
> +#define __HYPERVISOR_stack_switch 3
> +#define __HYPERVISOR_set_callbacks 4
> +#define __HYPERVISOR_fpu_taskswitch 5
> +#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */
> +#define __HYPERVISOR_platform_op 7
> +#define __HYPERVISOR_set_debugreg 8
> +#define __HYPERVISOR_get_debugreg 9
> +#define __HYPERVISOR_update_descriptor 10
> +#define __HYPERVISOR_memory_op 12
> +#define __HYPERVISOR_multicall 13
> +#define __HYPERVISOR_update_va_mapping 14
> +#define __HYPERVISOR_set_timer_op 15
> +#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
> +#define __HYPERVISOR_xen_version 17
> +#define __HYPERVISOR_console_io 18
> +#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */
> +#define __HYPERVISOR_grant_table_op 20
> +#define __HYPERVISOR_vm_assist 21
> +#define __HYPERVISOR_update_va_mapping_otherdomain 22
> +#define __HYPERVISOR_iret 23 /* x86 only */
> +#define __HYPERVISOR_vcpu_op 24
> +#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
> +#define __HYPERVISOR_mmuext_op 26
> +#define __HYPERVISOR_xsm_op 27
> +#define __HYPERVISOR_nmi_op 28
> +#define __HYPERVISOR_sched_op 29
> +#define __HYPERVISOR_callback_op 30
> +#define __HYPERVISOR_xenoprof_op 31
> +#define __HYPERVISOR_event_channel_op 32
> +#define __HYPERVISOR_physdev_op 33
> +#define __HYPERVISOR_hvm_op 34
> +#define __HYPERVISOR_sysctl 35
> +#define __HYPERVISOR_domctl 36
> +#define __HYPERVISOR_kexec_op 37
> +#define __HYPERVISOR_tmem_op 38
> +#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
> +
> +/* Architecture-specific hypercall definitions. */
> +#define __HYPERVISOR_arch_0 48
> +#define __HYPERVISOR_arch_1 49
> +#define __HYPERVISOR_arch_2 50
> +#define __HYPERVISOR_arch_3 51
> +#define __HYPERVISOR_arch_4 52
> +#define __HYPERVISOR_arch_5 53
> +#define __HYPERVISOR_arch_6 54
> +#define __HYPERVISOR_arch_7 55
> +
> +/* ` } */
> +
> +/*
> + * HYPERCALL COMPATIBILITY.
> + */
> +
> +/* New sched_op hypercall introduced in 0x00030101. */
> +#if __XEN_INTERFACE_VERSION__ < 0x00030101
> +#undef __HYPERVISOR_sched_op
> +#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat
> +#endif
> +
> +/* New event-channel and physdev hypercalls introduced in 0x00030202. */
> +#if __XEN_INTERFACE_VERSION__ < 0x00030202
> +#undef __HYPERVISOR_event_channel_op
> +#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
> +#undef __HYPERVISOR_physdev_op
> +#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
> +#endif
> +
> +/* New platform_op hypercall introduced in 0x00030204. */
> +#if __XEN_INTERFACE_VERSION__ < 0x00030204
> +#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +
> +typedef UINT16 domid_t;
> +
> +/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
> +#define DOMID_FIRST_RESERVED (0x7FF0U)
> +
> +/* DOMID_SELF is used in certain contexts to refer to oneself. */
> +#define DOMID_SELF (0x7FF0U)
> +
> +/*
> + * DOMID_IO is used to restrict page-table updates to mapping I/O memory.
> + * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO
> + * is useful to ensure that no mappings to the OS's own heap are accidentally
> + * installed. (e.g., in Linux this could cause havoc as reference counts
> + * aren't adjusted on the I/O-mapping code path).
> + * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can
> + * be specified by any calling domain.
> + */
> +#define DOMID_IO (0x7FF1U)
> +
> +/*
> + * DOMID_XEN is used to allow privileged domains to map restricted parts of
> + * Xen's heap space (e.g., the machine_to_phys table).
> + * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if
> + * the caller is privileged.
> + */
> +#define DOMID_XEN (0x7FF2U)
> +
> +/*
> + * DOMID_COW is used as the owner of sharable pages */
> +#define DOMID_COW (0x7FF3U)
> +
> +/* DOMID_INVALID is used to identify pages with unknown owner. */
> +#define DOMID_INVALID (0x7FF4U)
> +
> +/* Idle domain. */
> +#define DOMID_IDLE (0x7FFFU)
> +
> +#if __XEN_INTERFACE_VERSION__ < 0x00040400
> +/*
> + * Event channel endpoints per domain (when using the 2-level ABI):
> + * 1024 if a INTN is 32 bits; 4096 if a INTN is 64 bits.
> + */
> +#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS
> +#endif
> +
> +struct vcpu_time_info {
> + /*
> + * Updates to the following values are preceded and followed by an
> + * increment of 'version'. The guest can therefore detect updates by
> + * looking for changes to 'version'. If the least-significant bit of
> + * the version number is set then an update is in progress and the guest
> + * must wait to read a consistent set of values.
> + * The correct way to interact with the version number is similar to
> + * Linux's seqlock: see the implementations of
> read_seqbegin/read_seqretry.
> + */
> + UINT32 version;
> + UINT32 pad0;
> + UINT64 tsc_timestamp; /* TSC at last update of time vals. */
> + UINT64 system_time; /* Time, in nanosecs, since boot. */
> + /*
> + * Current system time:
> + * system_time +
> + * ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32)
> + * CPU frequency (Hz):
> + * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
> + */
> + UINT32 tsc_to_system_mul;
> + INT8 tsc_shift;
> + INT8 pad1[3];
> +}; /* 32 bytes */
> +typedef struct vcpu_time_info vcpu_time_info_t;
> +
> +struct vcpu_info {
> + /*
> + * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
> + * a pending notification for a particular VCPU. It is then cleared
> + * by the guest OS /before/ checking for pending work, thus avoiding
> + * a set-and-check race. Note that the mask is only accessed by Xen
> + * on the CPU that is currently hosting the VCPU. This means that the
> + * pending and mask flags can be updated by the guest without special
> + * synchronisation (i.e., no need for the x86 LOCK prefix).
> + * This may seem suboptimal because if the pending flag is set by
> + * a different CPU then an IPI may be scheduled even when the mask
> + * is set. However, note:
> + * 1. The task of 'interrupt holdoff' is covered by the per-event-
> + * channel mask bits. A 'noisy' event that is continually being
> + * triggered can be masked at source at this very precise
> + * granularity.
> + * 2. The main purpose of the per-VCPU mask is therefore to restrict
> + * reentrant execution: whether for concurrency control, or to
> + * prevent unbounded stack usage. Whatever the purpose, we expect
> + * that the mask will be asserted only for short periods at a time,
> + * and so the likelihood of a 'spurious' IPI is suitably small.
> + * The mask is read before making an event upcall to the guest: a
> + * non-zero mask therefore guarantees that the VCPU will not receive
> + * an upcall activation. The mask is cleared when the VCPU requests
> + * to block: this avoids wakeup-waiting races.
> + */
> + UINT8 evtchn_upcall_pending;
> +#ifdef XEN_HAVE_PV_UPCALL_MASK
> + UINT8 evtchn_upcall_mask;
> +#else /* XEN_HAVE_PV_UPCALL_MASK */
> + UINT8 pad0;
> +#endif /* XEN_HAVE_PV_UPCALL_MASK */
> + xen_ulong_t evtchn_pending_sel;
> + struct arch_vcpu_info arch;
> + struct vcpu_time_info time;
> +}; /* 64 bytes (x86) */
> +#ifndef __XEN__
> +typedef struct vcpu_info vcpu_info_t;
> +#endif
> +
> +/*
> + * `incontents 200 startofday_shared Start-of-day shared data structure
> + * Xen/kernel shared data -- pointer provided in start_info.
> + *
> + * This structure is defined to be both smaller than a page, and the
> + * only data on the shared page, but may vary in actual size even within
> + * compatible Xen versions; guests should not rely on the size
> + * of this structure remaining constant.
> + */
> +struct shared_info {
> + struct vcpu_info vcpu_info[XEN_LEGACY_MAX_VCPUS];
> +
> + /*
> + * A domain can create "event channels" on which it can send and receive
> + * asynchronous event notifications. There are three classes of event
> that
> + * are delivered by this mechanism:
> + * 1. Bi-directional inter- and intra-domain connections. Domains must
> + * arrange out-of-band to set up a connection (usually by allocating
> + * an unbound 'listener' port and avertising that via a storage
> service
> + * such as xenstore).
> + * 2. Physical interrupts. A domain with suitable hardware-access
> + * privileges can bind an event-channel port to a physical interrupt
> + * source.
> + * 3. Virtual interrupts ('events'). A domain can bind an event-channel
> + * port to a virtual interrupt source, such as the virtual-timer
> + * device or the emergency console.
> + *
> + * Event channels are addressed by a "port index". Each channel is
> + * associated with two bits of information:
> + * 1. PENDING -- notifies the domain that there is a pending
> notification
> + * to be processed. This bit is cleared by the guest.
> + * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING
> + * will cause an asynchronous upcall to be scheduled. This bit is
> only
> + * updated by the guest. It is read-only within Xen. If a channel
> + * becomes pending while the channel is masked then the 'edge' is
> lost
> + * (i.e., when the channel is unmasked, the guest must manually
> handle
> + * pending notifications as no upcall will be scheduled by Xen).
> + *
> + * To expedite scanning of pending notifications, any 0->1 pending
> + * transition on an unmasked channel causes a corresponding bit in a
> + * per-vcpu selector word to be set. Each bit in the selector covers a
> + * 'C INTN' in the PENDING bitfield array.
> + */
> + xen_ulong_t evtchn_pending[sizeof(xen_ulong_t) * 8];
> + xen_ulong_t evtchn_mask[sizeof(xen_ulong_t) * 8];
> +
> + /*
> + * Wallclock time: updated only by control software. Guests should base
> + * their gettimeofday() syscall on this wallclock-base value.
> + */
> + UINT32 wc_version; /* Version counter: see vcpu_time_info_t. */
> + UINT32 wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */
> + UINT32 wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */
> +
> + struct arch_shared_info arch;
> +
> +};
> +#ifndef __XEN__
> +typedef struct shared_info shared_info_t;
> +#endif
> +
> +/* Turn a plain number into a C UINTN constant. */
> +#define __mk_unsigned_long(x) x ## UL
> +#define mk_unsigned_long(x) __mk_unsigned_long(x)
> +
> +__DEFINE_XEN_GUEST_HANDLE(uint8, UINT8);
> +__DEFINE_XEN_GUEST_HANDLE(uint16, UINT16);
> +__DEFINE_XEN_GUEST_HANDLE(uint32, UINT32);
> +__DEFINE_XEN_GUEST_HANDLE(uint64, UINT64);
> +
> +#else /* __ASSEMBLY__ */
> +
> +/* In assembly code we cannot use C numeric constant suffixes. */
> +#define mk_unsigned_long(x) x
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_XEN_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> --
> Anthony PERARD
>
>
> ------------------------------------------------------------------------------
> Comprehensive Server Monitoring with Site24x7.
> Monitor 10 servers for $9/Month.
> Get alerted through email, SMS, voice calls or mobile push notifications.
> Take corrective actions from your mobile device.
> http://p.sf.net/sfu/Zoho
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@xxxxxxxxxxxxxxxxxxxxx
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |