xref: /freebsd/sys/contrib/xen/arch-x86/hvm/save.h (revision 3a9fd8242b35884921dfc4e886f284a75870a536)
1*3a9fd824SRoger Pau Monné /*
2*3a9fd824SRoger Pau Monné  * Structure definitions for HVM state that is held by Xen and must
3*3a9fd824SRoger Pau Monné  * be saved along with the domain's memory and device-model state.
4*3a9fd824SRoger Pau Monné  *
5*3a9fd824SRoger Pau Monné  * Copyright (c) 2007 XenSource Ltd.
6*3a9fd824SRoger Pau Monné  *
7*3a9fd824SRoger Pau Monné  * Permission is hereby granted, free of charge, to any person obtaining a copy
8*3a9fd824SRoger Pau Monné  * of this software and associated documentation files (the "Software"), to
9*3a9fd824SRoger Pau Monné  * deal in the Software without restriction, including without limitation the
10*3a9fd824SRoger Pau Monné  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11*3a9fd824SRoger Pau Monné  * sell copies of the Software, and to permit persons to whom the Software is
12*3a9fd824SRoger Pau Monné  * furnished to do so, subject to the following conditions:
13*3a9fd824SRoger Pau Monné  *
14*3a9fd824SRoger Pau Monné  * The above copyright notice and this permission notice shall be included in
15*3a9fd824SRoger Pau Monné  * all copies or substantial portions of the Software.
16*3a9fd824SRoger Pau Monné  *
17*3a9fd824SRoger Pau Monné  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*3a9fd824SRoger Pau Monné  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*3a9fd824SRoger Pau Monné  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20*3a9fd824SRoger Pau Monné  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*3a9fd824SRoger Pau Monné  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22*3a9fd824SRoger Pau Monné  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23*3a9fd824SRoger Pau Monné  * DEALINGS IN THE SOFTWARE.
24*3a9fd824SRoger Pau Monné  */
25*3a9fd824SRoger Pau Monné 
26*3a9fd824SRoger Pau Monné #ifndef __XEN_PUBLIC_HVM_SAVE_X86_H__
27*3a9fd824SRoger Pau Monné #define __XEN_PUBLIC_HVM_SAVE_X86_H__
28*3a9fd824SRoger Pau Monné 
29*3a9fd824SRoger Pau Monné #include "../../xen.h"
30*3a9fd824SRoger Pau Monné 
31*3a9fd824SRoger Pau Monné /*
32*3a9fd824SRoger Pau Monné  * Save/restore header: general info about the save file.
33*3a9fd824SRoger Pau Monné  */
34*3a9fd824SRoger Pau Monné 
35*3a9fd824SRoger Pau Monné #define HVM_FILE_MAGIC   0x54381286
36*3a9fd824SRoger Pau Monné #define HVM_FILE_VERSION 0x00000001
37*3a9fd824SRoger Pau Monné 
38*3a9fd824SRoger Pau Monné struct hvm_save_header {
39*3a9fd824SRoger Pau Monné     uint32_t magic;             /* Must be HVM_FILE_MAGIC */
40*3a9fd824SRoger Pau Monné     uint32_t version;           /* File format version */
41*3a9fd824SRoger Pau Monné     uint64_t changeset;         /* Version of Xen that saved this file */
42*3a9fd824SRoger Pau Monné     uint32_t cpuid;             /* CPUID[0x01][%eax] on the saving machine */
43*3a9fd824SRoger Pau Monné     uint32_t gtsc_khz;        /* Guest's TSC frequency in kHz */
44*3a9fd824SRoger Pau Monné };
45*3a9fd824SRoger Pau Monné 
46*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
47*3a9fd824SRoger Pau Monné 
48*3a9fd824SRoger Pau Monné 
49*3a9fd824SRoger Pau Monné /*
50*3a9fd824SRoger Pau Monné  * Processor
51*3a9fd824SRoger Pau Monné  *
52*3a9fd824SRoger Pau Monné  * Compat:
53*3a9fd824SRoger Pau Monné  *     - Pre-3.4 didn't have msr_tsc_aux
54*3a9fd824SRoger Pau Monné  *     - Pre-4.7 didn't have fpu_initialised
55*3a9fd824SRoger Pau Monné  */
56*3a9fd824SRoger Pau Monné 
57*3a9fd824SRoger Pau Monné struct hvm_hw_cpu {
58*3a9fd824SRoger Pau Monné     uint8_t  fpu_regs[512];
59*3a9fd824SRoger Pau Monné 
60*3a9fd824SRoger Pau Monné     uint64_t rax;
61*3a9fd824SRoger Pau Monné     uint64_t rbx;
62*3a9fd824SRoger Pau Monné     uint64_t rcx;
63*3a9fd824SRoger Pau Monné     uint64_t rdx;
64*3a9fd824SRoger Pau Monné     uint64_t rbp;
65*3a9fd824SRoger Pau Monné     uint64_t rsi;
66*3a9fd824SRoger Pau Monné     uint64_t rdi;
67*3a9fd824SRoger Pau Monné     uint64_t rsp;
68*3a9fd824SRoger Pau Monné     uint64_t r8;
69*3a9fd824SRoger Pau Monné     uint64_t r9;
70*3a9fd824SRoger Pau Monné     uint64_t r10;
71*3a9fd824SRoger Pau Monné     uint64_t r11;
72*3a9fd824SRoger Pau Monné     uint64_t r12;
73*3a9fd824SRoger Pau Monné     uint64_t r13;
74*3a9fd824SRoger Pau Monné     uint64_t r14;
75*3a9fd824SRoger Pau Monné     uint64_t r15;
76*3a9fd824SRoger Pau Monné 
77*3a9fd824SRoger Pau Monné     uint64_t rip;
78*3a9fd824SRoger Pau Monné     uint64_t rflags;
79*3a9fd824SRoger Pau Monné 
80*3a9fd824SRoger Pau Monné     uint64_t cr0;
81*3a9fd824SRoger Pau Monné     uint64_t cr2;
82*3a9fd824SRoger Pau Monné     uint64_t cr3;
83*3a9fd824SRoger Pau Monné     uint64_t cr4;
84*3a9fd824SRoger Pau Monné 
85*3a9fd824SRoger Pau Monné     uint64_t dr0;
86*3a9fd824SRoger Pau Monné     uint64_t dr1;
87*3a9fd824SRoger Pau Monné     uint64_t dr2;
88*3a9fd824SRoger Pau Monné     uint64_t dr3;
89*3a9fd824SRoger Pau Monné     uint64_t dr6;
90*3a9fd824SRoger Pau Monné     uint64_t dr7;
91*3a9fd824SRoger Pau Monné 
92*3a9fd824SRoger Pau Monné     uint32_t cs_sel;
93*3a9fd824SRoger Pau Monné     uint32_t ds_sel;
94*3a9fd824SRoger Pau Monné     uint32_t es_sel;
95*3a9fd824SRoger Pau Monné     uint32_t fs_sel;
96*3a9fd824SRoger Pau Monné     uint32_t gs_sel;
97*3a9fd824SRoger Pau Monné     uint32_t ss_sel;
98*3a9fd824SRoger Pau Monné     uint32_t tr_sel;
99*3a9fd824SRoger Pau Monné     uint32_t ldtr_sel;
100*3a9fd824SRoger Pau Monné 
101*3a9fd824SRoger Pau Monné     uint32_t cs_limit;
102*3a9fd824SRoger Pau Monné     uint32_t ds_limit;
103*3a9fd824SRoger Pau Monné     uint32_t es_limit;
104*3a9fd824SRoger Pau Monné     uint32_t fs_limit;
105*3a9fd824SRoger Pau Monné     uint32_t gs_limit;
106*3a9fd824SRoger Pau Monné     uint32_t ss_limit;
107*3a9fd824SRoger Pau Monné     uint32_t tr_limit;
108*3a9fd824SRoger Pau Monné     uint32_t ldtr_limit;
109*3a9fd824SRoger Pau Monné     uint32_t idtr_limit;
110*3a9fd824SRoger Pau Monné     uint32_t gdtr_limit;
111*3a9fd824SRoger Pau Monné 
112*3a9fd824SRoger Pau Monné     uint64_t cs_base;
113*3a9fd824SRoger Pau Monné     uint64_t ds_base;
114*3a9fd824SRoger Pau Monné     uint64_t es_base;
115*3a9fd824SRoger Pau Monné     uint64_t fs_base;
116*3a9fd824SRoger Pau Monné     uint64_t gs_base;
117*3a9fd824SRoger Pau Monné     uint64_t ss_base;
118*3a9fd824SRoger Pau Monné     uint64_t tr_base;
119*3a9fd824SRoger Pau Monné     uint64_t ldtr_base;
120*3a9fd824SRoger Pau Monné     uint64_t idtr_base;
121*3a9fd824SRoger Pau Monné     uint64_t gdtr_base;
122*3a9fd824SRoger Pau Monné 
123*3a9fd824SRoger Pau Monné     uint32_t cs_arbytes;
124*3a9fd824SRoger Pau Monné     uint32_t ds_arbytes;
125*3a9fd824SRoger Pau Monné     uint32_t es_arbytes;
126*3a9fd824SRoger Pau Monné     uint32_t fs_arbytes;
127*3a9fd824SRoger Pau Monné     uint32_t gs_arbytes;
128*3a9fd824SRoger Pau Monné     uint32_t ss_arbytes;
129*3a9fd824SRoger Pau Monné     uint32_t tr_arbytes;
130*3a9fd824SRoger Pau Monné     uint32_t ldtr_arbytes;
131*3a9fd824SRoger Pau Monné 
132*3a9fd824SRoger Pau Monné     uint64_t sysenter_cs;
133*3a9fd824SRoger Pau Monné     uint64_t sysenter_esp;
134*3a9fd824SRoger Pau Monné     uint64_t sysenter_eip;
135*3a9fd824SRoger Pau Monné 
136*3a9fd824SRoger Pau Monné     /* msr for em64t */
137*3a9fd824SRoger Pau Monné     uint64_t shadow_gs;
138*3a9fd824SRoger Pau Monné 
139*3a9fd824SRoger Pau Monné     /* msr content saved/restored. */
140*3a9fd824SRoger Pau Monné     uint64_t msr_flags; /* Obsolete, ignored. */
141*3a9fd824SRoger Pau Monné     uint64_t msr_lstar;
142*3a9fd824SRoger Pau Monné     uint64_t msr_star;
143*3a9fd824SRoger Pau Monné     uint64_t msr_cstar;
144*3a9fd824SRoger Pau Monné     uint64_t msr_syscall_mask;
145*3a9fd824SRoger Pau Monné     uint64_t msr_efer;
146*3a9fd824SRoger Pau Monné     uint64_t msr_tsc_aux;
147*3a9fd824SRoger Pau Monné 
148*3a9fd824SRoger Pau Monné     /* guest's idea of what rdtsc() would return */
149*3a9fd824SRoger Pau Monné     uint64_t tsc;
150*3a9fd824SRoger Pau Monné 
151*3a9fd824SRoger Pau Monné     /* pending event, if any */
152*3a9fd824SRoger Pau Monné     union {
153*3a9fd824SRoger Pau Monné         uint32_t pending_event;
154*3a9fd824SRoger Pau Monné         struct {
155*3a9fd824SRoger Pau Monné             uint8_t  pending_vector:8;
156*3a9fd824SRoger Pau Monné             uint8_t  pending_type:3;
157*3a9fd824SRoger Pau Monné             uint8_t  pending_error_valid:1;
158*3a9fd824SRoger Pau Monné             uint32_t pending_reserved:19;
159*3a9fd824SRoger Pau Monné             uint8_t  pending_valid:1;
160*3a9fd824SRoger Pau Monné         };
161*3a9fd824SRoger Pau Monné     };
162*3a9fd824SRoger Pau Monné     /* error code for pending event */
163*3a9fd824SRoger Pau Monné     uint32_t error_code;
164*3a9fd824SRoger Pau Monné 
165*3a9fd824SRoger Pau Monné #define _XEN_X86_FPU_INITIALISED        0
166*3a9fd824SRoger Pau Monné #define XEN_X86_FPU_INITIALISED         (1U<<_XEN_X86_FPU_INITIALISED)
167*3a9fd824SRoger Pau Monné     uint32_t flags;
168*3a9fd824SRoger Pau Monné     uint32_t pad0;
169*3a9fd824SRoger Pau Monné };
170*3a9fd824SRoger Pau Monné 
171*3a9fd824SRoger Pau Monné struct hvm_hw_cpu_compat {
172*3a9fd824SRoger Pau Monné     uint8_t  fpu_regs[512];
173*3a9fd824SRoger Pau Monné 
174*3a9fd824SRoger Pau Monné     uint64_t rax;
175*3a9fd824SRoger Pau Monné     uint64_t rbx;
176*3a9fd824SRoger Pau Monné     uint64_t rcx;
177*3a9fd824SRoger Pau Monné     uint64_t rdx;
178*3a9fd824SRoger Pau Monné     uint64_t rbp;
179*3a9fd824SRoger Pau Monné     uint64_t rsi;
180*3a9fd824SRoger Pau Monné     uint64_t rdi;
181*3a9fd824SRoger Pau Monné     uint64_t rsp;
182*3a9fd824SRoger Pau Monné     uint64_t r8;
183*3a9fd824SRoger Pau Monné     uint64_t r9;
184*3a9fd824SRoger Pau Monné     uint64_t r10;
185*3a9fd824SRoger Pau Monné     uint64_t r11;
186*3a9fd824SRoger Pau Monné     uint64_t r12;
187*3a9fd824SRoger Pau Monné     uint64_t r13;
188*3a9fd824SRoger Pau Monné     uint64_t r14;
189*3a9fd824SRoger Pau Monné     uint64_t r15;
190*3a9fd824SRoger Pau Monné 
191*3a9fd824SRoger Pau Monné     uint64_t rip;
192*3a9fd824SRoger Pau Monné     uint64_t rflags;
193*3a9fd824SRoger Pau Monné 
194*3a9fd824SRoger Pau Monné     uint64_t cr0;
195*3a9fd824SRoger Pau Monné     uint64_t cr2;
196*3a9fd824SRoger Pau Monné     uint64_t cr3;
197*3a9fd824SRoger Pau Monné     uint64_t cr4;
198*3a9fd824SRoger Pau Monné 
199*3a9fd824SRoger Pau Monné     uint64_t dr0;
200*3a9fd824SRoger Pau Monné     uint64_t dr1;
201*3a9fd824SRoger Pau Monné     uint64_t dr2;
202*3a9fd824SRoger Pau Monné     uint64_t dr3;
203*3a9fd824SRoger Pau Monné     uint64_t dr6;
204*3a9fd824SRoger Pau Monné     uint64_t dr7;
205*3a9fd824SRoger Pau Monné 
206*3a9fd824SRoger Pau Monné     uint32_t cs_sel;
207*3a9fd824SRoger Pau Monné     uint32_t ds_sel;
208*3a9fd824SRoger Pau Monné     uint32_t es_sel;
209*3a9fd824SRoger Pau Monné     uint32_t fs_sel;
210*3a9fd824SRoger Pau Monné     uint32_t gs_sel;
211*3a9fd824SRoger Pau Monné     uint32_t ss_sel;
212*3a9fd824SRoger Pau Monné     uint32_t tr_sel;
213*3a9fd824SRoger Pau Monné     uint32_t ldtr_sel;
214*3a9fd824SRoger Pau Monné 
215*3a9fd824SRoger Pau Monné     uint32_t cs_limit;
216*3a9fd824SRoger Pau Monné     uint32_t ds_limit;
217*3a9fd824SRoger Pau Monné     uint32_t es_limit;
218*3a9fd824SRoger Pau Monné     uint32_t fs_limit;
219*3a9fd824SRoger Pau Monné     uint32_t gs_limit;
220*3a9fd824SRoger Pau Monné     uint32_t ss_limit;
221*3a9fd824SRoger Pau Monné     uint32_t tr_limit;
222*3a9fd824SRoger Pau Monné     uint32_t ldtr_limit;
223*3a9fd824SRoger Pau Monné     uint32_t idtr_limit;
224*3a9fd824SRoger Pau Monné     uint32_t gdtr_limit;
225*3a9fd824SRoger Pau Monné 
226*3a9fd824SRoger Pau Monné     uint64_t cs_base;
227*3a9fd824SRoger Pau Monné     uint64_t ds_base;
228*3a9fd824SRoger Pau Monné     uint64_t es_base;
229*3a9fd824SRoger Pau Monné     uint64_t fs_base;
230*3a9fd824SRoger Pau Monné     uint64_t gs_base;
231*3a9fd824SRoger Pau Monné     uint64_t ss_base;
232*3a9fd824SRoger Pau Monné     uint64_t tr_base;
233*3a9fd824SRoger Pau Monné     uint64_t ldtr_base;
234*3a9fd824SRoger Pau Monné     uint64_t idtr_base;
235*3a9fd824SRoger Pau Monné     uint64_t gdtr_base;
236*3a9fd824SRoger Pau Monné 
237*3a9fd824SRoger Pau Monné     uint32_t cs_arbytes;
238*3a9fd824SRoger Pau Monné     uint32_t ds_arbytes;
239*3a9fd824SRoger Pau Monné     uint32_t es_arbytes;
240*3a9fd824SRoger Pau Monné     uint32_t fs_arbytes;
241*3a9fd824SRoger Pau Monné     uint32_t gs_arbytes;
242*3a9fd824SRoger Pau Monné     uint32_t ss_arbytes;
243*3a9fd824SRoger Pau Monné     uint32_t tr_arbytes;
244*3a9fd824SRoger Pau Monné     uint32_t ldtr_arbytes;
245*3a9fd824SRoger Pau Monné 
246*3a9fd824SRoger Pau Monné     uint64_t sysenter_cs;
247*3a9fd824SRoger Pau Monné     uint64_t sysenter_esp;
248*3a9fd824SRoger Pau Monné     uint64_t sysenter_eip;
249*3a9fd824SRoger Pau Monné 
250*3a9fd824SRoger Pau Monné     /* msr for em64t */
251*3a9fd824SRoger Pau Monné     uint64_t shadow_gs;
252*3a9fd824SRoger Pau Monné 
253*3a9fd824SRoger Pau Monné     /* msr content saved/restored. */
254*3a9fd824SRoger Pau Monné     uint64_t msr_flags; /* Obsolete, ignored. */
255*3a9fd824SRoger Pau Monné     uint64_t msr_lstar;
256*3a9fd824SRoger Pau Monné     uint64_t msr_star;
257*3a9fd824SRoger Pau Monné     uint64_t msr_cstar;
258*3a9fd824SRoger Pau Monné     uint64_t msr_syscall_mask;
259*3a9fd824SRoger Pau Monné     uint64_t msr_efer;
260*3a9fd824SRoger Pau Monné     /*uint64_t msr_tsc_aux; COMPAT */
261*3a9fd824SRoger Pau Monné 
262*3a9fd824SRoger Pau Monné     /* guest's idea of what rdtsc() would return */
263*3a9fd824SRoger Pau Monné     uint64_t tsc;
264*3a9fd824SRoger Pau Monné 
265*3a9fd824SRoger Pau Monné     /* pending event, if any */
266*3a9fd824SRoger Pau Monné     union {
267*3a9fd824SRoger Pau Monné         uint32_t pending_event;
268*3a9fd824SRoger Pau Monné         struct {
269*3a9fd824SRoger Pau Monné             uint8_t  pending_vector:8;
270*3a9fd824SRoger Pau Monné             uint8_t  pending_type:3;
271*3a9fd824SRoger Pau Monné             uint8_t  pending_error_valid:1;
272*3a9fd824SRoger Pau Monné             uint32_t pending_reserved:19;
273*3a9fd824SRoger Pau Monné             uint8_t  pending_valid:1;
274*3a9fd824SRoger Pau Monné         };
275*3a9fd824SRoger Pau Monné     };
276*3a9fd824SRoger Pau Monné     /* error code for pending event */
277*3a9fd824SRoger Pau Monné     uint32_t error_code;
278*3a9fd824SRoger Pau Monné };
279*3a9fd824SRoger Pau Monné 
_hvm_hw_fix_cpu(void * h,uint32_t size)280*3a9fd824SRoger Pau Monné static inline int _hvm_hw_fix_cpu(void *h, uint32_t size) {
281*3a9fd824SRoger Pau Monné 
282*3a9fd824SRoger Pau Monné     union hvm_hw_cpu_union {
283*3a9fd824SRoger Pau Monné         struct hvm_hw_cpu nat;
284*3a9fd824SRoger Pau Monné         struct hvm_hw_cpu_compat cmp;
285*3a9fd824SRoger Pau Monné     } *ucpu = (union hvm_hw_cpu_union *)h;
286*3a9fd824SRoger Pau Monné 
287*3a9fd824SRoger Pau Monné     if ( size == sizeof(struct hvm_hw_cpu_compat) )
288*3a9fd824SRoger Pau Monné     {
289*3a9fd824SRoger Pau Monné         /*
290*3a9fd824SRoger Pau Monné          * If we copy from the end backwards, we should
291*3a9fd824SRoger Pau Monné          * be able to do the modification in-place.
292*3a9fd824SRoger Pau Monné          */
293*3a9fd824SRoger Pau Monné         ucpu->nat.error_code = ucpu->cmp.error_code;
294*3a9fd824SRoger Pau Monné         ucpu->nat.pending_event = ucpu->cmp.pending_event;
295*3a9fd824SRoger Pau Monné         ucpu->nat.tsc = ucpu->cmp.tsc;
296*3a9fd824SRoger Pau Monné         ucpu->nat.msr_tsc_aux = 0;
297*3a9fd824SRoger Pau Monné     }
298*3a9fd824SRoger Pau Monné     /* Mimic the old behaviour by unconditionally setting fpu_initialised. */
299*3a9fd824SRoger Pau Monné     ucpu->nat.flags = XEN_X86_FPU_INITIALISED;
300*3a9fd824SRoger Pau Monné 
301*3a9fd824SRoger Pau Monné     return 0;
302*3a9fd824SRoger Pau Monné }
303*3a9fd824SRoger Pau Monné 
304*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE_COMPAT(CPU, 2, struct hvm_hw_cpu, \
305*3a9fd824SRoger Pau Monné                              struct hvm_hw_cpu_compat, _hvm_hw_fix_cpu);
306*3a9fd824SRoger Pau Monné 
307*3a9fd824SRoger Pau Monné /*
308*3a9fd824SRoger Pau Monné  * PIC
309*3a9fd824SRoger Pau Monné  */
310*3a9fd824SRoger Pau Monné 
311*3a9fd824SRoger Pau Monné struct hvm_hw_vpic {
312*3a9fd824SRoger Pau Monné     /* IR line bitmasks. */
313*3a9fd824SRoger Pau Monné     uint8_t irr;
314*3a9fd824SRoger Pau Monné     uint8_t imr;
315*3a9fd824SRoger Pau Monné     uint8_t isr;
316*3a9fd824SRoger Pau Monné 
317*3a9fd824SRoger Pau Monné     /* Line IRx maps to IRQ irq_base+x */
318*3a9fd824SRoger Pau Monné     uint8_t irq_base;
319*3a9fd824SRoger Pau Monné 
320*3a9fd824SRoger Pau Monné     /*
321*3a9fd824SRoger Pau Monné      * Where are we in ICW2-4 initialisation (0 means no init in progress)?
322*3a9fd824SRoger Pau Monné      * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
323*3a9fd824SRoger Pau Monné      * Bit 2: ICW1.IC4  (1 == ICW4 included in init sequence)
324*3a9fd824SRoger Pau Monné      * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
325*3a9fd824SRoger Pau Monné      */
326*3a9fd824SRoger Pau Monné     uint8_t init_state:4;
327*3a9fd824SRoger Pau Monné 
328*3a9fd824SRoger Pau Monné     /* IR line with highest priority. */
329*3a9fd824SRoger Pau Monné     uint8_t priority_add:4;
330*3a9fd824SRoger Pau Monné 
331*3a9fd824SRoger Pau Monné     /* Reads from A=0 obtain ISR or IRR? */
332*3a9fd824SRoger Pau Monné     uint8_t readsel_isr:1;
333*3a9fd824SRoger Pau Monné 
334*3a9fd824SRoger Pau Monné     /* Reads perform a polling read? */
335*3a9fd824SRoger Pau Monné     uint8_t poll:1;
336*3a9fd824SRoger Pau Monné 
337*3a9fd824SRoger Pau Monné     /* Automatically clear IRQs from the ISR during INTA? */
338*3a9fd824SRoger Pau Monné     uint8_t auto_eoi:1;
339*3a9fd824SRoger Pau Monné 
340*3a9fd824SRoger Pau Monné     /* Automatically rotate IRQ priorities during AEOI? */
341*3a9fd824SRoger Pau Monné     uint8_t rotate_on_auto_eoi:1;
342*3a9fd824SRoger Pau Monné 
343*3a9fd824SRoger Pau Monné     /* Exclude slave inputs when considering in-service IRQs? */
344*3a9fd824SRoger Pau Monné     uint8_t special_fully_nested_mode:1;
345*3a9fd824SRoger Pau Monné 
346*3a9fd824SRoger Pau Monné     /* Special mask mode excludes masked IRs from AEOI and priority checks. */
347*3a9fd824SRoger Pau Monné     uint8_t special_mask_mode:1;
348*3a9fd824SRoger Pau Monné 
349*3a9fd824SRoger Pau Monné     /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
350*3a9fd824SRoger Pau Monné     uint8_t is_master:1;
351*3a9fd824SRoger Pau Monné 
352*3a9fd824SRoger Pau Monné     /* Edge/trigger selection. */
353*3a9fd824SRoger Pau Monné     uint8_t elcr;
354*3a9fd824SRoger Pau Monné 
355*3a9fd824SRoger Pau Monné     /* Virtual INT output. */
356*3a9fd824SRoger Pau Monné     uint8_t int_output;
357*3a9fd824SRoger Pau Monné };
358*3a9fd824SRoger Pau Monné 
359*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
360*3a9fd824SRoger Pau Monné 
361*3a9fd824SRoger Pau Monné 
362*3a9fd824SRoger Pau Monné /*
363*3a9fd824SRoger Pau Monné  * IO-APIC
364*3a9fd824SRoger Pau Monné  */
365*3a9fd824SRoger Pau Monné 
366*3a9fd824SRoger Pau Monné union vioapic_redir_entry
367*3a9fd824SRoger Pau Monné {
368*3a9fd824SRoger Pau Monné     uint64_t bits;
369*3a9fd824SRoger Pau Monné     struct {
370*3a9fd824SRoger Pau Monné         uint8_t vector;
371*3a9fd824SRoger Pau Monné         uint8_t delivery_mode:3;
372*3a9fd824SRoger Pau Monné         uint8_t dest_mode:1;
373*3a9fd824SRoger Pau Monné         uint8_t delivery_status:1;
374*3a9fd824SRoger Pau Monné         uint8_t polarity:1;
375*3a9fd824SRoger Pau Monné         uint8_t remote_irr:1;
376*3a9fd824SRoger Pau Monné         uint8_t trig_mode:1;
377*3a9fd824SRoger Pau Monné         uint8_t mask:1;
378*3a9fd824SRoger Pau Monné         uint8_t reserve:7;
379*3a9fd824SRoger Pau Monné         uint8_t reserved[4];
380*3a9fd824SRoger Pau Monné         uint8_t dest_id;
381*3a9fd824SRoger Pau Monné     } fields;
382*3a9fd824SRoger Pau Monné };
383*3a9fd824SRoger Pau Monné 
384*3a9fd824SRoger Pau Monné #define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
385*3a9fd824SRoger Pau Monné 
386*3a9fd824SRoger Pau Monné #define XEN_HVM_VIOAPIC(name, cnt)                      \
387*3a9fd824SRoger Pau Monné     struct name {                                       \
388*3a9fd824SRoger Pau Monné         uint64_t base_address;                          \
389*3a9fd824SRoger Pau Monné         uint32_t ioregsel;                              \
390*3a9fd824SRoger Pau Monné         uint32_t id;                                    \
391*3a9fd824SRoger Pau Monné         union vioapic_redir_entry redirtbl[cnt];        \
392*3a9fd824SRoger Pau Monné     }
393*3a9fd824SRoger Pau Monné 
394*3a9fd824SRoger Pau Monné XEN_HVM_VIOAPIC(hvm_hw_vioapic, VIOAPIC_NUM_PINS);
395*3a9fd824SRoger Pau Monné 
396*3a9fd824SRoger Pau Monné #ifndef __XEN__
397*3a9fd824SRoger Pau Monné #undef XEN_HVM_VIOAPIC
398*3a9fd824SRoger Pau Monné #else
399*3a9fd824SRoger Pau Monné #undef VIOAPIC_NUM_PINS
400*3a9fd824SRoger Pau Monné #endif
401*3a9fd824SRoger Pau Monné 
402*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
403*3a9fd824SRoger Pau Monné 
404*3a9fd824SRoger Pau Monné 
405*3a9fd824SRoger Pau Monné /*
406*3a9fd824SRoger Pau Monné  * LAPIC
407*3a9fd824SRoger Pau Monné  */
408*3a9fd824SRoger Pau Monné 
409*3a9fd824SRoger Pau Monné struct hvm_hw_lapic {
410*3a9fd824SRoger Pau Monné     uint64_t             apic_base_msr;
411*3a9fd824SRoger Pau Monné     uint32_t             disabled; /* VLAPIC_xx_DISABLED */
412*3a9fd824SRoger Pau Monné     uint32_t             timer_divisor;
413*3a9fd824SRoger Pau Monné     uint64_t             tdt_msr;
414*3a9fd824SRoger Pau Monné };
415*3a9fd824SRoger Pau Monné 
416*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
417*3a9fd824SRoger Pau Monné 
418*3a9fd824SRoger Pau Monné struct hvm_hw_lapic_regs {
419*3a9fd824SRoger Pau Monné     uint8_t data[1024];
420*3a9fd824SRoger Pau Monné };
421*3a9fd824SRoger Pau Monné 
422*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
423*3a9fd824SRoger Pau Monné 
424*3a9fd824SRoger Pau Monné 
425*3a9fd824SRoger Pau Monné /*
426*3a9fd824SRoger Pau Monné  * IRQs
427*3a9fd824SRoger Pau Monné  */
428*3a9fd824SRoger Pau Monné 
429*3a9fd824SRoger Pau Monné struct hvm_hw_pci_irqs {
430*3a9fd824SRoger Pau Monné     /*
431*3a9fd824SRoger Pau Monné      * Virtual interrupt wires for a single PCI bus.
432*3a9fd824SRoger Pau Monné      * Indexed by: device*4 + INTx#.
433*3a9fd824SRoger Pau Monné      */
434*3a9fd824SRoger Pau Monné     union {
435*3a9fd824SRoger Pau Monné         unsigned long i[16 / sizeof (unsigned long)]; /* DECLARE_BITMAP(i, 32*4); */
436*3a9fd824SRoger Pau Monné         uint64_t pad[2];
437*3a9fd824SRoger Pau Monné     };
438*3a9fd824SRoger Pau Monné };
439*3a9fd824SRoger Pau Monné 
440*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs);
441*3a9fd824SRoger Pau Monné 
442*3a9fd824SRoger Pau Monné struct hvm_hw_isa_irqs {
443*3a9fd824SRoger Pau Monné     /*
444*3a9fd824SRoger Pau Monné      * Virtual interrupt wires for ISA devices.
445*3a9fd824SRoger Pau Monné      * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
446*3a9fd824SRoger Pau Monné      */
447*3a9fd824SRoger Pau Monné     union {
448*3a9fd824SRoger Pau Monné         unsigned long i[1];  /* DECLARE_BITMAP(i, 16); */
449*3a9fd824SRoger Pau Monné         uint64_t pad[1];
450*3a9fd824SRoger Pau Monné     };
451*3a9fd824SRoger Pau Monné };
452*3a9fd824SRoger Pau Monné 
453*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs);
454*3a9fd824SRoger Pau Monné 
455*3a9fd824SRoger Pau Monné struct hvm_hw_pci_link {
456*3a9fd824SRoger Pau Monné     /*
457*3a9fd824SRoger Pau Monné      * PCI-ISA interrupt router.
458*3a9fd824SRoger Pau Monné      * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
459*3a9fd824SRoger Pau Monné      * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
460*3a9fd824SRoger Pau Monné      * The router provides a programmable mapping from each link to a GSI.
461*3a9fd824SRoger Pau Monné      */
462*3a9fd824SRoger Pau Monné     uint8_t route[4];
463*3a9fd824SRoger Pau Monné     uint8_t pad0[4];
464*3a9fd824SRoger Pau Monné };
465*3a9fd824SRoger Pau Monné 
466*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);
467*3a9fd824SRoger Pau Monné 
468*3a9fd824SRoger Pau Monné /*
469*3a9fd824SRoger Pau Monné  *  PIT
470*3a9fd824SRoger Pau Monné  */
471*3a9fd824SRoger Pau Monné 
472*3a9fd824SRoger Pau Monné struct hvm_hw_pit {
473*3a9fd824SRoger Pau Monné     struct hvm_hw_pit_channel {
474*3a9fd824SRoger Pau Monné         uint32_t count; /* can be 65536 */
475*3a9fd824SRoger Pau Monné         uint16_t latched_count;
476*3a9fd824SRoger Pau Monné         uint8_t count_latched;
477*3a9fd824SRoger Pau Monné         uint8_t status_latched;
478*3a9fd824SRoger Pau Monné         uint8_t status;
479*3a9fd824SRoger Pau Monné         uint8_t read_state;
480*3a9fd824SRoger Pau Monné         uint8_t write_state;
481*3a9fd824SRoger Pau Monné         uint8_t write_latch;
482*3a9fd824SRoger Pau Monné         uint8_t rw_mode;
483*3a9fd824SRoger Pau Monné         uint8_t mode;
484*3a9fd824SRoger Pau Monné         uint8_t bcd; /* not supported */
485*3a9fd824SRoger Pau Monné         uint8_t gate; /* timer start */
486*3a9fd824SRoger Pau Monné     } channels[3];  /* 3 x 16 bytes */
487*3a9fd824SRoger Pau Monné     uint32_t speaker_data_on;
488*3a9fd824SRoger Pau Monné     uint32_t pad0;
489*3a9fd824SRoger Pau Monné };
490*3a9fd824SRoger Pau Monné 
491*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);
492*3a9fd824SRoger Pau Monné 
493*3a9fd824SRoger Pau Monné 
494*3a9fd824SRoger Pau Monné /*
495*3a9fd824SRoger Pau Monné  * RTC
496*3a9fd824SRoger Pau Monné  */
497*3a9fd824SRoger Pau Monné 
498*3a9fd824SRoger Pau Monné #define RTC_CMOS_SIZE 14
499*3a9fd824SRoger Pau Monné struct hvm_hw_rtc {
500*3a9fd824SRoger Pau Monné     /* CMOS bytes */
501*3a9fd824SRoger Pau Monné     uint8_t cmos_data[RTC_CMOS_SIZE];
502*3a9fd824SRoger Pau Monné     /* Index register for 2-part operations */
503*3a9fd824SRoger Pau Monné     uint8_t cmos_index;
504*3a9fd824SRoger Pau Monné     uint8_t pad0;
505*3a9fd824SRoger Pau Monné     /* RTC offset from host time */
506*3a9fd824SRoger Pau Monné     int64_t rtc_offset;
507*3a9fd824SRoger Pau Monné };
508*3a9fd824SRoger Pau Monné 
509*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);
510*3a9fd824SRoger Pau Monné 
511*3a9fd824SRoger Pau Monné 
512*3a9fd824SRoger Pau Monné /*
513*3a9fd824SRoger Pau Monné  * HPET
514*3a9fd824SRoger Pau Monné  */
515*3a9fd824SRoger Pau Monné 
516*3a9fd824SRoger Pau Monné #define HPET_TIMER_NUM     3    /* 3 timers supported now */
517*3a9fd824SRoger Pau Monné struct hvm_hw_hpet {
518*3a9fd824SRoger Pau Monné     /* Memory-mapped, software visible registers */
519*3a9fd824SRoger Pau Monné     uint64_t capability;        /* capabilities */
520*3a9fd824SRoger Pau Monné     uint64_t res0;              /* reserved */
521*3a9fd824SRoger Pau Monné     uint64_t config;            /* configuration */
522*3a9fd824SRoger Pau Monné     uint64_t res1;              /* reserved */
523*3a9fd824SRoger Pau Monné     uint64_t isr;               /* interrupt status reg */
524*3a9fd824SRoger Pau Monné     uint64_t res2[25];          /* reserved */
525*3a9fd824SRoger Pau Monné     uint64_t mc64;              /* main counter */
526*3a9fd824SRoger Pau Monné     uint64_t res3;              /* reserved */
527*3a9fd824SRoger Pau Monné     struct {                    /* timers */
528*3a9fd824SRoger Pau Monné         uint64_t config;        /* configuration/cap */
529*3a9fd824SRoger Pau Monné         uint64_t cmp;           /* comparator */
530*3a9fd824SRoger Pau Monné         uint64_t fsb;           /* FSB route, not supported now */
531*3a9fd824SRoger Pau Monné         uint64_t res4;          /* reserved */
532*3a9fd824SRoger Pau Monné     } timers[HPET_TIMER_NUM];
533*3a9fd824SRoger Pau Monné     uint64_t res5[4*(24-HPET_TIMER_NUM)];  /* reserved, up to 0x3ff */
534*3a9fd824SRoger Pau Monné 
535*3a9fd824SRoger Pau Monné     /* Hidden register state */
536*3a9fd824SRoger Pau Monné     uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
537*3a9fd824SRoger Pau Monné };
538*3a9fd824SRoger Pau Monné 
539*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
540*3a9fd824SRoger Pau Monné 
541*3a9fd824SRoger Pau Monné 
542*3a9fd824SRoger Pau Monné /*
543*3a9fd824SRoger Pau Monné  * PM timer
544*3a9fd824SRoger Pau Monné  */
545*3a9fd824SRoger Pau Monné 
546*3a9fd824SRoger Pau Monné struct hvm_hw_pmtimer {
547*3a9fd824SRoger Pau Monné     uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
548*3a9fd824SRoger Pau Monné     uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
549*3a9fd824SRoger Pau Monné     uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
550*3a9fd824SRoger Pau Monné };
551*3a9fd824SRoger Pau Monné 
552*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
553*3a9fd824SRoger Pau Monné 
554*3a9fd824SRoger Pau Monné /*
555*3a9fd824SRoger Pau Monné  * MTRR MSRs
556*3a9fd824SRoger Pau Monné  */
557*3a9fd824SRoger Pau Monné 
558*3a9fd824SRoger Pau Monné struct hvm_hw_mtrr {
559*3a9fd824SRoger Pau Monné #define MTRR_VCNT 8
560*3a9fd824SRoger Pau Monné #define NUM_FIXED_MSR 11
561*3a9fd824SRoger Pau Monné     uint64_t msr_pat_cr;
562*3a9fd824SRoger Pau Monné     /* mtrr physbase & physmask msr pair*/
563*3a9fd824SRoger Pau Monné     uint64_t msr_mtrr_var[MTRR_VCNT*2];
564*3a9fd824SRoger Pau Monné     uint64_t msr_mtrr_fixed[NUM_FIXED_MSR];
565*3a9fd824SRoger Pau Monné     uint64_t msr_mtrr_cap;
566*3a9fd824SRoger Pau Monné     uint64_t msr_mtrr_def_type;
567*3a9fd824SRoger Pau Monné };
568*3a9fd824SRoger Pau Monné 
569*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr);
570*3a9fd824SRoger Pau Monné 
571*3a9fd824SRoger Pau Monné /*
572*3a9fd824SRoger Pau Monné  * The save area of XSAVE/XRSTOR.
573*3a9fd824SRoger Pau Monné  */
574*3a9fd824SRoger Pau Monné 
575*3a9fd824SRoger Pau Monné struct hvm_hw_cpu_xsave {
576*3a9fd824SRoger Pau Monné     uint64_t xfeature_mask;        /* Ignored */
577*3a9fd824SRoger Pau Monné     uint64_t xcr0;                 /* Updated by XSETBV */
578*3a9fd824SRoger Pau Monné     uint64_t xcr0_accum;           /* Updated by XSETBV */
579*3a9fd824SRoger Pau Monné     struct {
580*3a9fd824SRoger Pau Monné         struct { char x[512]; } fpu_sse;
581*3a9fd824SRoger Pau Monné 
582*3a9fd824SRoger Pau Monné         struct hvm_hw_cpu_xsave_hdr {
583*3a9fd824SRoger Pau Monné             uint64_t xstate_bv;         /* Updated by XRSTOR */
584*3a9fd824SRoger Pau Monné             uint64_t xcomp_bv;          /* Updated by XRSTOR{C,S} */
585*3a9fd824SRoger Pau Monné             uint64_t reserved[6];
586*3a9fd824SRoger Pau Monné         } xsave_hdr;                    /* The 64-byte header */
587*3a9fd824SRoger Pau Monné     } save_area;
588*3a9fd824SRoger Pau Monné };
589*3a9fd824SRoger Pau Monné 
590*3a9fd824SRoger Pau Monné #define CPU_XSAVE_CODE  16
591*3a9fd824SRoger Pau Monné 
592*3a9fd824SRoger Pau Monné /*
593*3a9fd824SRoger Pau Monné  * Viridian hypervisor context.
594*3a9fd824SRoger Pau Monné  */
595*3a9fd824SRoger Pau Monné 
596*3a9fd824SRoger Pau Monné struct hvm_viridian_domain_context {
597*3a9fd824SRoger Pau Monné     uint64_t hypercall_gpa;
598*3a9fd824SRoger Pau Monné     uint64_t guest_os_id;
599*3a9fd824SRoger Pau Monné     uint64_t time_ref_count;
600*3a9fd824SRoger Pau Monné     uint64_t reference_tsc;
601*3a9fd824SRoger Pau Monné };
602*3a9fd824SRoger Pau Monné 
603*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context);
604*3a9fd824SRoger Pau Monné 
605*3a9fd824SRoger Pau Monné struct hvm_viridian_vcpu_context {
606*3a9fd824SRoger Pau Monné     uint64_t vp_assist_msr;
607*3a9fd824SRoger Pau Monné     uint8_t  apic_assist_pending;
608*3a9fd824SRoger Pau Monné     uint8_t  _pad[7];
609*3a9fd824SRoger Pau Monné     uint64_t simp_msr;
610*3a9fd824SRoger Pau Monné     uint64_t sint_msr[16];
611*3a9fd824SRoger Pau Monné     uint64_t stimer_config_msr[4];
612*3a9fd824SRoger Pau Monné     uint64_t stimer_count_msr[4];
613*3a9fd824SRoger Pau Monné };
614*3a9fd824SRoger Pau Monné 
615*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context);
616*3a9fd824SRoger Pau Monné 
617*3a9fd824SRoger Pau Monné struct hvm_vmce_vcpu {
618*3a9fd824SRoger Pau Monné     uint64_t caps;
619*3a9fd824SRoger Pau Monné     uint64_t mci_ctl2_bank0;
620*3a9fd824SRoger Pau Monné     uint64_t mci_ctl2_bank1;
621*3a9fd824SRoger Pau Monné     uint64_t mcg_ext_ctl;
622*3a9fd824SRoger Pau Monné };
623*3a9fd824SRoger Pau Monné 
624*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
625*3a9fd824SRoger Pau Monné 
626*3a9fd824SRoger Pau Monné struct hvm_tsc_adjust {
627*3a9fd824SRoger Pau Monné     uint64_t tsc_adjust;
628*3a9fd824SRoger Pau Monné };
629*3a9fd824SRoger Pau Monné 
630*3a9fd824SRoger Pau Monné DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);
631*3a9fd824SRoger Pau Monné 
632*3a9fd824SRoger Pau Monné 
633*3a9fd824SRoger Pau Monné struct hvm_msr {
634*3a9fd824SRoger Pau Monné     uint32_t count;
635*3a9fd824SRoger Pau Monné     struct hvm_one_msr {
636*3a9fd824SRoger Pau Monné         uint32_t index;
637*3a9fd824SRoger Pau Monné         uint32_t _rsvd;
638*3a9fd824SRoger Pau Monné         uint64_t val;
639*3a9fd824SRoger Pau Monné     } msr[XEN_FLEX_ARRAY_DIM];
640*3a9fd824SRoger Pau Monné };
641*3a9fd824SRoger Pau Monné 
642*3a9fd824SRoger Pau Monné #define CPU_MSR_CODE  20
643*3a9fd824SRoger Pau Monné 
644*3a9fd824SRoger Pau Monné /* Range 22 - 34 (inclusive) reserved for Amazon */
645*3a9fd824SRoger Pau Monné 
646*3a9fd824SRoger Pau Monné /*
647*3a9fd824SRoger Pau Monné  * Largest type-code in use
648*3a9fd824SRoger Pau Monné  */
649*3a9fd824SRoger Pau Monné #define HVM_SAVE_CODE_MAX 20
650*3a9fd824SRoger Pau Monné 
651*3a9fd824SRoger Pau Monné #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */
652*3a9fd824SRoger Pau Monné 
653*3a9fd824SRoger Pau Monné /*
654*3a9fd824SRoger Pau Monné  * Local variables:
655*3a9fd824SRoger Pau Monné  * mode: C
656*3a9fd824SRoger Pau Monné  * c-file-style: "BSD"
657*3a9fd824SRoger Pau Monné  * c-basic-offset: 4
658*3a9fd824SRoger Pau Monné  * tab-width: 4
659*3a9fd824SRoger Pau Monné  * indent-tabs-mode: nil
660*3a9fd824SRoger Pau Monné  * End:
661*3a9fd824SRoger Pau Monné  */
662