[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 |