1843e1988Sjohnlev /****************************************************************************** 2843e1988Sjohnlev * xen-x86_32.h 3*55fea89dSDan Cross * 4843e1988Sjohnlev * Guest OS interface to x86 32-bit Xen. 5*55fea89dSDan Cross * 6843e1988Sjohnlev * Permission is hereby granted, free of charge, to any person obtaining a copy 7843e1988Sjohnlev * of this software and associated documentation files (the "Software"), to 8843e1988Sjohnlev * deal in the Software without restriction, including without limitation the 9843e1988Sjohnlev * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10843e1988Sjohnlev * sell copies of the Software, and to permit persons to whom the Software is 11843e1988Sjohnlev * furnished to do so, subject to the following conditions: 12843e1988Sjohnlev * 13843e1988Sjohnlev * The above copyright notice and this permission notice shall be included in 14843e1988Sjohnlev * all copies or substantial portions of the Software. 15843e1988Sjohnlev * 16843e1988Sjohnlev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17843e1988Sjohnlev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18843e1988Sjohnlev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19843e1988Sjohnlev * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20843e1988Sjohnlev * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21843e1988Sjohnlev * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22843e1988Sjohnlev * DEALINGS IN THE SOFTWARE. 23843e1988Sjohnlev * 24a576ab5bSrab * Copyright (c) 2004-2007, K A Fraser 25843e1988Sjohnlev */ 26843e1988Sjohnlev 27843e1988Sjohnlev #ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 28843e1988Sjohnlev #define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 29843e1988Sjohnlev 30843e1988Sjohnlev /* 31843e1988Sjohnlev * Hypercall interface: 32843e1988Sjohnlev * Input: %ebx, %ecx, %edx, %esi, %edi (arguments 1-5) 33843e1988Sjohnlev * Output: %eax 34843e1988Sjohnlev * Access is via hypercall page (set up by guest loader or via a Xen MSR): 35843e1988Sjohnlev * call hypercall_page + hypercall-number * 32 36843e1988Sjohnlev * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx) 37843e1988Sjohnlev */ 38843e1988Sjohnlev 39843e1988Sjohnlev /* 40349b53ddSStuart Maybee * Direct hypercall interface: 41843e1988Sjohnlev * As above, except the entry sequence to the hypervisor is: 42843e1988Sjohnlev * mov $hypercall-number*32,%eax ; int $0x82 43843e1988Sjohnlev */ 44843e1988Sjohnlev #if !defined(_ASM) 45843e1988Sjohnlev #define TRAP_INSTR "int $0x82" 46843e1988Sjohnlev #else 47843e1988Sjohnlev #define TRAP_INSTR int $0x82 48843e1988Sjohnlev #endif 49843e1988Sjohnlev 50843e1988Sjohnlev /* 51843e1988Sjohnlev * These flat segments are in the Xen-private section of every GDT. Since these 52843e1988Sjohnlev * are also present in the initial GDT, many OSes will be able to avoid 53843e1988Sjohnlev * installing their own GDT. 54843e1988Sjohnlev */ 55843e1988Sjohnlev #define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 56843e1988Sjohnlev #define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 57843e1988Sjohnlev #define FLAT_RING1_SS 0xe021 /* GDT index 260 */ 58843e1988Sjohnlev #define FLAT_RING3_CS 0xe02b /* GDT index 261 */ 59843e1988Sjohnlev #define FLAT_RING3_DS 0xe033 /* GDT index 262 */ 60843e1988Sjohnlev #define FLAT_RING3_SS 0xe033 /* GDT index 262 */ 61843e1988Sjohnlev 62843e1988Sjohnlev #define FLAT_KERNEL_CS FLAT_RING1_CS 63843e1988Sjohnlev #define FLAT_KERNEL_DS FLAT_RING1_DS 64843e1988Sjohnlev #define FLAT_KERNEL_SS FLAT_RING1_SS 65843e1988Sjohnlev #define FLAT_USER_CS FLAT_RING3_CS 66843e1988Sjohnlev #define FLAT_USER_DS FLAT_RING3_DS 67843e1988Sjohnlev #define FLAT_USER_SS FLAT_RING3_SS 68843e1988Sjohnlev 69843e1988Sjohnlev #define __HYPERVISOR_VIRT_START_PAE 0xF5800000 70843e1988Sjohnlev #define __MACH2PHYS_VIRT_START_PAE 0xF5800000 71843e1988Sjohnlev #define __MACH2PHYS_VIRT_END_PAE 0xF6800000 72843e1988Sjohnlev #define HYPERVISOR_VIRT_START_PAE \ 73843e1988Sjohnlev mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE) 74843e1988Sjohnlev #define MACH2PHYS_VIRT_START_PAE \ 75843e1988Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE) 76843e1988Sjohnlev #define MACH2PHYS_VIRT_END_PAE \ 77843e1988Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE) 78843e1988Sjohnlev 79349b53ddSStuart Maybee /* Non-PAE bounds are obsolete. */ 80843e1988Sjohnlev #define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 81843e1988Sjohnlev #define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 82843e1988Sjohnlev #define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 83843e1988Sjohnlev #define HYPERVISOR_VIRT_START_NONPAE \ 84843e1988Sjohnlev mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE) 85843e1988Sjohnlev #define MACH2PHYS_VIRT_START_NONPAE \ 86843e1988Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE) 87843e1988Sjohnlev #define MACH2PHYS_VIRT_END_NONPAE \ 88843e1988Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE) 89843e1988Sjohnlev 90843e1988Sjohnlev #define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE 91843e1988Sjohnlev #define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE 92843e1988Sjohnlev #define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE 93843e1988Sjohnlev 94843e1988Sjohnlev #ifndef HYPERVISOR_VIRT_START 95843e1988Sjohnlev #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 96843e1988Sjohnlev #endif 97843e1988Sjohnlev 98843e1988Sjohnlev #define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 99843e1988Sjohnlev #define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 100843e1988Sjohnlev #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2) 101843e1988Sjohnlev #ifndef machine_to_phys_mapping 102843e1988Sjohnlev #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) 103843e1988Sjohnlev #endif 104843e1988Sjohnlev 105a576ab5bSrab /* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ 106349b53ddSStuart Maybee #if defined(__XEN__) || defined(__XEN_TOOLS__) 107349b53ddSStuart Maybee #undef ___DEFINE_XEN_GUEST_HANDLE 108a576ab5bSrab 109a576ab5bSrab #ifdef __GNUC__ 110349b53ddSStuart Maybee 111349b53ddSStuart Maybee #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 112a576ab5bSrab typedef struct { type *p; } \ 113a576ab5bSrab __guest_handle_ ## name; \ 114a576ab5bSrab typedef struct { union { type *p; uint64_aligned_t q; }; } \ 115a576ab5bSrab __guest_handle_64_ ## name 116349b53ddSStuart Maybee 117349b53ddSStuart Maybee #else /* __GNUC__ */ 118349b53ddSStuart Maybee 119349b53ddSStuart Maybee /* 120349b53ddSStuart Maybee * Workaround for 6671857. 121349b53ddSStuart Maybee */ 122349b53ddSStuart Maybee #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 123a576ab5bSrab typedef struct { type *p; } \ 124a576ab5bSrab __guest_handle_ ## name; \ 125349b53ddSStuart Maybee typedef struct { union { type *p; uint64_aligned_t q; } u; }\ 126a576ab5bSrab __guest_handle_64_ ## name 127349b53ddSStuart Maybee 128349b53ddSStuart Maybee #endif /* __GNUC__ */ 129a576ab5bSrab 130a576ab5bSrab #undef set_xen_guest_handle 131a576ab5bSrab #define set_xen_guest_handle(hnd, val) \ 132a576ab5bSrab do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ 133a576ab5bSrab (hnd).p = val; \ 134a576ab5bSrab } while ( 0 ) 135349b53ddSStuart Maybee #define uint64_aligned_t uint64_t __attribute__((aligned(8))) 136349b53ddSStuart Maybee #define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name 137349b53ddSStuart Maybee #define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) 138349b53ddSStuart Maybee #endif 139a576ab5bSrab 140843e1988Sjohnlev #ifndef __ASSEMBLY__ 141843e1988Sjohnlev 142843e1988Sjohnlev struct cpu_user_regs { 143843e1988Sjohnlev uint32_t ebx; 144843e1988Sjohnlev uint32_t ecx; 145843e1988Sjohnlev uint32_t edx; 146843e1988Sjohnlev uint32_t esi; 147843e1988Sjohnlev uint32_t edi; 148843e1988Sjohnlev uint32_t ebp; 149843e1988Sjohnlev uint32_t eax; 150843e1988Sjohnlev uint16_t error_code; /* private */ 151843e1988Sjohnlev uint16_t entry_vector; /* private */ 152843e1988Sjohnlev uint32_t eip; 153843e1988Sjohnlev uint16_t cs; 154843e1988Sjohnlev uint8_t saved_upcall_mask; 155843e1988Sjohnlev uint8_t _pad0; 156843e1988Sjohnlev uint32_t eflags; /* eflags.IF == !saved_upcall_mask */ 157843e1988Sjohnlev uint32_t esp; 158843e1988Sjohnlev uint16_t ss, _pad1; 159843e1988Sjohnlev uint16_t es, _pad2; 160843e1988Sjohnlev uint16_t ds, _pad3; 161843e1988Sjohnlev uint16_t fs, _pad4; 162843e1988Sjohnlev uint16_t gs, _pad5; 163843e1988Sjohnlev }; 164843e1988Sjohnlev typedef struct cpu_user_regs cpu_user_regs_t; 165843e1988Sjohnlev DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); 166843e1988Sjohnlev 167843e1988Sjohnlev /* 168843e1988Sjohnlev * Page-directory addresses above 4GB do not fit into architectural %cr3. 169843e1988Sjohnlev * When accessing %cr3, or equivalent field in vcpu_guest_context, guests 170843e1988Sjohnlev * must use the following accessor macros to pack/unpack valid MFNs. 171843e1988Sjohnlev */ 172843e1988Sjohnlev #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) 173843e1988Sjohnlev #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) 174843e1988Sjohnlev 175843e1988Sjohnlev struct arch_vcpu_info { 176843e1988Sjohnlev unsigned long cr2; 177843e1988Sjohnlev unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ 178843e1988Sjohnlev }; 179843e1988Sjohnlev typedef struct arch_vcpu_info arch_vcpu_info_t; 180843e1988Sjohnlev 181843e1988Sjohnlev struct xen_callback { 182843e1988Sjohnlev unsigned long cs; 183843e1988Sjohnlev unsigned long eip; 184843e1988Sjohnlev }; 185843e1988Sjohnlev typedef struct xen_callback xen_callback_t; 186843e1988Sjohnlev 187843e1988Sjohnlev /* 188843e1988Sjohnlev * Structure used to capture the register state at panic time. This struct 189843e1988Sjohnlev * is built to mimic a similar structure in Solaris. If there is interest 190843e1988Sjohnlev * in making this panic implementation an official part of Xen, this should 191843e1988Sjohnlev * be made more platform-neutral. 192843e1988Sjohnlev */ 193843e1988Sjohnlev struct panic_regs { 194843e1988Sjohnlev unsigned long pad1; 195843e1988Sjohnlev unsigned long pad2; 196843e1988Sjohnlev 197843e1988Sjohnlev unsigned long gs; 198843e1988Sjohnlev unsigned long fs; 199843e1988Sjohnlev unsigned long es; 200843e1988Sjohnlev unsigned long ds; 201843e1988Sjohnlev unsigned long edi; 202843e1988Sjohnlev unsigned long esi; 203843e1988Sjohnlev unsigned long ebp; 204843e1988Sjohnlev unsigned long esp; 205843e1988Sjohnlev unsigned long ebx; 206843e1988Sjohnlev unsigned long edx; 207843e1988Sjohnlev unsigned long ecx; 208843e1988Sjohnlev unsigned long eax; 209843e1988Sjohnlev unsigned long pad3; 210843e1988Sjohnlev unsigned long pad4; 211843e1988Sjohnlev unsigned long eip; 212843e1988Sjohnlev unsigned long cs; 213843e1988Sjohnlev unsigned long efl; 214843e1988Sjohnlev unsigned long pad5; 215843e1988Sjohnlev unsigned long ss; 216843e1988Sjohnlev }; 217843e1988Sjohnlev 218843e1988Sjohnlev #endif /* !__ASSEMBLY__ */ 219843e1988Sjohnlev 220843e1988Sjohnlev /* Offsets of each field in the xen_panic_regs structure. */ 221843e1988Sjohnlev #define PANIC_REG_PAD1 0 222843e1988Sjohnlev #define PANIC_REG_PAD2 4 223843e1988Sjohnlev #define PANIC_REG_GS 8 224843e1988Sjohnlev #define PANIC_REG_FS 12 225843e1988Sjohnlev #define PANIC_REG_ES 16 226843e1988Sjohnlev #define PANIC_REG_DS 20 227843e1988Sjohnlev #define PANIC_REG_EDI 24 228843e1988Sjohnlev #define PANIC_REG_ESI 28 229843e1988Sjohnlev #define PANIC_REG_EBP 32 230843e1988Sjohnlev #define PANIC_REG_ESP 36 231843e1988Sjohnlev #define PANIC_REG_EBX 40 232843e1988Sjohnlev #define PANIC_REG_EDX 44 233843e1988Sjohnlev #define PANIC_REG_ECX 48 234843e1988Sjohnlev #define PANIC_REG_EAX 52 235843e1988Sjohnlev #define PANIC_REG_PAD3 56 236843e1988Sjohnlev #define PANIC_REG_PAD4 60 237843e1988Sjohnlev #define PANIC_REG_EIP 64 238843e1988Sjohnlev #define PANIC_REG_CS 68 239843e1988Sjohnlev #define PANIC_REG_EFL 72 240843e1988Sjohnlev #define PANIC_REG_PAD5 76 241843e1988Sjohnlev #define PANIC_REG_SS 80 242843e1988Sjohnlev #define PANIC_REG_STRUCT_SIZE 84 243843e1988Sjohnlev 244843e1988Sjohnlev #endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */ 245843e1988Sjohnlev 246843e1988Sjohnlev /* 247843e1988Sjohnlev * Local variables: 248843e1988Sjohnlev * mode: C 249843e1988Sjohnlev * c-set-style: "BSD" 250843e1988Sjohnlev * c-basic-offset: 4 251843e1988Sjohnlev * tab-width: 4 252843e1988Sjohnlev * indent-tabs-mode: nil 253843e1988Sjohnlev * End: 254843e1988Sjohnlev */ 255