xref: /qemu/include/hw/xen/interface/arch-x86/xen-x86_32.h (revision 3e34860a3a03f969ad0720ec9c12ea10e88738a6)
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