debuggers.hg

annotate tools/misc/xen-hvmctx.c @ 22848:6341fe0f4e5a

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