162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci * arch-x86_32.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Guest OS interface to x86 32-bit Xen.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (c) 2004, K A Fraser
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef _ASM_X86_XEN_INTERFACE_32_H
1162306a36Sopenharmony_ci#define _ASM_X86_XEN_INTERFACE_32_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * These flat segments are in the Xen-private section of every GDT. Since these
1662306a36Sopenharmony_ci * are also present in the initial GDT, many OSes will be able to avoid
1762306a36Sopenharmony_ci * installing their own GDT.
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_ci#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
2062306a36Sopenharmony_ci#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
2162306a36Sopenharmony_ci#define FLAT_RING1_SS 0xe021    /* GDT index 260 */
2262306a36Sopenharmony_ci#define FLAT_RING3_CS 0xe02b    /* GDT index 261 */
2362306a36Sopenharmony_ci#define FLAT_RING3_DS 0xe033    /* GDT index 262 */
2462306a36Sopenharmony_ci#define FLAT_RING3_SS 0xe033    /* GDT index 262 */
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define FLAT_KERNEL_CS FLAT_RING1_CS
2762306a36Sopenharmony_ci#define FLAT_KERNEL_DS FLAT_RING1_DS
2862306a36Sopenharmony_ci#define FLAT_KERNEL_SS FLAT_RING1_SS
2962306a36Sopenharmony_ci#define FLAT_USER_CS    FLAT_RING3_CS
3062306a36Sopenharmony_ci#define FLAT_USER_DS    FLAT_RING3_DS
3162306a36Sopenharmony_ci#define FLAT_USER_SS    FLAT_RING3_SS
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/* And the trap vector is... */
3462306a36Sopenharmony_ci#define TRAP_INSTR "int $0x82"
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define __MACH2PHYS_VIRT_START 0xF5800000
3762306a36Sopenharmony_ci#define __MACH2PHYS_VIRT_END   0xF6800000
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define __MACH2PHYS_SHIFT      2
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/*
4262306a36Sopenharmony_ci * Virtual addresses beyond this are not modifiable by guest OSes. The
4362306a36Sopenharmony_ci * machine->physical mapping table starts at this address, read-only.
4462306a36Sopenharmony_ci */
4562306a36Sopenharmony_ci#define __HYPERVISOR_VIRT_START 0xF5800000
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#ifndef __ASSEMBLY__
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistruct cpu_user_regs {
5062306a36Sopenharmony_ci    uint32_t ebx;
5162306a36Sopenharmony_ci    uint32_t ecx;
5262306a36Sopenharmony_ci    uint32_t edx;
5362306a36Sopenharmony_ci    uint32_t esi;
5462306a36Sopenharmony_ci    uint32_t edi;
5562306a36Sopenharmony_ci    uint32_t ebp;
5662306a36Sopenharmony_ci    uint32_t eax;
5762306a36Sopenharmony_ci    uint16_t error_code;    /* private */
5862306a36Sopenharmony_ci    uint16_t entry_vector;  /* private */
5962306a36Sopenharmony_ci    uint32_t eip;
6062306a36Sopenharmony_ci    uint16_t cs;
6162306a36Sopenharmony_ci    uint8_t  saved_upcall_mask;
6262306a36Sopenharmony_ci    uint8_t  _pad0;
6362306a36Sopenharmony_ci    uint32_t eflags;        /* eflags.IF == !saved_upcall_mask */
6462306a36Sopenharmony_ci    uint32_t esp;
6562306a36Sopenharmony_ci    uint16_t ss, _pad1;
6662306a36Sopenharmony_ci    uint16_t es, _pad2;
6762306a36Sopenharmony_ci    uint16_t ds, _pad3;
6862306a36Sopenharmony_ci    uint16_t fs, _pad4;
6962306a36Sopenharmony_ci    uint16_t gs, _pad5;
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_citypedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistruct arch_vcpu_info {
7662306a36Sopenharmony_ci    unsigned long cr2;
7762306a36Sopenharmony_ci    unsigned long pad[5]; /* sizeof(struct vcpu_info) == 64 */
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistruct xen_callback {
8162306a36Sopenharmony_ci	unsigned long cs;
8262306a36Sopenharmony_ci	unsigned long eip;
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_citypedef struct xen_callback xen_callback_t;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#define XEN_CALLBACK(__cs, __eip)				\
8762306a36Sopenharmony_ci	((struct xen_callback){ .cs = (__cs), .eip = (unsigned long)(__eip) })
8862306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/*
9262306a36Sopenharmony_ci * Page-directory addresses above 4GB do not fit into architectural %cr3.
9362306a36Sopenharmony_ci * When accessing %cr3, or equivalent field in vcpu_guest_context, guests
9462306a36Sopenharmony_ci * must use the following accessor macros to pack/unpack valid MFNs.
9562306a36Sopenharmony_ci *
9662306a36Sopenharmony_ci * Note that Xen is using the fact that the pagetable base is always
9762306a36Sopenharmony_ci * page-aligned, and putting the 12 MSB of the address into the 12 LSB
9862306a36Sopenharmony_ci * of cr3.
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_ci#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
10162306a36Sopenharmony_ci#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci#endif /* _ASM_X86_XEN_INTERFACE_32_H */
104