1*8ac98aedSDavid Woodhouse /* SPDX-License-Identifier: MIT */ 250c88402SJoao Martins /****************************************************************************** 350c88402SJoao Martins * xen-x86_32.h 450c88402SJoao Martins * 550c88402SJoao Martins * Guest OS interface to x86 32-bit Xen. 650c88402SJoao Martins * 750c88402SJoao Martins * Copyright (c) 2004-2007, K A Fraser 850c88402SJoao Martins */ 950c88402SJoao Martins 1050c88402SJoao Martins #ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 1150c88402SJoao Martins #define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 1250c88402SJoao Martins 1350c88402SJoao Martins /* 1450c88402SJoao Martins * Hypercall interface: 1550c88402SJoao Martins * Input: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6) 1650c88402SJoao Martins * Output: %eax 1750c88402SJoao Martins * Access is via hypercall page (set up by guest loader or via a Xen MSR): 1850c88402SJoao Martins * call hypercall_page + hypercall-number * 32 1950c88402SJoao Martins * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx) 2050c88402SJoao Martins */ 2150c88402SJoao Martins 2250c88402SJoao Martins /* 2350c88402SJoao Martins * These flat segments are in the Xen-private section of every GDT. Since these 2450c88402SJoao Martins * are also present in the initial GDT, many OSes will be able to avoid 2550c88402SJoao Martins * installing their own GDT. 2650c88402SJoao Martins */ 2750c88402SJoao Martins #define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 2850c88402SJoao Martins #define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 2950c88402SJoao Martins #define FLAT_RING1_SS 0xe021 /* GDT index 260 */ 3050c88402SJoao Martins #define FLAT_RING3_CS 0xe02b /* GDT index 261 */ 3150c88402SJoao Martins #define FLAT_RING3_DS 0xe033 /* GDT index 262 */ 3250c88402SJoao Martins #define FLAT_RING3_SS 0xe033 /* GDT index 262 */ 3350c88402SJoao Martins 3450c88402SJoao Martins #define FLAT_KERNEL_CS FLAT_RING1_CS 3550c88402SJoao Martins #define FLAT_KERNEL_DS FLAT_RING1_DS 3650c88402SJoao Martins #define FLAT_KERNEL_SS FLAT_RING1_SS 3750c88402SJoao Martins #define FLAT_USER_CS FLAT_RING3_CS 3850c88402SJoao Martins #define FLAT_USER_DS FLAT_RING3_DS 3950c88402SJoao Martins #define FLAT_USER_SS FLAT_RING3_SS 4050c88402SJoao Martins 4150c88402SJoao Martins #define __HYPERVISOR_VIRT_START_PAE 0xF5800000 4250c88402SJoao Martins #define __MACH2PHYS_VIRT_START_PAE 0xF5800000 4350c88402SJoao Martins #define __MACH2PHYS_VIRT_END_PAE 0xF6800000 4450c88402SJoao Martins #define HYPERVISOR_VIRT_START_PAE xen_mk_ulong(__HYPERVISOR_VIRT_START_PAE) 4550c88402SJoao Martins #define MACH2PHYS_VIRT_START_PAE xen_mk_ulong(__MACH2PHYS_VIRT_START_PAE) 4650c88402SJoao Martins #define MACH2PHYS_VIRT_END_PAE xen_mk_ulong(__MACH2PHYS_VIRT_END_PAE) 4750c88402SJoao Martins 4850c88402SJoao Martins /* Non-PAE bounds are obsolete. */ 4950c88402SJoao Martins #define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 5050c88402SJoao Martins #define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 5150c88402SJoao Martins #define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 5250c88402SJoao Martins #define HYPERVISOR_VIRT_START_NONPAE \ 5350c88402SJoao Martins xen_mk_ulong(__HYPERVISOR_VIRT_START_NONPAE) 5450c88402SJoao Martins #define MACH2PHYS_VIRT_START_NONPAE \ 5550c88402SJoao Martins xen_mk_ulong(__MACH2PHYS_VIRT_START_NONPAE) 5650c88402SJoao Martins #define MACH2PHYS_VIRT_END_NONPAE \ 5750c88402SJoao Martins xen_mk_ulong(__MACH2PHYS_VIRT_END_NONPAE) 5850c88402SJoao Martins 5950c88402SJoao Martins #define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE 6050c88402SJoao Martins #define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE 6150c88402SJoao Martins #define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE 6250c88402SJoao Martins 6350c88402SJoao Martins #ifndef HYPERVISOR_VIRT_START 6450c88402SJoao Martins #define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) 6550c88402SJoao Martins #endif 6650c88402SJoao Martins 6750c88402SJoao Martins #define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) 6850c88402SJoao Martins #define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) 6950c88402SJoao Martins #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2) 7050c88402SJoao Martins #ifndef machine_to_phys_mapping 7150c88402SJoao Martins #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) 7250c88402SJoao Martins #endif 7350c88402SJoao Martins 7450c88402SJoao Martins /* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ 7550c88402SJoao Martins #if defined(__XEN__) || defined(__XEN_TOOLS__) 7650c88402SJoao Martins #undef ___DEFINE_XEN_GUEST_HANDLE 7750c88402SJoao Martins #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 7850c88402SJoao Martins typedef struct { type *p; } \ 7950c88402SJoao Martins __guest_handle_ ## name; \ 8050c88402SJoao Martins typedef struct { union { type *p; uint64_aligned_t q; }; } \ 8150c88402SJoao Martins __guest_handle_64_ ## name 8250c88402SJoao Martins #undef set_xen_guest_handle_raw 8350c88402SJoao Martins #define set_xen_guest_handle_raw(hnd, val) \ 8450c88402SJoao Martins do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ 8550c88402SJoao Martins (hnd).p = val; \ 8650c88402SJoao Martins } while ( 0 ) 8750c88402SJoao Martins #define int64_aligned_t int64_t __attribute__((aligned(8))) 8850c88402SJoao Martins #define uint64_aligned_t uint64_t __attribute__((aligned(8))) 8950c88402SJoao Martins #define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name 9050c88402SJoao Martins #define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) 9150c88402SJoao Martins #endif 9250c88402SJoao Martins 9350c88402SJoao Martins #ifndef __ASSEMBLY__ 9450c88402SJoao Martins 9550c88402SJoao Martins #if defined(XEN_GENERATING_COMPAT_HEADERS) 9650c88402SJoao Martins /* nothing */ 9750c88402SJoao Martins #elif defined(__XEN__) || defined(__XEN_TOOLS__) 9850c88402SJoao Martins /* Anonymous unions include all permissible names (e.g., al/ah/ax/eax). */ 9950c88402SJoao Martins #define __DECL_REG_LO8(which) union { \ 10050c88402SJoao Martins uint32_t e ## which ## x; \ 10150c88402SJoao Martins uint16_t which ## x; \ 10250c88402SJoao Martins struct { \ 10350c88402SJoao Martins uint8_t which ## l; \ 10450c88402SJoao Martins uint8_t which ## h; \ 10550c88402SJoao Martins }; \ 10650c88402SJoao Martins } 10750c88402SJoao Martins #define __DECL_REG_LO16(name) union { \ 10850c88402SJoao Martins uint32_t e ## name, _e ## name; \ 10950c88402SJoao Martins uint16_t name; \ 11050c88402SJoao Martins } 11150c88402SJoao Martins #else 11250c88402SJoao Martins /* Other sources must always use the proper 32-bit name (e.g., eax). */ 11350c88402SJoao Martins #define __DECL_REG_LO8(which) uint32_t e ## which ## x 11450c88402SJoao Martins #define __DECL_REG_LO16(name) uint32_t e ## name 11550c88402SJoao Martins #endif 11650c88402SJoao Martins 11750c88402SJoao Martins struct cpu_user_regs { 11850c88402SJoao Martins __DECL_REG_LO8(b); 11950c88402SJoao Martins __DECL_REG_LO8(c); 12050c88402SJoao Martins __DECL_REG_LO8(d); 12150c88402SJoao Martins __DECL_REG_LO16(si); 12250c88402SJoao Martins __DECL_REG_LO16(di); 12350c88402SJoao Martins __DECL_REG_LO16(bp); 12450c88402SJoao Martins __DECL_REG_LO8(a); 12550c88402SJoao Martins uint16_t error_code; /* private */ 12650c88402SJoao Martins uint16_t entry_vector; /* private */ 12750c88402SJoao Martins __DECL_REG_LO16(ip); 12850c88402SJoao Martins uint16_t cs; 12950c88402SJoao Martins uint8_t saved_upcall_mask; 13050c88402SJoao Martins uint8_t _pad0; 13150c88402SJoao Martins __DECL_REG_LO16(flags); /* eflags.IF == !saved_upcall_mask */ 13250c88402SJoao Martins __DECL_REG_LO16(sp); 13350c88402SJoao Martins uint16_t ss, _pad1; 13450c88402SJoao Martins uint16_t es, _pad2; 13550c88402SJoao Martins uint16_t ds, _pad3; 13650c88402SJoao Martins uint16_t fs, _pad4; 13750c88402SJoao Martins uint16_t gs, _pad5; 13850c88402SJoao Martins }; 13950c88402SJoao Martins typedef struct cpu_user_regs cpu_user_regs_t; 14050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); 14150c88402SJoao Martins 14250c88402SJoao Martins #undef __DECL_REG_LO8 14350c88402SJoao Martins #undef __DECL_REG_LO16 14450c88402SJoao Martins 14550c88402SJoao Martins /* 14650c88402SJoao Martins * Page-directory addresses above 4GB do not fit into architectural %cr3. 14750c88402SJoao Martins * When accessing %cr3, or equivalent field in vcpu_guest_context, guests 14850c88402SJoao Martins * must use the following accessor macros to pack/unpack valid MFNs. 14950c88402SJoao Martins */ 15050c88402SJoao Martins #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) 15150c88402SJoao Martins #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) 15250c88402SJoao Martins 15350c88402SJoao Martins struct arch_vcpu_info { 15450c88402SJoao Martins unsigned long cr2; 15550c88402SJoao Martins unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ 15650c88402SJoao Martins }; 15750c88402SJoao Martins typedef struct arch_vcpu_info arch_vcpu_info_t; 15850c88402SJoao Martins 15950c88402SJoao Martins struct xen_callback { 16050c88402SJoao Martins unsigned long cs; 16150c88402SJoao Martins unsigned long eip; 16250c88402SJoao Martins }; 16350c88402SJoao Martins typedef struct xen_callback xen_callback_t; 16450c88402SJoao Martins 16550c88402SJoao Martins #endif /* !__ASSEMBLY__ */ 16650c88402SJoao Martins 16750c88402SJoao Martins #endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */ 16850c88402SJoao Martins 16950c88402SJoao Martins /* 17050c88402SJoao Martins * Local variables: 17150c88402SJoao Martins * mode: C 17250c88402SJoao Martins * c-file-style: "BSD" 17350c88402SJoao Martins * c-basic-offset: 4 17450c88402SJoao Martins * tab-width: 4 17550c88402SJoao Martins * indent-tabs-mode: nil 17650c88402SJoao Martins * End: 17750c88402SJoao Martins */ 178