1183375Skmacy/*
2183375Skmacy * Structure definitions for HVM state that is held by Xen and must
3183375Skmacy * be saved along with the domain's memory and device-model state.
4183375Skmacy *
5183375Skmacy * Copyright (c) 2007 XenSource Ltd.
6183375Skmacy *
7183375Skmacy * Permission is hereby granted, free of charge, to any person obtaining a copy
8183375Skmacy * of this software and associated documentation files (the "Software"), to
9183375Skmacy * deal in the Software without restriction, including without limitation the
10183375Skmacy * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11183375Skmacy * sell copies of the Software, and to permit persons to whom the Software is
12183375Skmacy * furnished to do so, subject to the following conditions:
13183375Skmacy *
14183375Skmacy * The above copyright notice and this permission notice shall be included in
15183375Skmacy * all copies or substantial portions of the Software.
16183375Skmacy *
17183375Skmacy * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18183375Skmacy * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19183375Skmacy * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20183375Skmacy * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21183375Skmacy * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22183375Skmacy * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23183375Skmacy * DEALINGS IN THE SOFTWARE.
24183375Skmacy */
25183375Skmacy
26183375Skmacy#ifndef __XEN_PUBLIC_HVM_SAVE_X86_H__
27183375Skmacy#define __XEN_PUBLIC_HVM_SAVE_X86_H__
28183375Skmacy
29183375Skmacy/*
30183375Skmacy * Save/restore header: general info about the save file.
31183375Skmacy */
32183375Skmacy
33183375Skmacy#define HVM_FILE_MAGIC   0x54381286
34183375Skmacy#define HVM_FILE_VERSION 0x00000001
35183375Skmacy
36183375Skmacystruct hvm_save_header {
37183375Skmacy    uint32_t magic;             /* Must be HVM_FILE_MAGIC */
38183375Skmacy    uint32_t version;           /* File format version */
39183375Skmacy    uint64_t changeset;         /* Version of Xen that saved this file */
40183375Skmacy    uint32_t cpuid;             /* CPUID[0x01][%eax] on the saving machine */
41251767Sgibbs    uint32_t gtsc_khz;        /* Guest's TSC frequency in kHz */
42183375Skmacy};
43183375Skmacy
44183375SkmacyDECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
45183375Skmacy
46183375Skmacy
47183375Skmacy/*
48183375Skmacy * Processor
49251767Sgibbs *
50251767Sgibbs * Compat: Pre-3.4 didn't have msr_tsc_aux
51183375Skmacy */
52183375Skmacy
53183375Skmacystruct hvm_hw_cpu {
54183375Skmacy    uint8_t  fpu_regs[512];
55183375Skmacy
56183375Skmacy    uint64_t rax;
57183375Skmacy    uint64_t rbx;
58183375Skmacy    uint64_t rcx;
59183375Skmacy    uint64_t rdx;
60183375Skmacy    uint64_t rbp;
61183375Skmacy    uint64_t rsi;
62183375Skmacy    uint64_t rdi;
63183375Skmacy    uint64_t rsp;
64183375Skmacy    uint64_t r8;
65183375Skmacy    uint64_t r9;
66183375Skmacy    uint64_t r10;
67183375Skmacy    uint64_t r11;
68183375Skmacy    uint64_t r12;
69183375Skmacy    uint64_t r13;
70183375Skmacy    uint64_t r14;
71183375Skmacy    uint64_t r15;
72183375Skmacy
73183375Skmacy    uint64_t rip;
74183375Skmacy    uint64_t rflags;
75183375Skmacy
76183375Skmacy    uint64_t cr0;
77183375Skmacy    uint64_t cr2;
78183375Skmacy    uint64_t cr3;
79183375Skmacy    uint64_t cr4;
80183375Skmacy
81183375Skmacy    uint64_t dr0;
82183375Skmacy    uint64_t dr1;
83183375Skmacy    uint64_t dr2;
84183375Skmacy    uint64_t dr3;
85183375Skmacy    uint64_t dr6;
86183375Skmacy    uint64_t dr7;
87183375Skmacy
88183375Skmacy    uint32_t cs_sel;
89183375Skmacy    uint32_t ds_sel;
90183375Skmacy    uint32_t es_sel;
91183375Skmacy    uint32_t fs_sel;
92183375Skmacy    uint32_t gs_sel;
93183375Skmacy    uint32_t ss_sel;
94183375Skmacy    uint32_t tr_sel;
95183375Skmacy    uint32_t ldtr_sel;
96183375Skmacy
97183375Skmacy    uint32_t cs_limit;
98183375Skmacy    uint32_t ds_limit;
99183375Skmacy    uint32_t es_limit;
100183375Skmacy    uint32_t fs_limit;
101183375Skmacy    uint32_t gs_limit;
102183375Skmacy    uint32_t ss_limit;
103183375Skmacy    uint32_t tr_limit;
104183375Skmacy    uint32_t ldtr_limit;
105183375Skmacy    uint32_t idtr_limit;
106183375Skmacy    uint32_t gdtr_limit;
107183375Skmacy
108183375Skmacy    uint64_t cs_base;
109183375Skmacy    uint64_t ds_base;
110183375Skmacy    uint64_t es_base;
111183375Skmacy    uint64_t fs_base;
112183375Skmacy    uint64_t gs_base;
113183375Skmacy    uint64_t ss_base;
114183375Skmacy    uint64_t tr_base;
115183375Skmacy    uint64_t ldtr_base;
116183375Skmacy    uint64_t idtr_base;
117183375Skmacy    uint64_t gdtr_base;
118183375Skmacy
119183375Skmacy    uint32_t cs_arbytes;
120183375Skmacy    uint32_t ds_arbytes;
121183375Skmacy    uint32_t es_arbytes;
122183375Skmacy    uint32_t fs_arbytes;
123183375Skmacy    uint32_t gs_arbytes;
124183375Skmacy    uint32_t ss_arbytes;
125183375Skmacy    uint32_t tr_arbytes;
126183375Skmacy    uint32_t ldtr_arbytes;
127183375Skmacy
128251767Sgibbs    uint64_t sysenter_cs;
129251767Sgibbs    uint64_t sysenter_esp;
130251767Sgibbs    uint64_t sysenter_eip;
131183375Skmacy
132251767Sgibbs    /* msr for em64t */
133251767Sgibbs    uint64_t shadow_gs;
134251767Sgibbs
135251767Sgibbs    /* msr content saved/restored. */
136251767Sgibbs    uint64_t msr_flags;
137251767Sgibbs    uint64_t msr_lstar;
138251767Sgibbs    uint64_t msr_star;
139251767Sgibbs    uint64_t msr_cstar;
140251767Sgibbs    uint64_t msr_syscall_mask;
141251767Sgibbs    uint64_t msr_efer;
142251767Sgibbs    uint64_t msr_tsc_aux;
143251767Sgibbs
144251767Sgibbs    /* guest's idea of what rdtsc() would return */
145251767Sgibbs    uint64_t tsc;
146251767Sgibbs
147251767Sgibbs    /* pending event, if any */
148251767Sgibbs    union {
149251767Sgibbs        uint32_t pending_event;
150251767Sgibbs        struct {
151251767Sgibbs            uint8_t  pending_vector:8;
152251767Sgibbs            uint8_t  pending_type:3;
153251767Sgibbs            uint8_t  pending_error_valid:1;
154251767Sgibbs            uint32_t pending_reserved:19;
155251767Sgibbs            uint8_t  pending_valid:1;
156251767Sgibbs        };
157251767Sgibbs    };
158251767Sgibbs    /* error code for pending event */
159251767Sgibbs    uint32_t error_code;
160251767Sgibbs};
161251767Sgibbs
162251767Sgibbsstruct hvm_hw_cpu_compat {
163251767Sgibbs    uint8_t  fpu_regs[512];
164251767Sgibbs
165251767Sgibbs    uint64_t rax;
166251767Sgibbs    uint64_t rbx;
167251767Sgibbs    uint64_t rcx;
168251767Sgibbs    uint64_t rdx;
169251767Sgibbs    uint64_t rbp;
170251767Sgibbs    uint64_t rsi;
171251767Sgibbs    uint64_t rdi;
172251767Sgibbs    uint64_t rsp;
173251767Sgibbs    uint64_t r8;
174251767Sgibbs    uint64_t r9;
175251767Sgibbs    uint64_t r10;
176251767Sgibbs    uint64_t r11;
177251767Sgibbs    uint64_t r12;
178251767Sgibbs    uint64_t r13;
179251767Sgibbs    uint64_t r14;
180251767Sgibbs    uint64_t r15;
181251767Sgibbs
182251767Sgibbs    uint64_t rip;
183251767Sgibbs    uint64_t rflags;
184251767Sgibbs
185251767Sgibbs    uint64_t cr0;
186251767Sgibbs    uint64_t cr2;
187251767Sgibbs    uint64_t cr3;
188251767Sgibbs    uint64_t cr4;
189251767Sgibbs
190251767Sgibbs    uint64_t dr0;
191251767Sgibbs    uint64_t dr1;
192251767Sgibbs    uint64_t dr2;
193251767Sgibbs    uint64_t dr3;
194251767Sgibbs    uint64_t dr6;
195251767Sgibbs    uint64_t dr7;
196251767Sgibbs
197251767Sgibbs    uint32_t cs_sel;
198251767Sgibbs    uint32_t ds_sel;
199251767Sgibbs    uint32_t es_sel;
200251767Sgibbs    uint32_t fs_sel;
201251767Sgibbs    uint32_t gs_sel;
202251767Sgibbs    uint32_t ss_sel;
203251767Sgibbs    uint32_t tr_sel;
204251767Sgibbs    uint32_t ldtr_sel;
205251767Sgibbs
206251767Sgibbs    uint32_t cs_limit;
207251767Sgibbs    uint32_t ds_limit;
208251767Sgibbs    uint32_t es_limit;
209251767Sgibbs    uint32_t fs_limit;
210251767Sgibbs    uint32_t gs_limit;
211251767Sgibbs    uint32_t ss_limit;
212251767Sgibbs    uint32_t tr_limit;
213251767Sgibbs    uint32_t ldtr_limit;
214251767Sgibbs    uint32_t idtr_limit;
215251767Sgibbs    uint32_t gdtr_limit;
216251767Sgibbs
217251767Sgibbs    uint64_t cs_base;
218251767Sgibbs    uint64_t ds_base;
219251767Sgibbs    uint64_t es_base;
220251767Sgibbs    uint64_t fs_base;
221251767Sgibbs    uint64_t gs_base;
222251767Sgibbs    uint64_t ss_base;
223251767Sgibbs    uint64_t tr_base;
224251767Sgibbs    uint64_t ldtr_base;
225251767Sgibbs    uint64_t idtr_base;
226251767Sgibbs    uint64_t gdtr_base;
227251767Sgibbs
228251767Sgibbs    uint32_t cs_arbytes;
229251767Sgibbs    uint32_t ds_arbytes;
230251767Sgibbs    uint32_t es_arbytes;
231251767Sgibbs    uint32_t fs_arbytes;
232251767Sgibbs    uint32_t gs_arbytes;
233251767Sgibbs    uint32_t ss_arbytes;
234251767Sgibbs    uint32_t tr_arbytes;
235251767Sgibbs    uint32_t ldtr_arbytes;
236251767Sgibbs
237251767Sgibbs    uint64_t sysenter_cs;
238183375Skmacy    uint64_t sysenter_esp;
239183375Skmacy    uint64_t sysenter_eip;
240183375Skmacy
241183375Skmacy    /* msr for em64t */
242183375Skmacy    uint64_t shadow_gs;
243183375Skmacy
244183375Skmacy    /* msr content saved/restored. */
245183375Skmacy    uint64_t msr_flags;
246183375Skmacy    uint64_t msr_lstar;
247183375Skmacy    uint64_t msr_star;
248183375Skmacy    uint64_t msr_cstar;
249183375Skmacy    uint64_t msr_syscall_mask;
250183375Skmacy    uint64_t msr_efer;
251251767Sgibbs    /*uint64_t msr_tsc_aux; COMPAT */
252183375Skmacy
253183375Skmacy    /* guest's idea of what rdtsc() would return */
254183375Skmacy    uint64_t tsc;
255183375Skmacy
256183375Skmacy    /* pending event, if any */
257183375Skmacy    union {
258183375Skmacy        uint32_t pending_event;
259183375Skmacy        struct {
260183375Skmacy            uint8_t  pending_vector:8;
261183375Skmacy            uint8_t  pending_type:3;
262183375Skmacy            uint8_t  pending_error_valid:1;
263183375Skmacy            uint32_t pending_reserved:19;
264183375Skmacy            uint8_t  pending_valid:1;
265183375Skmacy        };
266183375Skmacy    };
267183375Skmacy    /* error code for pending event */
268183375Skmacy    uint32_t error_code;
269183375Skmacy};
270183375Skmacy
271251767Sgibbsstatic inline int _hvm_hw_fix_cpu(void *h) {
272251767Sgibbs    struct hvm_hw_cpu *new=h;
273251767Sgibbs    struct hvm_hw_cpu_compat *old=h;
274183375Skmacy
275251767Sgibbs    /* If we copy from the end backwards, we should
276251767Sgibbs     * be able to do the modification in-place */
277251767Sgibbs    new->error_code=old->error_code;
278251767Sgibbs    new->pending_event=old->pending_event;
279251767Sgibbs    new->tsc=old->tsc;
280251767Sgibbs    new->msr_tsc_aux=0;
281183375Skmacy
282251767Sgibbs    return 0;
283251767Sgibbs}
284251767Sgibbs
285251767SgibbsDECLARE_HVM_SAVE_TYPE_COMPAT(CPU, 2, struct hvm_hw_cpu, \
286251767Sgibbs                             struct hvm_hw_cpu_compat, _hvm_hw_fix_cpu);
287251767Sgibbs
288183375Skmacy/*
289183375Skmacy * PIC
290183375Skmacy */
291183375Skmacy
292183375Skmacystruct hvm_hw_vpic {
293183375Skmacy    /* IR line bitmasks. */
294183375Skmacy    uint8_t irr;
295183375Skmacy    uint8_t imr;
296183375Skmacy    uint8_t isr;
297183375Skmacy
298183375Skmacy    /* Line IRx maps to IRQ irq_base+x */
299183375Skmacy    uint8_t irq_base;
300183375Skmacy
301183375Skmacy    /*
302183375Skmacy     * Where are we in ICW2-4 initialisation (0 means no init in progress)?
303183375Skmacy     * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
304183375Skmacy     * Bit 2: ICW1.IC4  (1 == ICW4 included in init sequence)
305183375Skmacy     * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
306183375Skmacy     */
307183375Skmacy    uint8_t init_state:4;
308183375Skmacy
309183375Skmacy    /* IR line with highest priority. */
310183375Skmacy    uint8_t priority_add:4;
311183375Skmacy
312183375Skmacy    /* Reads from A=0 obtain ISR or IRR? */
313183375Skmacy    uint8_t readsel_isr:1;
314183375Skmacy
315183375Skmacy    /* Reads perform a polling read? */
316183375Skmacy    uint8_t poll:1;
317183375Skmacy
318183375Skmacy    /* Automatically clear IRQs from the ISR during INTA? */
319183375Skmacy    uint8_t auto_eoi:1;
320183375Skmacy
321183375Skmacy    /* Automatically rotate IRQ priorities during AEOI? */
322183375Skmacy    uint8_t rotate_on_auto_eoi:1;
323183375Skmacy
324183375Skmacy    /* Exclude slave inputs when considering in-service IRQs? */
325183375Skmacy    uint8_t special_fully_nested_mode:1;
326183375Skmacy
327183375Skmacy    /* Special mask mode excludes masked IRs from AEOI and priority checks. */
328183375Skmacy    uint8_t special_mask_mode:1;
329183375Skmacy
330183375Skmacy    /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
331183375Skmacy    uint8_t is_master:1;
332183375Skmacy
333183375Skmacy    /* Edge/trigger selection. */
334183375Skmacy    uint8_t elcr;
335183375Skmacy
336183375Skmacy    /* Virtual INT output. */
337183375Skmacy    uint8_t int_output;
338183375Skmacy};
339183375Skmacy
340183375SkmacyDECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
341183375Skmacy
342183375Skmacy
343183375Skmacy/*
344183375Skmacy * IO-APIC
345183375Skmacy */
346183375Skmacy
347183375Skmacy#define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
348183375Skmacy
349183375Skmacystruct hvm_hw_vioapic {
350183375Skmacy    uint64_t base_address;
351183375Skmacy    uint32_t ioregsel;
352183375Skmacy    uint32_t id;
353183375Skmacy    union vioapic_redir_entry
354183375Skmacy    {
355183375Skmacy        uint64_t bits;
356183375Skmacy        struct {
357183375Skmacy            uint8_t vector;
358183375Skmacy            uint8_t delivery_mode:3;
359183375Skmacy            uint8_t dest_mode:1;
360183375Skmacy            uint8_t delivery_status:1;
361183375Skmacy            uint8_t polarity:1;
362183375Skmacy            uint8_t remote_irr:1;
363183375Skmacy            uint8_t trig_mode:1;
364183375Skmacy            uint8_t mask:1;
365183375Skmacy            uint8_t reserve:7;
366183375Skmacy            uint8_t reserved[4];
367183375Skmacy            uint8_t dest_id;
368183375Skmacy        } fields;
369183375Skmacy    } redirtbl[VIOAPIC_NUM_PINS];
370183375Skmacy};
371183375Skmacy
372183375SkmacyDECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
373183375Skmacy
374183375Skmacy
375183375Skmacy/*
376183375Skmacy * LAPIC
377183375Skmacy */
378183375Skmacy
379183375Skmacystruct hvm_hw_lapic {
380183375Skmacy    uint64_t             apic_base_msr;
381183375Skmacy    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
382183375Skmacy    uint32_t             timer_divisor;
383251767Sgibbs    uint64_t             tdt_msr;
384183375Skmacy};
385183375Skmacy
386183375SkmacyDECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
387183375Skmacy
388183375Skmacystruct hvm_hw_lapic_regs {
389183375Skmacy    uint8_t data[1024];
390183375Skmacy};
391183375Skmacy
392183375SkmacyDECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
393183375Skmacy
394183375Skmacy
395183375Skmacy/*
396183375Skmacy * IRQs
397183375Skmacy */
398183375Skmacy
399183375Skmacystruct hvm_hw_pci_irqs {
400183375Skmacy    /*
401183375Skmacy     * Virtual interrupt wires for a single PCI bus.
402183375Skmacy     * Indexed by: device*4 + INTx#.
403183375Skmacy     */
404183375Skmacy    union {
405251767Sgibbs        unsigned long i[16 / sizeof (unsigned long)]; /* DECLARE_BITMAP(i, 32*4); */
406183375Skmacy        uint64_t pad[2];
407183375Skmacy    };
408183375Skmacy};
409183375Skmacy
410183375SkmacyDECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs);
411183375Skmacy
412183375Skmacystruct hvm_hw_isa_irqs {
413183375Skmacy    /*
414183375Skmacy     * Virtual interrupt wires for ISA devices.
415183375Skmacy     * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
416183375Skmacy     */
417183375Skmacy    union {
418251767Sgibbs        unsigned long i[1];  /* DECLARE_BITMAP(i, 16); */
419183375Skmacy        uint64_t pad[1];
420183375Skmacy    };
421183375Skmacy};
422183375Skmacy
423183375SkmacyDECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs);
424183375Skmacy
425183375Skmacystruct hvm_hw_pci_link {
426183375Skmacy    /*
427183375Skmacy     * PCI-ISA interrupt router.
428183375Skmacy     * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
429183375Skmacy     * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
430183375Skmacy     * The router provides a programmable mapping from each link to a GSI.
431183375Skmacy     */
432183375Skmacy    uint8_t route[4];
433183375Skmacy    uint8_t pad0[4];
434183375Skmacy};
435183375Skmacy
436183375SkmacyDECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);
437183375Skmacy
438183375Skmacy/*
439183375Skmacy *  PIT
440183375Skmacy */
441183375Skmacy
442183375Skmacystruct hvm_hw_pit {
443183375Skmacy    struct hvm_hw_pit_channel {
444183375Skmacy        uint32_t count; /* can be 65536 */
445183375Skmacy        uint16_t latched_count;
446183375Skmacy        uint8_t count_latched;
447183375Skmacy        uint8_t status_latched;
448183375Skmacy        uint8_t status;
449183375Skmacy        uint8_t read_state;
450183375Skmacy        uint8_t write_state;
451183375Skmacy        uint8_t write_latch;
452183375Skmacy        uint8_t rw_mode;
453183375Skmacy        uint8_t mode;
454183375Skmacy        uint8_t bcd; /* not supported */
455183375Skmacy        uint8_t gate; /* timer start */
456183375Skmacy    } channels[3];  /* 3 x 16 bytes */
457183375Skmacy    uint32_t speaker_data_on;
458183375Skmacy    uint32_t pad0;
459183375Skmacy};
460183375Skmacy
461183375SkmacyDECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);
462183375Skmacy
463183375Skmacy
464183375Skmacy/*
465183375Skmacy * RTC
466183375Skmacy */
467183375Skmacy
468183375Skmacy#define RTC_CMOS_SIZE 14
469183375Skmacystruct hvm_hw_rtc {
470183375Skmacy    /* CMOS bytes */
471183375Skmacy    uint8_t cmos_data[RTC_CMOS_SIZE];
472183375Skmacy    /* Index register for 2-part operations */
473183375Skmacy    uint8_t cmos_index;
474183375Skmacy    uint8_t pad0;
475183375Skmacy};
476183375Skmacy
477183375SkmacyDECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);
478183375Skmacy
479183375Skmacy
480183375Skmacy/*
481183375Skmacy * HPET
482183375Skmacy */
483183375Skmacy
484183375Skmacy#define HPET_TIMER_NUM     3    /* 3 timers supported now */
485183375Skmacystruct hvm_hw_hpet {
486183375Skmacy    /* Memory-mapped, software visible registers */
487183375Skmacy    uint64_t capability;        /* capabilities */
488183375Skmacy    uint64_t res0;              /* reserved */
489183375Skmacy    uint64_t config;            /* configuration */
490183375Skmacy    uint64_t res1;              /* reserved */
491183375Skmacy    uint64_t isr;               /* interrupt status reg */
492183375Skmacy    uint64_t res2[25];          /* reserved */
493183375Skmacy    uint64_t mc64;              /* main counter */
494183375Skmacy    uint64_t res3;              /* reserved */
495183375Skmacy    struct {                    /* timers */
496183375Skmacy        uint64_t config;        /* configuration/cap */
497183375Skmacy        uint64_t cmp;           /* comparator */
498183375Skmacy        uint64_t fsb;           /* FSB route, not supported now */
499183375Skmacy        uint64_t res4;          /* reserved */
500183375Skmacy    } timers[HPET_TIMER_NUM];
501183375Skmacy    uint64_t res5[4*(24-HPET_TIMER_NUM)];  /* reserved, up to 0x3ff */
502183375Skmacy
503183375Skmacy    /* Hidden register state */
504183375Skmacy    uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
505183375Skmacy};
506183375Skmacy
507183375SkmacyDECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
508183375Skmacy
509183375Skmacy
510183375Skmacy/*
511183375Skmacy * PM timer
512183375Skmacy */
513183375Skmacy
514183375Skmacystruct hvm_hw_pmtimer {
515183375Skmacy    uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
516183375Skmacy    uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
517183375Skmacy    uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
518183375Skmacy};
519183375Skmacy
520183375SkmacyDECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
521183375Skmacy
522183375Skmacy/*
523183375Skmacy * MTRR MSRs
524183375Skmacy */
525183375Skmacy
526183375Skmacystruct hvm_hw_mtrr {
527183375Skmacy#define MTRR_VCNT 8
528183375Skmacy#define NUM_FIXED_MSR 11
529183375Skmacy    uint64_t msr_pat_cr;
530183375Skmacy    /* mtrr physbase & physmask msr pair*/
531183375Skmacy    uint64_t msr_mtrr_var[MTRR_VCNT*2];
532183375Skmacy    uint64_t msr_mtrr_fixed[NUM_FIXED_MSR];
533183375Skmacy    uint64_t msr_mtrr_cap;
534183375Skmacy    uint64_t msr_mtrr_def_type;
535183375Skmacy};
536183375Skmacy
537183375SkmacyDECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr);
538183375Skmacy
539251767Sgibbs/*
540251767Sgibbs * The save area of XSAVE/XRSTOR.
541251767Sgibbs */
542251767Sgibbs
543251767Sgibbsstruct hvm_hw_cpu_xsave {
544251767Sgibbs    uint64_t xfeature_mask;
545251767Sgibbs    uint64_t xcr0;                 /* Updated by XSETBV */
546251767Sgibbs    uint64_t xcr0_accum;           /* Updated by XSETBV */
547251767Sgibbs    struct {
548251767Sgibbs        struct { char x[512]; } fpu_sse;
549251767Sgibbs
550251767Sgibbs        struct {
551251767Sgibbs            uint64_t xstate_bv;         /* Updated by XRSTOR */
552251767Sgibbs            uint64_t reserved[7];
553251767Sgibbs        } xsave_hdr;                    /* The 64-byte header */
554251767Sgibbs
555251767Sgibbs        struct { char x[0]; } ymm;    /* YMM */
556251767Sgibbs    } save_area;
557251767Sgibbs};
558251767Sgibbs
559251767Sgibbs#define CPU_XSAVE_CODE  16
560251767Sgibbs
561251767Sgibbs/*
562251767Sgibbs * Viridian hypervisor context.
563251767Sgibbs */
564251767Sgibbs
565251767Sgibbsstruct hvm_viridian_domain_context {
566251767Sgibbs    uint64_t hypercall_gpa;
567251767Sgibbs    uint64_t guest_os_id;
568251767Sgibbs};
569251767Sgibbs
570251767SgibbsDECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context);
571251767Sgibbs
572251767Sgibbsstruct hvm_viridian_vcpu_context {
573251767Sgibbs    uint64_t apic_assist;
574251767Sgibbs};
575251767Sgibbs
576251767SgibbsDECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context);
577251767Sgibbs
578251767Sgibbsstruct hvm_vmce_vcpu {
579251767Sgibbs    uint64_t caps;
580251767Sgibbs};
581251767Sgibbs
582251767SgibbsDECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
583251767Sgibbs
584183375Skmacy/*
585183375Skmacy * Largest type-code in use
586183375Skmacy */
587251767Sgibbs#define HVM_SAVE_CODE_MAX 18
588183375Skmacy
589183375Skmacy#endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */
590