15084Sjohnlev /****************************************************************************** 25084Sjohnlev * xen-x86_32.h 35084Sjohnlev * 45084Sjohnlev * Guest OS interface to x86 32-bit Xen. 55084Sjohnlev * 65084Sjohnlev * Permission is hereby granted, free of charge, to any person obtaining a copy 75084Sjohnlev * of this software and associated documentation files (the "Software"), to 85084Sjohnlev * deal in the Software without restriction, including without limitation the 95084Sjohnlev * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 105084Sjohnlev * sell copies of the Software, and to permit persons to whom the Software is 115084Sjohnlev * furnished to do so, subject to the following conditions: 125084Sjohnlev * 135084Sjohnlev * The above copyright notice and this permission notice shall be included in 145084Sjohnlev * all copies or substantial portions of the Software. 155084Sjohnlev * 165084Sjohnlev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175084Sjohnlev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185084Sjohnlev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 195084Sjohnlev * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 205084Sjohnlev * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 215084Sjohnlev * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 225084Sjohnlev * DEALINGS IN THE SOFTWARE. 235084Sjohnlev * 246144Srab * Copyright (c) 2004-2007, K A Fraser 255084Sjohnlev */ 265084Sjohnlev 275084Sjohnlev #ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 285084Sjohnlev #define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 295084Sjohnlev 305084Sjohnlev /* 315084Sjohnlev * Hypercall interface: 325084Sjohnlev * Input: %ebx, %ecx, %edx, %esi, %edi (arguments 1-5) 335084Sjohnlev * Output: %eax 345084Sjohnlev * Access is via hypercall page (set up by guest loader or via a Xen MSR): 355084Sjohnlev * call hypercall_page + hypercall-number * 32 365084Sjohnlev * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx) 375084Sjohnlev */ 385084Sjohnlev 395084Sjohnlev /* 40*10175SStuart.Maybee@Sun.COM * Direct hypercall interface: 415084Sjohnlev * As above, except the entry sequence to the hypervisor is: 425084Sjohnlev * mov $hypercall-number*32,%eax ; int $0x82 435084Sjohnlev */ 445084Sjohnlev #if !defined(_ASM) 455084Sjohnlev #define TRAP_INSTR "int $0x82" 465084Sjohnlev #else 475084Sjohnlev #define TRAP_INSTR int $0x82 485084Sjohnlev #endif 495084Sjohnlev 505084Sjohnlev /* 515084Sjohnlev * These flat segments are in the Xen-private section of every GDT. Since these 525084Sjohnlev * are also present in the initial GDT, many OSes will be able to avoid 535084Sjohnlev * installing their own GDT. 545084Sjohnlev */ 555084Sjohnlev #define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 565084Sjohnlev #define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 575084Sjohnlev #define FLAT_RING1_SS 0xe021 /* GDT index 260 */ 585084Sjohnlev #define FLAT_RING3_CS 0xe02b /* GDT index 261 */ 595084Sjohnlev #define FLAT_RING3_DS 0xe033 /* GDT index 262 */ 605084Sjohnlev #define FLAT_RING3_SS 0xe033 /* GDT index 262 */ 615084Sjohnlev 625084Sjohnlev #define FLAT_KERNEL_CS FLAT_RING1_CS 635084Sjohnlev #define FLAT_KERNEL_DS FLAT_RING1_DS 645084Sjohnlev #define FLAT_KERNEL_SS FLAT_RING1_SS 655084Sjohnlev #define FLAT_USER_CS FLAT_RING3_CS 665084Sjohnlev #define FLAT_USER_DS FLAT_RING3_DS 675084Sjohnlev #define FLAT_USER_SS FLAT_RING3_SS 685084Sjohnlev 695084Sjohnlev #define __HYPERVISOR_VIRT_START_PAE 0xF5800000 705084Sjohnlev #define __MACH2PHYS_VIRT_START_PAE 0xF5800000 715084Sjohnlev #define __MACH2PHYS_VIRT_END_PAE 0xF6800000 725084Sjohnlev #define HYPERVISOR_VIRT_START_PAE \ 735084Sjohnlev mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE) 745084Sjohnlev #define MACH2PHYS_VIRT_START_PAE \ 755084Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE) 765084Sjohnlev #define MACH2PHYS_VIRT_END_PAE \ 775084Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE) 785084Sjohnlev 79*10175SStuart.Maybee@Sun.COM /* Non-PAE bounds are obsolete. */ 805084Sjohnlev #define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 815084Sjohnlev #define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 825084Sjohnlev #define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 835084Sjohnlev #define HYPERVISOR_VIRT_START_NONPAE \ 845084Sjohnlev mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE) 855084Sjohnlev #define MACH2PHYS_VIRT_START_NONPAE \ 865084Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE) 875084Sjohnlev #define MACH2PHYS_VIRT_END_NONPAE \ 885084Sjohnlev mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE) 895084Sjohnlev 905084Sjohnlev #define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE 915084Sjohnlev #define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE 925084Sjohnlev #define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE 935084Sjohnlev 945084Sjohnlev #ifndef HYPERVISOR_VIRT_START 955084Sjohnlev #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 965084Sjohnlev #endif 975084Sjohnlev 985084Sjohnlev #define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 995084Sjohnlev #define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 1005084Sjohnlev #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2) 1015084Sjohnlev #ifndef machine_to_phys_mapping 1025084Sjohnlev #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) 1035084Sjohnlev #endif 1045084Sjohnlev 1056144Srab /* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ 106*10175SStuart.Maybee@Sun.COM #if defined(__XEN__) || defined(__XEN_TOOLS__) 107*10175SStuart.Maybee@Sun.COM #undef ___DEFINE_XEN_GUEST_HANDLE 1086144Srab 1096144Srab #ifdef __GNUC__ 110*10175SStuart.Maybee@Sun.COM 111*10175SStuart.Maybee@Sun.COM #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 1126144Srab typedef struct { type *p; } \ 1136144Srab __guest_handle_ ## name; \ 1146144Srab typedef struct { union { type *p; uint64_aligned_t q; }; } \ 1156144Srab __guest_handle_64_ ## name 116*10175SStuart.Maybee@Sun.COM 117*10175SStuart.Maybee@Sun.COM #else /* __GNUC__ */ 118*10175SStuart.Maybee@Sun.COM 119*10175SStuart.Maybee@Sun.COM /* 120*10175SStuart.Maybee@Sun.COM * Workaround for 6671857. 121*10175SStuart.Maybee@Sun.COM */ 122*10175SStuart.Maybee@Sun.COM #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 1236144Srab typedef struct { type *p; } \ 1246144Srab __guest_handle_ ## name; \ 125*10175SStuart.Maybee@Sun.COM typedef struct { union { type *p; uint64_aligned_t q; } u; }\ 1266144Srab __guest_handle_64_ ## name 127*10175SStuart.Maybee@Sun.COM 128*10175SStuart.Maybee@Sun.COM #endif /* __GNUC__ */ 1296144Srab 1306144Srab #undef set_xen_guest_handle 1316144Srab #define set_xen_guest_handle(hnd, val) \ 1326144Srab do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ 1336144Srab (hnd).p = val; \ 1346144Srab } while ( 0 ) 135*10175SStuart.Maybee@Sun.COM #define uint64_aligned_t uint64_t __attribute__((aligned(8))) 136*10175SStuart.Maybee@Sun.COM #define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name 137*10175SStuart.Maybee@Sun.COM #define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) 138*10175SStuart.Maybee@Sun.COM #endif 1396144Srab 1405084Sjohnlev #ifndef __ASSEMBLY__ 1415084Sjohnlev 1425084Sjohnlev struct cpu_user_regs { 1435084Sjohnlev uint32_t ebx; 1445084Sjohnlev uint32_t ecx; 1455084Sjohnlev uint32_t edx; 1465084Sjohnlev uint32_t esi; 1475084Sjohnlev uint32_t edi; 1485084Sjohnlev uint32_t ebp; 1495084Sjohnlev uint32_t eax; 1505084Sjohnlev uint16_t error_code; /* private */ 1515084Sjohnlev uint16_t entry_vector; /* private */ 1525084Sjohnlev uint32_t eip; 1535084Sjohnlev uint16_t cs; 1545084Sjohnlev uint8_t saved_upcall_mask; 1555084Sjohnlev uint8_t _pad0; 1565084Sjohnlev uint32_t eflags; /* eflags.IF == !saved_upcall_mask */ 1575084Sjohnlev uint32_t esp; 1585084Sjohnlev uint16_t ss, _pad1; 1595084Sjohnlev uint16_t es, _pad2; 1605084Sjohnlev uint16_t ds, _pad3; 1615084Sjohnlev uint16_t fs, _pad4; 1625084Sjohnlev uint16_t gs, _pad5; 1635084Sjohnlev }; 1645084Sjohnlev typedef struct cpu_user_regs cpu_user_regs_t; 1655084Sjohnlev DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); 1665084Sjohnlev 1675084Sjohnlev /* 1685084Sjohnlev * Page-directory addresses above 4GB do not fit into architectural %cr3. 1695084Sjohnlev * When accessing %cr3, or equivalent field in vcpu_guest_context, guests 1705084Sjohnlev * must use the following accessor macros to pack/unpack valid MFNs. 1715084Sjohnlev */ 1725084Sjohnlev #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) 1735084Sjohnlev #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) 1745084Sjohnlev 1755084Sjohnlev struct arch_vcpu_info { 1765084Sjohnlev unsigned long cr2; 1775084Sjohnlev unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ 1785084Sjohnlev }; 1795084Sjohnlev typedef struct arch_vcpu_info arch_vcpu_info_t; 1805084Sjohnlev 1815084Sjohnlev struct xen_callback { 1825084Sjohnlev unsigned long cs; 1835084Sjohnlev unsigned long eip; 1845084Sjohnlev }; 1855084Sjohnlev typedef struct xen_callback xen_callback_t; 1865084Sjohnlev 1875084Sjohnlev /* 1885084Sjohnlev * Structure used to capture the register state at panic time. This struct 1895084Sjohnlev * is built to mimic a similar structure in Solaris. If there is interest 1905084Sjohnlev * in making this panic implementation an official part of Xen, this should 1915084Sjohnlev * be made more platform-neutral. 1925084Sjohnlev */ 1935084Sjohnlev struct panic_regs { 1945084Sjohnlev unsigned long pad1; 1955084Sjohnlev unsigned long pad2; 1965084Sjohnlev 1975084Sjohnlev unsigned long gs; 1985084Sjohnlev unsigned long fs; 1995084Sjohnlev unsigned long es; 2005084Sjohnlev unsigned long ds; 2015084Sjohnlev unsigned long edi; 2025084Sjohnlev unsigned long esi; 2035084Sjohnlev unsigned long ebp; 2045084Sjohnlev unsigned long esp; 2055084Sjohnlev unsigned long ebx; 2065084Sjohnlev unsigned long edx; 2075084Sjohnlev unsigned long ecx; 2085084Sjohnlev unsigned long eax; 2095084Sjohnlev unsigned long pad3; 2105084Sjohnlev unsigned long pad4; 2115084Sjohnlev unsigned long eip; 2125084Sjohnlev unsigned long cs; 2135084Sjohnlev unsigned long efl; 2145084Sjohnlev unsigned long pad5; 2155084Sjohnlev unsigned long ss; 2165084Sjohnlev }; 2175084Sjohnlev 2185084Sjohnlev #endif /* !__ASSEMBLY__ */ 2195084Sjohnlev 2205084Sjohnlev /* Offsets of each field in the xen_panic_regs structure. */ 2215084Sjohnlev #define PANIC_REG_PAD1 0 2225084Sjohnlev #define PANIC_REG_PAD2 4 2235084Sjohnlev #define PANIC_REG_GS 8 2245084Sjohnlev #define PANIC_REG_FS 12 2255084Sjohnlev #define PANIC_REG_ES 16 2265084Sjohnlev #define PANIC_REG_DS 20 2275084Sjohnlev #define PANIC_REG_EDI 24 2285084Sjohnlev #define PANIC_REG_ESI 28 2295084Sjohnlev #define PANIC_REG_EBP 32 2305084Sjohnlev #define PANIC_REG_ESP 36 2315084Sjohnlev #define PANIC_REG_EBX 40 2325084Sjohnlev #define PANIC_REG_EDX 44 2335084Sjohnlev #define PANIC_REG_ECX 48 2345084Sjohnlev #define PANIC_REG_EAX 52 2355084Sjohnlev #define PANIC_REG_PAD3 56 2365084Sjohnlev #define PANIC_REG_PAD4 60 2375084Sjohnlev #define PANIC_REG_EIP 64 2385084Sjohnlev #define PANIC_REG_CS 68 2395084Sjohnlev #define PANIC_REG_EFL 72 2405084Sjohnlev #define PANIC_REG_PAD5 76 2415084Sjohnlev #define PANIC_REG_SS 80 2425084Sjohnlev #define PANIC_REG_STRUCT_SIZE 84 2435084Sjohnlev 2445084Sjohnlev #endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */ 2455084Sjohnlev 2465084Sjohnlev /* 2475084Sjohnlev * Local variables: 2485084Sjohnlev * mode: C 2495084Sjohnlev * c-set-style: "BSD" 2505084Sjohnlev * c-basic-offset: 4 2515084Sjohnlev * tab-width: 4 2525084Sjohnlev * indent-tabs-mode: nil 2535084Sjohnlev * End: 2545084Sjohnlev */ 255