]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/xen/interface/arch-x86/hvm/save.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / xen / interface / arch-x86 / hvm / save.h
1 /* 
2  * Structure definitions for HVM state that is held by Xen and must
3  * be saved along with the domain's memory and device-model state.
4  * 
5  * Copyright (c) 2007 XenSource Ltd.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to
9  * deal in the Software without restriction, including without limitation the
10  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25
26 #ifndef __XEN_PUBLIC_HVM_SAVE_X86_H__
27 #define __XEN_PUBLIC_HVM_SAVE_X86_H__
28
29 /* 
30  * Save/restore header: general info about the save file. 
31  */
32
33 #define HVM_FILE_MAGIC   0x54381286
34 #define HVM_FILE_VERSION 0x00000001
35
36 struct hvm_save_header {
37     uint32_t magic;             /* Must be HVM_FILE_MAGIC */
38     uint32_t version;           /* File format version */
39     uint64_t changeset;         /* Version of Xen that saved this file */
40     uint32_t cpuid;             /* CPUID[0x01][%eax] on the saving machine */
41     uint32_t pad0;
42 };
43
44 DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
45
46
47 /*
48  * Processor
49  */
50
51 struct hvm_hw_cpu {
52     uint8_t  fpu_regs[512];
53
54     uint64_t rax;
55     uint64_t rbx;
56     uint64_t rcx;
57     uint64_t rdx;
58     uint64_t rbp;
59     uint64_t rsi;
60     uint64_t rdi;
61     uint64_t rsp;
62     uint64_t r8;
63     uint64_t r9;
64     uint64_t r10;
65     uint64_t r11;
66     uint64_t r12;
67     uint64_t r13;
68     uint64_t r14;
69     uint64_t r15;
70
71     uint64_t rip;
72     uint64_t rflags;
73
74     uint64_t cr0;
75     uint64_t cr2;
76     uint64_t cr3;
77     uint64_t cr4;
78
79     uint64_t dr0;
80     uint64_t dr1;
81     uint64_t dr2;
82     uint64_t dr3;
83     uint64_t dr6;
84     uint64_t dr7;    
85
86     uint32_t cs_sel;
87     uint32_t ds_sel;
88     uint32_t es_sel;
89     uint32_t fs_sel;
90     uint32_t gs_sel;
91     uint32_t ss_sel;
92     uint32_t tr_sel;
93     uint32_t ldtr_sel;
94
95     uint32_t cs_limit;
96     uint32_t ds_limit;
97     uint32_t es_limit;
98     uint32_t fs_limit;
99     uint32_t gs_limit;
100     uint32_t ss_limit;
101     uint32_t tr_limit;
102     uint32_t ldtr_limit;
103     uint32_t idtr_limit;
104     uint32_t gdtr_limit;
105
106     uint64_t cs_base;
107     uint64_t ds_base;
108     uint64_t es_base;
109     uint64_t fs_base;
110     uint64_t gs_base;
111     uint64_t ss_base;
112     uint64_t tr_base;
113     uint64_t ldtr_base;
114     uint64_t idtr_base;
115     uint64_t gdtr_base;
116
117     uint32_t cs_arbytes;
118     uint32_t ds_arbytes;
119     uint32_t es_arbytes;
120     uint32_t fs_arbytes;
121     uint32_t gs_arbytes;
122     uint32_t ss_arbytes;
123     uint32_t tr_arbytes;
124     uint32_t ldtr_arbytes;
125
126     uint32_t sysenter_cs;
127     uint32_t padding0;
128
129     uint64_t sysenter_esp;
130     uint64_t sysenter_eip;
131
132     /* msr for em64t */
133     uint64_t shadow_gs;
134
135     /* msr content saved/restored. */
136     uint64_t msr_flags;
137     uint64_t msr_lstar;
138     uint64_t msr_star;
139     uint64_t msr_cstar;
140     uint64_t msr_syscall_mask;
141     uint64_t msr_efer;
142
143     /* guest's idea of what rdtsc() would return */
144     uint64_t tsc;
145
146     /* pending event, if any */
147     union {
148         uint32_t pending_event;
149         struct {
150             uint8_t  pending_vector:8;
151             uint8_t  pending_type:3;
152             uint8_t  pending_error_valid:1;
153             uint32_t pending_reserved:19;
154             uint8_t  pending_valid:1;
155         };
156     };
157     /* error code for pending event */
158     uint32_t error_code;
159 };
160
161 DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu);
162
163
164 /*
165  * PIC
166  */
167
168 struct hvm_hw_vpic {
169     /* IR line bitmasks. */
170     uint8_t irr;
171     uint8_t imr;
172     uint8_t isr;
173
174     /* Line IRx maps to IRQ irq_base+x */
175     uint8_t irq_base;
176
177     /*
178      * Where are we in ICW2-4 initialisation (0 means no init in progress)?
179      * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
180      * Bit 2: ICW1.IC4  (1 == ICW4 included in init sequence)
181      * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
182      */
183     uint8_t init_state:4;
184
185     /* IR line with highest priority. */
186     uint8_t priority_add:4;
187
188     /* Reads from A=0 obtain ISR or IRR? */
189     uint8_t readsel_isr:1;
190
191     /* Reads perform a polling read? */
192     uint8_t poll:1;
193
194     /* Automatically clear IRQs from the ISR during INTA? */
195     uint8_t auto_eoi:1;
196
197     /* Automatically rotate IRQ priorities during AEOI? */
198     uint8_t rotate_on_auto_eoi:1;
199
200     /* Exclude slave inputs when considering in-service IRQs? */
201     uint8_t special_fully_nested_mode:1;
202
203     /* Special mask mode excludes masked IRs from AEOI and priority checks. */
204     uint8_t special_mask_mode:1;
205
206     /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
207     uint8_t is_master:1;
208
209     /* Edge/trigger selection. */
210     uint8_t elcr;
211
212     /* Virtual INT output. */
213     uint8_t int_output;
214 };
215
216 DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
217
218
219 /*
220  * IO-APIC
221  */
222
223 #ifdef __ia64__
224 #define VIOAPIC_IS_IOSAPIC 1
225 #define VIOAPIC_NUM_PINS  24
226 #else
227 #define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
228 #endif
229
230 struct hvm_hw_vioapic {
231     uint64_t base_address;
232     uint32_t ioregsel;
233     uint32_t id;
234     union vioapic_redir_entry
235     {
236         uint64_t bits;
237         struct {
238             uint8_t vector;
239             uint8_t delivery_mode:3;
240             uint8_t dest_mode:1;
241             uint8_t delivery_status:1;
242             uint8_t polarity:1;
243             uint8_t remote_irr:1;
244             uint8_t trig_mode:1;
245             uint8_t mask:1;
246             uint8_t reserve:7;
247 #if !VIOAPIC_IS_IOSAPIC
248             uint8_t reserved[4];
249             uint8_t dest_id;
250 #else
251             uint8_t reserved[3];
252             uint16_t dest_id;
253 #endif
254         } fields;
255     } redirtbl[VIOAPIC_NUM_PINS];
256 };
257
258 DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
259
260
261 /*
262  * LAPIC
263  */
264
265 struct hvm_hw_lapic {
266     uint64_t             apic_base_msr;
267     uint32_t             disabled; /* VLAPIC_xx_DISABLED */
268     uint32_t             timer_divisor;
269 };
270
271 DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
272
273 struct hvm_hw_lapic_regs {
274     uint8_t data[1024];
275 };
276
277 DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
278
279
280 /*
281  * IRQs
282  */
283
284 struct hvm_hw_pci_irqs {
285     /*
286      * Virtual interrupt wires for a single PCI bus.
287      * Indexed by: device*4 + INTx#.
288      */
289     union {
290         DECLARE_BITMAP(i, 32*4);
291         uint64_t pad[2];
292     };
293 };
294
295 DECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs);
296
297 struct hvm_hw_isa_irqs {
298     /*
299      * Virtual interrupt wires for ISA devices.
300      * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
301      */
302     union {
303         DECLARE_BITMAP(i, 16);
304         uint64_t pad[1];
305     };
306 };
307
308 DECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs);
309
310 struct hvm_hw_pci_link {
311     /*
312      * PCI-ISA interrupt router.
313      * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
314      * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
315      * The router provides a programmable mapping from each link to a GSI.
316      */
317     uint8_t route[4];
318     uint8_t pad0[4];
319 };
320
321 DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);
322
323 /* 
324  *  PIT
325  */
326
327 struct hvm_hw_pit {
328     struct hvm_hw_pit_channel {
329         uint32_t count; /* can be 65536 */
330         uint16_t latched_count;
331         uint8_t count_latched;
332         uint8_t status_latched;
333         uint8_t status;
334         uint8_t read_state;
335         uint8_t write_state;
336         uint8_t write_latch;
337         uint8_t rw_mode;
338         uint8_t mode;
339         uint8_t bcd; /* not supported */
340         uint8_t gate; /* timer start */
341     } channels[3];  /* 3 x 16 bytes */
342     uint32_t speaker_data_on;
343     uint32_t pad0;
344 };
345
346 DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);
347
348
349 /* 
350  * RTC
351  */ 
352
353 #define RTC_CMOS_SIZE 14
354 struct hvm_hw_rtc {
355     /* CMOS bytes */
356     uint8_t cmos_data[RTC_CMOS_SIZE];
357     /* Index register for 2-part operations */
358     uint8_t cmos_index;
359     uint8_t pad0;
360 };
361
362 DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);
363
364
365 /*
366  * HPET
367  */
368
369 #define HPET_TIMER_NUM     3    /* 3 timers supported now */
370 struct hvm_hw_hpet {
371     /* Memory-mapped, software visible registers */
372     uint64_t capability;        /* capabilities */
373     uint64_t res0;              /* reserved */
374     uint64_t config;            /* configuration */
375     uint64_t res1;              /* reserved */
376     uint64_t isr;               /* interrupt status reg */
377     uint64_t res2[25];          /* reserved */
378     uint64_t mc64;              /* main counter */
379     uint64_t res3;              /* reserved */
380     struct {                    /* timers */
381         uint64_t config;        /* configuration/cap */
382         uint64_t cmp;           /* comparator */
383         uint64_t fsb;           /* FSB route, not supported now */
384         uint64_t res4;          /* reserved */
385     } timers[HPET_TIMER_NUM];
386     uint64_t res5[4*(24-HPET_TIMER_NUM)];  /* reserved, up to 0x3ff */
387
388     /* Hidden register state */
389     uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
390 };
391
392 DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
393
394
395 /*
396  * PM timer
397  */
398
399 struct hvm_hw_pmtimer {
400     uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
401     uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
402     uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
403 };
404
405 DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
406
407 /*
408  * MTRR MSRs
409  */
410
411 struct hvm_hw_mtrr {
412 #define MTRR_VCNT 8
413 #define NUM_FIXED_MSR 11
414     uint64_t msr_pat_cr;
415     /* mtrr physbase & physmask msr pair*/
416     uint64_t msr_mtrr_var[MTRR_VCNT*2];
417     uint64_t msr_mtrr_fixed[NUM_FIXED_MSR];
418     uint64_t msr_mtrr_cap;
419     uint64_t msr_mtrr_def_type;
420 };
421
422 DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr);
423
424 /* 
425  * Largest type-code in use
426  */
427 #define HVM_SAVE_CODE_MAX 14
428
429 #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */