~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/misc/xen-hvmctx.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * xen-hvmctx.c
 
3
 *
 
4
 * Print out the contents of a HVM save record in a human-readable way.
 
5
 * 
 
6
 * Tim Deegan <Tim.Deegan@citrix.com>
 
7
 * Copyright (c) 2008 Citrix Systems, Inc.
 
8
 *
 
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
 * of this software and associated documentation files (the "Software"), to
 
11
 * deal in the Software without restriction, including without limitation the
 
12
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 
13
 * sell copies of the Software, and to permit persons to whom the Software is
 
14
 * furnished to do so, subject to the following conditions:
 
15
 *
 
16
 * The above copyright notice and this permission notice shall be included in
 
17
 * all copies or substantial portions of the Software.
 
18
 *
 
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
25
 * DEALINGS IN THE SOFTWARE.
 
26
 */
 
27
 
 
28
#include <inttypes.h>
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <stddef.h>
 
32
#include <stdint.h>
 
33
#include <unistd.h>
 
34
#include <string.h>
 
35
#include <errno.h>
 
36
#include <limits.h>
 
37
#include <sys/types.h>
 
38
#include <sys/stat.h>
 
39
#include <arpa/inet.h>
 
40
 
 
41
#define BITS_PER_LONG __WORDSIZE
 
42
#define BITS_TO_LONGS(bits) \
 
43
        (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 
44
#define DECLARE_BITMAP(name,bits) \
 
45
        unsigned long name[BITS_TO_LONGS(bits)]
 
46
 
 
47
#include <xenctrl.h>
 
48
#include <xen/xen.h>
 
49
#include <xen/domctl.h>
 
50
#include <xen/hvm/save.h>
 
51
 
 
52
static uint8_t *buf = NULL;
 
53
static uint32_t len;
 
54
static uint32_t off;
 
55
 
 
56
#define READ(_x) do {                                                      \
 
57
    if ( len - off < sizeof (_x) )                                         \
 
58
    {                                                                      \
 
59
        fprintf(stderr, "Error: need another %u bytes, only %u available", \
 
60
                (unsigned int)sizeof(_x), len - off);                      \
 
61
        exit(1);                                                           \
 
62
    }                                                                      \
 
63
    memcpy(&(_x), buf + off, sizeof (_x));                                 \
 
64
    off += sizeof (_x);                                                    \
 
65
} while (0)
 
66
 
 
67
static void dump_header(void)
 
68
 
69
    HVM_SAVE_TYPE(HEADER) h;
 
70
    READ(h);
 
71
    printf("     Header: magic %#lx, version %lu\n",
 
72
           (unsigned long) h.magic, (unsigned long) h.version);
 
73
    printf("             Xen changeset %llx\n", 
 
74
           (unsigned long long) h.changeset);
 
75
    printf("             CPUID[0][%%eax] 0x%.8lx\n", (unsigned long) h.cpuid);
 
76
    printf("             gtsc_khz %lu\n", (unsigned long) h.gtsc_khz);
 
77
}
 
78
 
 
79
struct fpu_mm {
 
80
    uint64_t lo;
 
81
    uint16_t hi;
 
82
    uint16_t pad[3];
 
83
} __attribute__((packed));
 
84
 
 
85
struct fpu_xmm {
 
86
    uint64_t lo;
 
87
    uint64_t hi;
 
88
};
 
89
 
 
90
struct fpu_regs {
 
91
    uint16_t fcw;
 
92
    uint16_t fsw;
 
93
    uint8_t ftw;
 
94
    uint8_t res0;
 
95
    uint16_t fop;
 
96
    uint64_t fpuip;
 
97
    uint64_t fpudp;
 
98
    uint32_t mxcsr;
 
99
    uint32_t mxcsr_mask;
 
100
    struct fpu_mm mm[8];
 
101
    struct fpu_xmm xmm[15];
 
102
    uint64_t res1[12];
 
103
} __attribute__((packed));
 
104
 
 
105
static void dump_fpu(void *p)
 
106
{
 
107
    struct fpu_regs *r = p;
 
108
    int i;
 
109
 
 
110
    printf("    FPU:    fcw 0x%4.4x fsw 0x%4.4x\n"  
 
111
           "            ftw 0x%2.2x (0x%2.2x) fop 0x%4.4x\n"
 
112
           "          fpuip 0x%16.16"PRIx64" fpudp 0x%16.16"PRIx64"\n"
 
113
           "          mxcsr 0x%8.8lx mask 0x%8.8lx\n",
 
114
           (unsigned)r->fcw, (unsigned)r->fsw, 
 
115
           (unsigned)r->ftw, (unsigned)r->res0, (unsigned)r->fop, 
 
116
           r->fpuip, r->fpudp, 
 
117
           (unsigned long)r->mxcsr, (unsigned long)r->mxcsr_mask);
 
118
 
 
119
    for ( i = 0 ; i < 8 ; i++ ) 
 
120
        printf("            mm%i 0x%4.4x%16.16"PRIx64" (0x%4.4x%4.4x%4.4x)\n",
 
121
               i, r->mm[i].hi, r->mm[i].lo,
 
122
               r->mm[i].pad[2], r->mm[i].pad[1], r->mm[i].pad[0]);
 
123
 
 
124
    for ( i = 0 ; i < 16 ; i++ ) 
 
125
        printf("          xmm%2.2i 0x%16.16"PRIx64"%16.16"PRIx64"\n",
 
126
               i, r->xmm[i].hi, r->xmm[i].lo);
 
127
    
 
128
    for ( i = 0 ; i < 6 ; i++ ) 
 
129
        printf("               (0x%16.16"PRIx64"%16.16"PRIx64")\n",
 
130
               r->res1[2*i+1], r->res1[2*i]);
 
131
}
 
132
 
 
133
static void dump_cpu(void) 
 
134
{
 
135
    HVM_SAVE_TYPE(CPU) c;
 
136
    READ(c);
 
137
    printf("    CPU:    rax 0x%16.16llx     rbx 0x%16.16llx\n"
 
138
           "            rcx 0x%16.16llx     rdx 0x%16.16llx\n"
 
139
           "            rbp 0x%16.16llx     rsi 0x%16.16llx\n"
 
140
           "            rdi 0x%16.16llx     rsp 0x%16.16llx\n"
 
141
           "             r8 0x%16.16llx      r9 0x%16.16llx\n"
 
142
           "            r10 0x%16.16llx     r11 0x%16.16llx\n"
 
143
           "            r12 0x%16.16llx     r13 0x%16.16llx\n"
 
144
           "            r14 0x%16.16llx     r15 0x%16.16llx\n"
 
145
           "            rip 0x%16.16llx  rflags 0x%16.16llx\n"
 
146
           "            cr0 0x%16.16llx     cr2 0x%16.16llx\n"
 
147
           "            cr3 0x%16.16llx     cr4 0x%16.16llx\n"
 
148
           "            dr0 0x%16.16llx     dr1 0x%16.16llx\n"
 
149
           "            dr2 0x%16.16llx     dr3 0x%16.16llx\n"
 
150
           "            dr6 0x%16.16llx     dr7 0x%16.16llx\n"
 
151
           "             cs 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
152
           "             ds 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
153
           "             es 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
154
           "             fs 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
155
           "             gs 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
156
           "             ss 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
157
           "             tr 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
158
           "           ldtr 0x%8.8x (0x%16.16llx + 0x%8.8x / 0x%5.5x)\n"
 
159
           "           itdr            (0x%16.16llx + 0x%8.8x)\n"
 
160
           "           gdtr            (0x%16.16llx + 0x%8.8x)\n"
 
161
           "    sysenter cs 0x%8.8llx  eip 0x%16.16llx  esp 0x%16.16llx\n"
 
162
           "      shadow gs 0x%16.16llx\n"
 
163
           "      MSR flags 0x%16.16llx  lstar 0x%16.16llx\n"
 
164
           "           star 0x%16.16llx  cstar 0x%16.16llx\n"
 
165
           "         sfmask 0x%16.16llx   efer 0x%16.16llx\n"
 
166
           "            tsc 0x%16.16llx\n"
 
167
           "          event 0x%8.8lx error 0x%8.8lx\n",
 
168
           (unsigned long long) c.rax, (unsigned long long) c.rbx,
 
169
           (unsigned long long) c.rcx, (unsigned long long) c.rdx,
 
170
           (unsigned long long) c.rbp, (unsigned long long) c.rsi,
 
171
           (unsigned long long) c.rdi, (unsigned long long) c.rsp,
 
172
           (unsigned long long) c.r8, (unsigned long long) c.r9,
 
173
           (unsigned long long) c.r10, (unsigned long long) c.r11,
 
174
           (unsigned long long) c.r12, (unsigned long long) c.r13,
 
175
           (unsigned long long) c.r14, (unsigned long long) c.r15,
 
176
           (unsigned long long) c.rip, (unsigned long long) c.rflags,
 
177
           (unsigned long long) c.cr0, (unsigned long long) c.cr2,
 
178
           (unsigned long long) c.cr3, (unsigned long long) c.cr4,
 
179
           (unsigned long long) c.dr0, (unsigned long long) c.dr1,
 
180
           (unsigned long long) c.dr2, (unsigned long long) c.dr3,
 
181
           (unsigned long long) c.dr6, (unsigned long long) c.dr7,
 
182
           c.cs_sel, (unsigned long long) c.cs_base, c.cs_limit, c.cs_arbytes,
 
183
           c.ds_sel, (unsigned long long) c.ds_base, c.ds_limit, c.ds_arbytes,
 
184
           c.es_sel, (unsigned long long) c.es_base, c.es_limit, c.es_arbytes,
 
185
           c.fs_sel, (unsigned long long) c.fs_base, c.fs_limit, c.fs_arbytes,
 
186
           c.gs_sel, (unsigned long long) c.gs_base, c.gs_limit, c.gs_arbytes,
 
187
           c.ss_sel, (unsigned long long) c.ss_base, c.ss_limit, c.ss_arbytes,
 
188
           c.tr_sel, (unsigned long long) c.tr_base, c.tr_limit, c.tr_arbytes,
 
189
           c.ldtr_sel, (unsigned long long) c.ldtr_base,
 
190
           c.ldtr_limit, c.ldtr_arbytes,
 
191
           (unsigned long long) c.idtr_base, c.idtr_limit, 
 
192
           (unsigned long long) c.gdtr_base, c.gdtr_limit, 
 
193
           (unsigned long long) c.sysenter_cs, 
 
194
           (unsigned long long) c.sysenter_eip, 
 
195
           (unsigned long long) c.sysenter_esp,
 
196
           (unsigned long long) c.shadow_gs,
 
197
           (unsigned long long) c.msr_flags,
 
198
           (unsigned long long) c.msr_lstar,
 
199
           (unsigned long long) c.msr_star,
 
200
           (unsigned long long) c.msr_cstar,
 
201
           (unsigned long long) c.msr_syscall_mask,
 
202
           (unsigned long long) c.msr_efer,
 
203
           (unsigned long long) c.tsc,
 
204
           (unsigned long) c.pending_event, (unsigned long) c.error_code);
 
205
    dump_fpu(&c.fpu_regs);
 
206
}
 
207
 
 
208
 
 
209
static void dump_pic(void) 
 
210
{
 
211
    HVM_SAVE_TYPE(PIC) p;
 
212
    READ(p);
 
213
    printf("    PIC: IRQ base %#x, irr %#x, imr %#x, isr %#x\n",
 
214
           p.irq_base, p.irr, p.imr, p.isr);
 
215
 
 
216
    printf("         init_state %u, priority_add %u, readsel_isr %u, poll %u\n",
 
217
           p.init_state, p.priority_add, p.readsel_isr, p.poll);
 
218
    printf("         auto_eoi %u, rotate_on_auto_eoi %u\n",
 
219
           p.auto_eoi, p.rotate_on_auto_eoi);
 
220
    printf("         special_fully_nested_mode %u, special_mask_mode %u\n",
 
221
           p.special_fully_nested_mode, p.special_mask_mode);
 
222
    printf("         is_master %u, elcr %#x, int_output %#x\n",
 
223
           p.is_master, p.elcr, p.int_output);
 
224
}
 
225
 
 
226
 
 
227
static void dump_ioapic(void) 
 
228
{
 
229
    int i;
 
230
    HVM_SAVE_TYPE(IOAPIC) p;
 
231
    READ(p);
 
232
    printf("    IOAPIC: base_address %#llx, ioregsel %#x id %#x\n",
 
233
           (unsigned long long) p.base_address, p.ioregsel, p.id);
 
234
    for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
 
235
    {
 
236
        printf("            pin %.2i: 0x%.16llx\n", i, 
 
237
               (unsigned long long) p.redirtbl[i].bits);
 
238
    }
 
239
}
 
240
 
 
241
static void dump_lapic(void)
 
242
{
 
243
    HVM_SAVE_TYPE(LAPIC) p;
 
244
    READ(p);
 
245
    printf("    LAPIC: base_msr %#llx, disabled %#x, timer_divisor %#x\n",
 
246
           (unsigned long long) p.apic_base_msr, p.disabled, p.timer_divisor);
 
247
}
 
248
 
 
249
static void dump_lapic_regs(void)
 
250
{
 
251
    unsigned int i;
 
252
    HVM_SAVE_TYPE(LAPIC_REGS) r;
 
253
    READ(r);
 
254
    printf("    LAPIC registers:\n");
 
255
    for ( i = 0 ; i < 0x400 ; i += 32 )
 
256
    {
 
257
        printf("          0x%4.4x: 0x%16.16llx   0x%4.4x: 0x%16.16llx\n",
 
258
               i, *(unsigned long long *)&r.data[i], 
 
259
               i + 16, *(unsigned long long *)&r.data[i + 16]);        
 
260
    }
 
261
}
 
262
 
 
263
static void dump_pci_irq(void)
 
264
{
 
265
    HVM_SAVE_TYPE(PCI_IRQ) i;
 
266
    READ(i);
 
267
    printf("    PCI IRQs: 0x%16.16llx%16.16llx\n", 
 
268
           (unsigned long long) i.pad[0], (unsigned long long) i.pad[1]);
 
269
}
 
270
 
 
271
static void dump_isa_irq(void)
 
272
{
 
273
    HVM_SAVE_TYPE(ISA_IRQ) i;
 
274
    READ(i);
 
275
    printf("    ISA IRQs: 0x%4.4llx\n", 
 
276
           (unsigned long long) i.pad[0]);
 
277
}
 
278
 
 
279
static void dump_pci_link(void)
 
280
{
 
281
    HVM_SAVE_TYPE(PCI_LINK) l;
 
282
    READ(l);
 
283
    printf("    PCI LINK: %u %u %u %u\n", 
 
284
           l.route[0], l.route[1], l.route[2], l.route[3]);
 
285
}
 
286
 
 
287
static void dump_pit(void) 
 
288
{
 
289
    int i;
 
290
    HVM_SAVE_TYPE(PIT) p;
 
291
    READ(p);
 
292
    printf("    PIT: speaker %s\n", p.speaker_data_on ? "on" : "off");
 
293
    for ( i = 0 ; i < 2 ; i++ )
 
294
    {
 
295
        printf("         ch %1i: count %#x, latched_count %#x, count_latched %u\n", 
 
296
               i, p.channels[i].count, p.channels[i].latched_count, 
 
297
               p.channels[i].count_latched);
 
298
        printf("               status %#x, status_latched %#x\n", 
 
299
               p.channels[i].status, p.channels[i].status_latched);
 
300
        printf("               rd_state %#x, wr_state %#x, wr_latch %#x, rw_mode %#x\n", 
 
301
               p.channels[i].read_state, p.channels[i].write_state, 
 
302
               p.channels[i].write_latch, p.channels[i].rw_mode);
 
303
        printf("               mode %#x, bcd %#x, gate %#x\n",
 
304
               p.channels[i].mode, p.channels[i].bcd, p.channels[i].gate);
 
305
    }    
 
306
}
 
307
 
 
308
static void dump_rtc(void)
 
309
{
 
310
    HVM_SAVE_TYPE(RTC) r;
 
311
    READ(r);
 
312
    printf("    RTC: regs 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
 
313
           r.cmos_data[0], r.cmos_data[1], r.cmos_data[2], r.cmos_data[3], 
 
314
           r.cmos_data[4], r.cmos_data[5], r.cmos_data[6], r.cmos_data[7]);
 
315
    printf("              0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x, index 0x%2.2x\n",
 
316
           r.cmos_data[8], r.cmos_data[9], r.cmos_data[10], r.cmos_data[11], 
 
317
           r.cmos_data[12], r.cmos_data[13], r.cmos_index);
 
318
 
 
319
}
 
320
 
 
321
static void dump_hpet(void)
 
322
{
 
323
    int i;
 
324
    HVM_SAVE_TYPE(HPET) h;
 
325
    READ(h);
 
326
    printf("    HPET: capability %#llx config %#llx\n",
 
327
           (unsigned long long) h.capability,
 
328
           (unsigned long long) h.config);
 
329
    printf("          isr %#llx counter %#llx\n",
 
330
           (unsigned long long) h.isr,
 
331
           (unsigned long long) h.mc64);
 
332
    for ( i = 0; i < HPET_TIMER_NUM; i++ )
 
333
    {
 
334
        printf("          timer%i config %#llx cmp %#llx\n", i,
 
335
               (unsigned long long) h.timers[i].config,
 
336
               (unsigned long long) h.timers[i].cmp);
 
337
        printf("          timer%i period %#llx fsb %#llx\n", i, 
 
338
               (unsigned long long) h.period[i],
 
339
               (unsigned long long) h.timers[i].fsb);
 
340
    }
 
341
}
 
342
 
 
343
static void dump_pmtimer(void)
 
344
{
 
345
    HVM_SAVE_TYPE(PMTIMER) p;
 
346
    READ(p);
 
347
    printf("    ACPI PM: TMR_VAL 0x%x, PM1a_STS 0x%x, PM1a_EN 0x%x\n", 
 
348
           p.tmr_val, (unsigned) p.pm1a_sts, (unsigned) p.pm1a_en);
 
349
}
 
350
 
 
351
static void dump_mtrr(void)
 
352
{
 
353
    HVM_SAVE_TYPE(MTRR) p;
 
354
    int i;
 
355
    READ(p);
 
356
    printf("    MTRR: PAT 0x%llx, cap 0x%llx, default 0x%llx\n", 
 
357
           (unsigned long long) p.msr_pat_cr,
 
358
           (unsigned long long) p.msr_mtrr_cap,
 
359
           (unsigned long long) p.msr_mtrr_def_type);
 
360
    for ( i = 0 ; i < MTRR_VCNT ; i++ )
 
361
        printf("          var %i 0x%16.16llx 0x%16.16llx\n", i,
 
362
               (unsigned long long) p.msr_mtrr_var[2 * i], 
 
363
               (unsigned long long) p.msr_mtrr_var[2 * i + 1]);
 
364
    for ( i = 0 ; i < NUM_FIXED_MSR ; i++ )
 
365
        printf("          fixed %.2i 0x%16.16llx\n", i,
 
366
               (unsigned long long) p.msr_mtrr_fixed[i]);
 
367
}
 
368
 
 
369
static void dump_viridian(void)
 
370
{
 
371
    HVM_SAVE_TYPE(VIRIDIAN) p;
 
372
    READ(p);
 
373
    printf("    VIRIDIAN: hypercall gpa 0x%llx, guest ID 0x%llx\n",
 
374
           (unsigned long long) p.hypercall_gpa,
 
375
           (unsigned long long) p.guest_os_id);           
 
376
}
 
377
 
 
378
int main(int argc, char **argv)
 
379
{
 
380
    int entry, domid, xch;
 
381
 
 
382
    struct hvm_save_descriptor desc;
 
383
 
 
384
    if ( argc != 2 || !argv[1] || (domid = atoi(argv[1])) < 0 ) 
 
385
    {
 
386
        fprintf(stderr, "usage: %s <domid>\n", argv[0]);
 
387
        exit(1);
 
388
    }
 
389
 
 
390
    xch = xc_interface_open();
 
391
    if ( xch < 0 )
 
392
    {
 
393
        fprintf(stderr, "Error: can't open libxc handle\n");
 
394
        exit(1);
 
395
    }
 
396
    len = xc_domain_hvm_getcontext(xch, domid, 0, 0);
 
397
    if ( len == (uint32_t) -1 )
 
398
    {
 
399
        fprintf(stderr, "Error: can't get record length for dom %i\n", domid);
 
400
        exit(1);
 
401
    }
 
402
    buf = malloc(len);
 
403
    if ( buf == NULL )
 
404
    {
 
405
        fprintf(stderr, "Error: can't allocate %u bytes\n", len);
 
406
        exit(1);
 
407
    }
 
408
    len = xc_domain_hvm_getcontext(xch, domid, buf, len);
 
409
    if ( len == (uint32_t) -1 )
 
410
    {
 
411
        fprintf(stderr, "Error: can't get HVM record for dom %i\n", domid);
 
412
        exit(1);
 
413
    }
 
414
    off = 0;
 
415
 
 
416
    /* Say hello */
 
417
    printf("HVM save record for domain %i\n", domid);
 
418
 
 
419
    entry = 0;
 
420
    do {
 
421
        READ(desc);
 
422
        printf("Entry %i: type %u instance %u, length %u\n",
 
423
               entry++, (unsigned) desc.typecode,
 
424
               (unsigned) desc.instance, (unsigned) desc.length);
 
425
        switch (desc.typecode) 
 
426
        {
 
427
        case HVM_SAVE_CODE(HEADER): dump_header(); break;
 
428
        case HVM_SAVE_CODE(CPU): dump_cpu(); break;
 
429
        case HVM_SAVE_CODE(PIC): dump_pic(); break;
 
430
        case HVM_SAVE_CODE(IOAPIC): dump_ioapic(); break;
 
431
        case HVM_SAVE_CODE(LAPIC): dump_lapic(); break;
 
432
        case HVM_SAVE_CODE(LAPIC_REGS): dump_lapic_regs(); break;
 
433
        case HVM_SAVE_CODE(PCI_IRQ): dump_pci_irq(); break;
 
434
        case HVM_SAVE_CODE(ISA_IRQ): dump_isa_irq(); break;
 
435
        case HVM_SAVE_CODE(PCI_LINK): dump_pci_link(); break;
 
436
        case HVM_SAVE_CODE(PIT): dump_pit(); break;
 
437
        case HVM_SAVE_CODE(RTC): dump_rtc(); break;
 
438
        case HVM_SAVE_CODE(HPET): dump_hpet(); break;
 
439
        case HVM_SAVE_CODE(PMTIMER): dump_pmtimer(); break;
 
440
        case HVM_SAVE_CODE(MTRR): dump_mtrr(); break;
 
441
        case HVM_SAVE_CODE(VIRIDIAN): dump_viridian(); break;
 
442
        case HVM_SAVE_CODE(END): break;
 
443
        default:
 
444
            printf(" ** Don't understand type %u: skipping\n",
 
445
                   (unsigned) desc.typecode);
 
446
            off += (desc.length);
 
447
        }
 
448
    } while ( desc.typecode != HVM_SAVE_CODE(END) && off < len );
 
449
 
 
450
    return 0;
 
451