Initial revision
[linux-2.6.git] / include / asm-xen / xen-public / arch-x86_64.h
1 /******************************************************************************
2  * arch-x86_64.h
3  * 
4  * Guest OS interface to x86 64-bit Xen.
5  * 
6  * Copyright (c) 2004, K A Fraser
7  */
8
9 #ifndef __XEN_PUBLIC_ARCH_X86_64_H__
10 #define __XEN_PUBLIC_ARCH_X86_64_H__
11
12 #ifndef PACKED
13 /* GCC-specific way to pack structure definitions (no implicit padding). */
14 #define PACKED __attribute__ ((packed))
15 #endif
16
17 /* Pointers are naturally 64 bits in this architecture; no padding needed. */
18 #define _MEMORY_PADDING(_X)
19 #define MEMORY_PADDING 
20
21 /*
22  * SEGMENT DESCRIPTOR TABLES
23  */
24 /*
25  * A number of GDT entries are reserved by Xen. These are not situated at the
26  * start of the GDT because some stupid OSes export hard-coded selector values
27  * in their ABI. These hard-coded values are always near the start of the GDT,
28  * so Xen places itself out of the way.
29  * 
30  * NR_RESERVED_GDT_ENTRIES is (8 + 4 * NR_CPUS) Please update this value if 
31  * you increase NR_CPUS or add another GDT entry to gdt_table in boot/x86_64.S
32  * 
33  * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
34  * and LAST_RESERVED_GDT_ENTRY are reserved).
35  */
36 #define NR_RESERVED_GDT_ENTRIES    136
37 #define FIRST_RESERVED_GDT_ENTRY   256
38 #define LAST_RESERVED_GDT_ENTRY    \
39   (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
40
41 /*
42  * 64-bit segment selectors
43  * These flat segments are in the Xen-private section of every GDT. Since these
44  * are also present in the initial GDT, many OSes will be able to avoid
45  * installing their own GDT.
46  */
47
48 #define FLAT_RING3_CS32 0x0823  /* GDT index 260 */
49 #define FLAT_RING3_CS64 0x0833  /* GDT index 261 */
50 #define FLAT_RING3_DS32 0x082b  /* GDT index 262 */
51 #define FLAT_RING3_DS64 0x0000  /* NULL selector */
52 #define FLAT_RING3_SS32 0x082b  /* GDT index 262 */
53 #define FLAT_RING3_SS64 0x082b  /* GDT index 262 */
54
55 #define FLAT_KERNEL_DS64 FLAT_RING3_DS64
56 #define FLAT_KERNEL_DS32 FLAT_RING3_DS32
57 #define FLAT_KERNEL_DS   FLAT_KERNEL_DS64
58 #define FLAT_KERNEL_CS64 FLAT_RING3_CS64
59 #define FLAT_KERNEL_CS32 FLAT_RING3_CS32
60 #define FLAT_KERNEL_CS   FLAT_KERNEL_CS64
61 #define FLAT_KERNEL_SS64 FLAT_RING3_SS64
62 #define FLAT_KERNEL_SS32 FLAT_RING3_SS32
63 #define FLAT_KERNEL_SS   FLAT_KERNEL_SS64
64
65 #define FLAT_USER_DS64 FLAT_RING3_DS64
66 #define FLAT_USER_DS32 FLAT_RING3_DS32
67 #define FLAT_USER_DS   FLAT_USER_DS64
68 #define FLAT_USER_CS64 FLAT_RING3_CS64
69 #define FLAT_USER_CS32 FLAT_RING3_CS32
70 #define FLAT_USER_CS   FLAT_USER_CS64
71 #define FLAT_USER_SS64 FLAT_RING3_SS64
72 #define FLAT_USER_SS32 FLAT_RING3_SS32
73 #define FLAT_USER_SS   FLAT_USER_SS64
74
75 /* And the trap vector is... */
76 #define TRAP_INSTR "syscall"
77
78 #ifndef HYPERVISOR_VIRT_START
79 #define HYPERVISOR_VIRT_START (0xFFFF800000000000UL)
80 #define HYPERVISOR_VIRT_END   (0xFFFF880000000000UL)
81 #endif
82
83 #ifndef __ASSEMBLY__
84
85 /* The machine->physical mapping table starts at this address, read-only. */
86 #ifndef machine_to_phys_mapping
87 #define machine_to_phys_mapping ((u32 *)HYPERVISOR_VIRT_START)
88 #endif
89
90 /*
91  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
92  *  @which == SEGBASE_*  ;  @base == 64-bit base address
93  * Returns 0 on success.
94  */
95 #define SEGBASE_FS          0
96 #define SEGBASE_GS_USER     1
97 #define SEGBASE_GS_KERNEL   2
98 #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
99
100 /*
101  * int HYPERVISOR_switch_to_user(void)
102  * All arguments are on the kernel stack, in the following format.
103  * Never returns if successful. Current kernel context is lost.
104  * If flags contains ECF_IN_SYSCALL:
105  *   Restore RAX, RIP, RFLAGS, RSP. 
106  *   Discard R11, RCX, CS, SS.
107  * Otherwise:
108  *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
109  * All other registers are saved on hypercall entry and restored to user.
110  */
111 /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
112 #define ECF_IN_SYSCALL (1<<8)
113 struct switch_to_user {
114     /* Top of stack (%rsp at point of hypercall). */
115     u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
116     /* Bottom of switch_to_user stack frame. */
117 } PACKED;
118
119 /* NB. Both the following are 64 bits each. */
120 typedef unsigned long memory_t;   /* Full-sized pointer/address/memory-size. */
121 typedef unsigned long cpureg_t;   /* Full-sized register.                    */
122
123 /*
124  * Send an array of these to HYPERVISOR_set_trap_table().
125  * N.B. As in x86/32 mode, the privilege level specifies which modes may enter
126  * a trap via a software interrupt. Since rings 1 and 2 are unavailable, we
127  * allocate privilege levels as follows:
128  *  Level == 0: Noone may enter
129  *  Level == 1: Kernel may enter
130  *  Level == 2: Kernel may enter
131  *  Level == 3: Everyone may enter
132  */
133 #define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
134 #define TI_GET_IF(_ti)       ((_ti)->flags & 4)
135 #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
136 #define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
137 typedef struct {
138     u8       vector;  /* 0: exception vector                              */
139     u8       flags;   /* 1: 0-3: privilege level; 4: clear event enable?  */
140     u16      cs;      /* 2: code selector                                 */
141     u32      __pad;   /* 4 */
142     memory_t address; /* 8: code address                                  */
143 } PACKED trap_info_t; /* 16 bytes */
144
145 typedef struct xen_regs
146 {
147     u64 r15;
148     u64 r14;
149     u64 r13;
150     u64 r12;
151     union { u64 rbp, ebp; } PACKED;
152     union { u64 rbx, ebx; } PACKED;
153     u64 r11;
154     u64 r10;
155     u64 r9;
156     u64 r8;
157     union { u64 rax, eax; } PACKED;
158     union { u64 rcx, ecx; } PACKED;
159     union { u64 rdx, edx; } PACKED;
160     union { u64 rsi, esi; } PACKED;
161     union { u64 rdi, edi; } PACKED;
162     u32 error_code;    /* private */
163     u32 entry_vector;  /* private */
164     union { u64 rip, eip; } PACKED;
165     u64 cs;
166     union { u64 rflags, eflags; } PACKED;
167     union { u64 rsp, esp; } PACKED;
168     u64 ss;
169     u64 es;
170     u64 ds;
171     u64 fs;      /* Non-zero => takes precedence over fs_base.     */
172     u64 gs;      /* Non-zero => takes precedence over gs_base_app. */
173     u64 fs_base;
174     u64 gs_base_kernel;
175     u64 gs_base_user;
176 } PACKED execution_context_t;
177
178 typedef u64 tsc_timestamp_t; /* RDTSC timestamp */
179
180 /*
181  * The following is all CPU context. Note that the i387_ctxt block is filled 
182  * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
183  */
184 typedef struct {
185 #define ECF_I387_VALID (1<<0)
186 #define ECF_VMX_GUEST  (1<<1)
187 #define ECF_IN_KERNEL (1<<2)
188     unsigned long flags;
189     execution_context_t cpu_ctxt;           /* User-level CPU registers     */
190     char          fpu_ctxt[512];            /* User-level FPU registers     */
191     trap_info_t   trap_ctxt[256];           /* Virtual IDT                  */
192     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
193     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
194     unsigned long kernel_ss, kernel_esp;  /* Virtual TSS (only SS1/ESP1)  */
195     unsigned long pt_base;                  /* CR3 (pagetable base)         */
196     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
197     unsigned long event_callback_eip;
198     unsigned long failsafe_callback_eip;
199     unsigned long syscall_callback_eip;
200     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
201 } PACKED full_execution_context_t;
202
203 typedef struct {
204     /* MFN of a table of MFNs that make up p2m table */
205     u64 pfn_to_mfn_frame_list;
206 } PACKED arch_shared_info_t;
207
208 typedef struct {
209 } PACKED arch_vcpu_info_t;
210
211 #endif /* !__ASSEMBLY__ */
212
213 #endif