ia64/xen-unstable

annotate xen/include/public/arch-x86/hvm/save.h @ 18621:8d993552673a

x86, hvm: Hyper-V guest interface support with small set of enlightenments

A minimal implementation of the Viridian (Hyper-V) guest
interface. The only enlightenments advertised and supported are vAPIC
MSRs and long-spin-wait notifications. The set of enlightenments can
easily be extended in future, as they are found to provide a
performance win, and configured via an extended HVM_PARAM_VIRIDIAN hvm
parameter.

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