# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1192101030 -32400 # Node ID 9009a8f49f11378d562a4aed005b17f136a773c0 # Parent 57c32f36b569df0b24edd1d90b0d45035cce55d5 implement IA64 VTi domain save/restore. work in progress PATCHNAME: implement_vti_domain_save_restore Signed-off-by: Isaku Yamahata diff -r 57c32f36b569 -r 9009a8f49f11 config/ia64.mk --- a/config/ia64.mk Thu Oct 11 19:04:53 2007 +0900 +++ b/config/ia64.mk Thu Oct 11 20:10:30 2007 +0900 @@ -1,6 +1,7 @@ CONFIG_IA64 := y CONFIG_IA64 := y CONFIG_IA64_$(XEN_OS) := y +CONFIG_HVM_SAVE := y CONFIG_IOEMU := y CONFIG_XCUTILS := y CONFIG_XENCOMM := y diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/Makefile --- a/xen/arch/ia64/vmx/Makefile Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/arch/ia64/vmx/Makefile Thu Oct 11 20:10:30 2007 +0900 @@ -20,3 +20,4 @@ obj-y += optvfault.o obj-y += optvfault.o obj-y += vacpi.o obj-y += vmx_vcpu_save.o +obj-y += save.o diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/save.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/ia64/vmx/save.c Thu Oct 11 20:10:30 2007 +0900 @@ -0,0 +1,72 @@ +/* + * hvm/save.c: Save and restore HVM guest's emulated hardware state. + * + * Copyright (c) 2007, Isaku Yamahata + * VA Linux Systems Japan K.K. + * IA64 support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +void +arch_hvm_save(struct hvm_save_header *hdr) +{ + unsigned int i; + + for (i = 0; i < 5; ++i) + hdr->cpuid[i] = ia64_get_cpuid(i); +} + +int +arch_hvm_load(struct hvm_save_header *hdr) +{ + unsigned int i; + if (hdr->magic != HVM_FILE_MAGIC) { + gdprintk(XENLOG_ERR, + "HVM restore: bad magic number %#"PRIx64"\n", hdr->magic); + return -1; + } + + if (hdr->version != HVM_FILE_VERSION) { + gdprintk(XENLOG_ERR, + "HVM restore: unsupported version %"PRIx64"\n", hdr->version); + return -1; + } + + for (i = 0; i < 5; ++i) { + unsigned long cpuid = ia64_get_cpuid(i); + /*TODO: need to define how big a difference is acceptable */ + if (hdr->cpuid[i] != cpuid) + gdprintk(XENLOG_WARNING, + "HVM restore: saved CPUID[%d] (%#lx) " + "does not match host (%#lx).\n", i, hdr->cpuid[i], cpuid); + } + + return 0; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/vacpi.c --- a/xen/arch/ia64/vmx/vacpi.c Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/arch/ia64/vmx/vacpi.c Thu Oct 11 20:10:30 2007 +0900 @@ -7,6 +7,7 @@ * Copyright (c) 2007 VA Linux Systems Japan K.K * Isaku Yamahata * SMP support + * save/restore support * * Copyright (c) 2007, XenSource inc. * Copyright (c) 2006, Intel Corporation. @@ -28,6 +29,8 @@ #include #include #include +#include +#include /* The interesting bits of the PM1a_STS register */ #define TMR_STS (1 << 0) @@ -197,3 +200,69 @@ void vacpi_relinquish_resources(struct d struct vacpi *s = &d->arch.hvm_domain.vacpi; kill_timer(&s->timer); } + +// stolen from xen/arch/x86/hvm/pmtimer.c +static int vacpi_save(struct domain *d, hvm_domain_context_t *h) +{ + struct vacpi *s = &d->arch.hvm_domain.vacpi; + unsigned long delta; + uint32_t msb = s->regs.tmr_val & TMR_VAL_MSB; + struct hvm_hw_ia64_vacpi vacpi_save; + int rc; + + stop_timer(&s->timer); //XXX + + spin_lock(&s->lock); + + /* Update the counter to the guest's current time. We always save + * with the domain paused, so the saved time should be after the + * last_gtime, but just in case, make sure we only go forwards */ + + //XXX NOW() should be the time that domais paused + delta = NOW() - s->last_gtime; + delta = ((delta >> 8) * ((FREQUENCE_PMTIMER << 32) / SECONDS(1))) >> 24; + if ( delta < 1UL<<31 ) + s->regs.tmr_val += delta; + if ( (s->regs.tmr_val & TMR_VAL_MSB) != msb ) + s->regs.pm1a_sts |= TMR_STS; + /* No point in setting the SCI here because we'll already have saved the + * IRQ and *PIC state; we'll fix it up when we restore the domain */ + + vacpi_save.regs = s->regs; + rc = hvm_save_entry(VACPI, 0, h, &vacpi_save); + + spin_unlock(&s->lock); + + pmt_timer_callback(d);//XXX This might change the domain state. + return 0; +} + +static int vacpi_load(struct domain *d, hvm_domain_context_t *h) +{ + struct vacpi *s = &d->arch.hvm_domain.vacpi; + struct hvm_hw_ia64_vacpi vacpi_load; + + /* Reload the registers */ + if ( hvm_load_entry(VACPI, h, &vacpi_load) ) + return -EINVAL; + + stop_timer(&s->timer);//XXX + + spin_lock(&s->lock); + + s->regs = vacpi_load.regs; + + /* Calculate future counter values from now. */ + //XXX NOW(); last_gtime should be set when domain is unpaused + s->last_gtime = NOW(); + + /* Set the SCI state from the registers */ + pmt_update_sci(d, s); + + spin_unlock(&s->lock); + + pmt_timer_callback(d);//XXX + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(VACPI, vacpi_save, vacpi_load, 1, HVMSR_PER_DOM); diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/viosapic.c --- a/xen/arch/ia64/vmx/viosapic.c Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/arch/ia64/vmx/viosapic.c Thu Oct 11 20:10:30 2007 +0900 @@ -27,6 +27,7 @@ * Copyright (C) 2007 VA Linux Systems Japan K.K. * Isaku Yamahata * SMP support + * xen save/restore support */ #include @@ -40,6 +41,8 @@ #include #include #include +#include +#include static void viosapic_deliver(struct viosapic *viosapic, int irq) { @@ -355,3 +358,69 @@ void viosapic_init(struct domain *d) viosapic->base_address = VIOSAPIC_DEFAULT_BASE_ADDRESS; } + +#define VIOSAPIC_INVALID_VCPU_ID (-1UL) +static int viosapic_save(struct domain *d, hvm_domain_context_t *h) +{ + struct viosapic *viosapic = domain_viosapic(d); + struct hvm_hw_ia64_viosapic viosapic_save; + int i; + + memset(&viosapic_save, 0, sizeof(viosapic_save)); + + spin_lock(&viosapic->lock); + viosapic_save.irr = viosapic->irr; + viosapic_save.isr = viosapic->isr; + viosapic_save.ioregsel = viosapic->ioregsel; + if (viosapic->lowest_vcpu != NULL) + viosapic_save.lowest_vcpu_id = viosapic->lowest_vcpu->vcpu_id; + else + viosapic_save.lowest_vcpu_id = VIOSAPIC_INVALID_VCPU_ID; + viosapic_save.base_address = viosapic->base_address; + + for (i = 0; i < VIOSAPIC_NUM_PINS; i++) + viosapic_save.redirtbl[i] = viosapic->redirtbl[i]; + spin_unlock(&viosapic->lock); + + return hvm_save_entry(VIOSAPIC, 0, h, &viosapic_save); +} + +static int viosapic_load(struct domain *d, hvm_domain_context_t *h) +{ + struct viosapic *viosapic = domain_viosapic(d); + struct hvm_hw_ia64_viosapic viosapic_load; + struct vcpu *lowest_vcpu; + int i; + + if (hvm_load_entry(VIOSAPIC, h, &viosapic_load)) + return -EINVAL; + + lowest_vcpu = NULL; + if (viosapic_load.lowest_vcpu_id < MAX_VIRT_CPUS) + lowest_vcpu = d->vcpu[viosapic_load.lowest_vcpu_id]; + else if (viosapic_load.lowest_vcpu_id != VIOSAPIC_INVALID_VCPU_ID) + return -EINVAL; + + if (viosapic_load.base_address != VIOSAPIC_DEFAULT_BASE_ADDRESS) + return -EINVAL; + + spin_lock(&viosapic->lock); + viosapic->irr = viosapic_load.irr; + viosapic->isr = viosapic_load.isr; + viosapic->ioregsel = viosapic_load.ioregsel; + + viosapic->lowest_vcpu = lowest_vcpu; + + viosapic->base_address = viosapic_load.base_address; + + for (i = 0; i < VIOSAPIC_NUM_PINS; i++) + viosapic->redirtbl[i] = viosapic_load.redirtbl[i]; + + service_iosapic(viosapic);//XXX + spin_unlock(&viosapic->lock); + + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(VIOSAPIC, viosapic_save, viosapic_load, + 1, HVMSR_PER_DOM); diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/vlsapic.c --- a/xen/arch/ia64/vmx/vlsapic.c Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/arch/ia64/vmx/vlsapic.c Thu Oct 11 20:10:30 2007 +0900 @@ -3,6 +3,10 @@ /* * vlsapic.c: virtual lsapic model including ITC timer. * Copyright (c) 2005, Intel Corporation. + * + * Copyright (c) 2007, Isaku Yamahata + * VA Linux Systems Japan K.K. + * save/restore support * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -40,6 +44,8 @@ #include #include #include +#include +#include #ifdef IPI_DEBUG #define IPI_DPRINTK(x...) printk(x) @@ -820,3 +826,122 @@ void vlsapic_write(struct vcpu *v, } } +static int vlsapic_save(struct domain *d, hvm_domain_context_t *h) +{ + struct vcpu *v; + + for_each_vcpu(d, v) { + struct hvm_hw_ia64_vlsapic vlsapic; + int i; + + if (test_bit(_VPF_down, &v->pause_flags)) + continue; + + memset(&vlsapic, 0, sizeof(vlsapic)); + for (i = 0; i < 4; i++) + vlsapic.insvc[i] = VLSAPIC_INSVC(v,i); + + vlsapic.vhpi = VCPU(v, vhpi); + vlsapic.xtp = VLSAPIC_XTP(v); + vlsapic.pal_init_pending = v->arch.arch_vmx.pal_init_pending; + + if (hvm_save_entry(VLSAPIC, v->vcpu_id, h, &vlsapic)) + return -EINVAL; + } + + return 0; +} + +static int vlsapic_load(struct domain *d, hvm_domain_context_t *h) +{ + uint16_t vcpuid; + struct vcpu *v; + struct hvm_hw_ia64_vlsapic vlsapic; + int i; + + vcpuid = hvm_load_instance(h); + if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) { + gdprintk(XENLOG_ERR, + "%s: domain has no vlsapic %u\n", __func__, vcpuid); + return -EINVAL; + } + + if (hvm_load_entry(VLSAPIC, h, &vlsapic) != 0) + return -EINVAL; + + for (i = 0; i < 4; i++) + VLSAPIC_INSVC(v,i) = vlsapic.insvc[i]; + + VCPU(v, vhpi) = vlsapic.vhpi; + VLSAPIC_XTP(v) = vlsapic.xtp; + v->arch.arch_vmx.pal_init_pending = vlsapic.pal_init_pending; + v->arch.irq_new_pending = 1; /* to force checking irq */ + + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(VLSAPIC, vlsapic_save, vlsapic_load, + 1, HVMSR_PER_VCPU); + +static int vtime_save(struct domain *d, hvm_domain_context_t *h) +{ + struct vcpu *v; + + for_each_vcpu(d, v) { + vtime_t *vtm = &VMX(v, vtm); + struct hvm_hw_ia64_vtime vtime; + + if (test_bit(_VPF_down, &v->pause_flags)) + continue; + + stop_timer(&vtm->vtm_timer);//XXX should wait for callback not running. + + memset(&vtime, 0, sizeof(vtime)); + vtime.itc = now_itc(vtm); + vtime.itm = VCPU(v, itm); + vtime.last_itc = vtm->last_itc; + vtime.pending = vtm->pending; + + vtm_set_itm(v, vtime.itm);// this may start timer. + + if (hvm_save_entry(VTIME, v->vcpu_id, h, &vtime)) + return -EINVAL; + } + + return 0; +} + +static int vtime_load(struct domain *d, hvm_domain_context_t *h) +{ + uint16_t vcpuid; + struct vcpu *v; + struct hvm_hw_ia64_vtime vtime; + vtime_t *vtm; + + vcpuid = hvm_load_instance(h); + if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) { + gdprintk(XENLOG_ERR, + "%s: domain has no vtime %u\n", __func__, vcpuid); + return -EINVAL; + } + + if (hvm_load_entry(VTIME, h, &vtime) != 0) + return -EINVAL; + + vtm = &VMX(v, vtm); + stop_timer(&vtm->vtm_timer); //XXX should wait for callback not running. + + vtm->last_itc = vtime.last_itc; + vtm->pending = vtime.pending; + + migrate_timer(&vtm->vtm_timer, v->processor); + vtm_set_itm(v, vtime.itm); + vtm_set_itc(v, vtime.itc); // This may start timer. + + if (test_and_clear_bit(_VPF_down, &v->pause_flags)) + vcpu_wake(v); + + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(VTIME, vtime_save, vtime_load, 1, HVMSR_PER_VCPU); diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/vmx_vcpu_save.c --- a/xen/arch/ia64/vmx/vmx_vcpu_save.c Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/arch/ia64/vmx/vmx_vcpu_save.c Thu Oct 11 20:10:30 2007 +0900 @@ -22,6 +22,8 @@ #include #include +#include +#include void vmx_arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) @@ -192,6 +194,166 @@ vmx_arch_set_info_guest(struct vcpu *v, return 0; } + +static int vmx_cpu_save(struct domain *d, hvm_domain_context_t *h) +{ + struct vcpu *v; + + for_each_vcpu(d, v) { + struct pt_regs *regs = vcpu_regs(v); + struct hvm_hw_ia64_cpu ia64_cpu; + + if (test_bit(_VPF_down, &v->pause_flags)) + continue; + + memset(&ia64_cpu, 0, sizeof(ia64_cpu)); + + ia64_cpu.ipsr = regs->cr_ipsr; + + if (hvm_save_entry(CPU, v->vcpu_id, h, &ia64_cpu)) + return -EINVAL; + } + + return 0; +} + +static int vmx_cpu_load(struct domain *d, hvm_domain_context_t *h) +{ + int rc = 0; + uint16_t vcpuid; + struct vcpu *v; + struct hvm_hw_ia64_cpu ia64_cpu; + struct pt_regs *regs; + + vcpuid = hvm_load_instance(h); + if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) { + gdprintk(XENLOG_ERR, + "%s: domain has no vcpu %u\n", __func__, vcpuid); + rc = -EINVAL; + goto out; + } + + if (hvm_load_entry(CPU, h, &ia64_cpu) != 0) { + rc = -EINVAL; + goto out; + } + + regs = vcpu_regs(v); + regs->cr_ipsr = ia64_cpu.ipsr | IA64_PSR_VM; + + out: + return rc; +} + +HVM_REGISTER_SAVE_RESTORE(CPU, vmx_cpu_save, vmx_cpu_load, 1, HVMSR_PER_VCPU); + +static int vmx_vpd_save(struct domain *d, hvm_domain_context_t *h) +{ + struct vcpu *v; + + for_each_vcpu(d, v) { + vpd_t *vpd = (void *)v->arch.privregs; + + if (test_bit(_VPF_down, &v->pause_flags)) + continue; + + // currently struct hvm_hw_ia64_vpd = struct vpd + // if it is changed, this must be revised. + if (hvm_save_entry(VPD, v->vcpu_id, h, (struct hvm_hw_ia64_vpd*)vpd)) + return -EINVAL; + } + + return 0; +} + +static int vmx_vpd_load(struct domain *d, hvm_domain_context_t *h) +{ + int rc = 0; + uint16_t vcpuid; + struct vcpu *v; + vpd_t *vpd; + struct hvm_hw_ia64_vpd *ia64_vpd = NULL; + int i; + + vcpuid = hvm_load_instance(h); + if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) { + gdprintk(XENLOG_ERR, + "%s: domain has no vcpu %u\n", __func__, vcpuid); + rc = -EINVAL; + goto out; + } + + ia64_vpd = xmalloc(struct hvm_hw_ia64_vpd); + if (ia64_vpd == NULL) { + gdprintk(XENLOG_ERR, + "%s: can't allocate memory %d\n", __func__, vcpuid); + rc = -ENOMEM; + goto out; + } + + if (hvm_load_entry(VPD, h, ia64_vpd) != 0) { + rc = -EINVAL; + goto out; + } + + vpd = (void *)v->arch.privregs; +#define VPD_COPY(x) vpd->vpd_low.x = ia64_vpd->vpd.vpd_low.x + + for (i = 0; i < 16; i++) + VPD_COPY(vgr[i]); + for (i = 0; i < 16; i++) + VPD_COPY(vbgr[i]); + VPD_COPY(vnat); + VPD_COPY(vbnat); + for (i = 0; i < 5; i++) + VPD_COPY(vcpuid[i]); + VPD_COPY(vpsr); + VPD_COPY(vpr); + + // cr +#if 0 + VPD_COPY(dcr); + VPD_COPY(itm); + VPD_COPY(iva); + VPD_COPY(pta); + VPD_COPY(ipsr); + VPD_COPY(isr); + VPD_COPY(iip); + VPD_COPY(ifa); + VPD_COPY(itir); + VPD_COPY(iipa); + VPD_COPY(ifs); + VPD_COPY(iim); + VPD_COPY(iha); + VPD_COPY(lid); + VPD_COPY(ivr); + VPD_COPY(tpr); + VPD_COPY(eoi); + VPD_COPY(irr[0]); + VPD_COPY(irr[1]); + VPD_COPY(irr[2]); + VPD_COPY(irr[3]); + VPD_COPY(itv); + VPD_COPY(pmv); + VPD_COPY(cmcv); + VPD_COPY(lrr0); + VPD_COPY(lrr1); +#else + memcpy(&vpd->vpd_low.vcr[0], &ia64_vpd->vpd.vpd_low.vcr[0], + sizeof(vpd->vpd_low.vcr)); +#endif +#undef VPD_COPY + + v->arch.irq_new_condition = 1; + + out: + if (ia64_vpd != NULL) + xfree(ia64_vpd); + return rc; +} + +HVM_REGISTER_SAVE_RESTORE(VPD, vmx_vpd_save, vmx_vpd_load, 1, HVMSR_PER_VCPU); + /* * Local variables: * mode: C diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/asm-ia64/hvm/support.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-ia64/hvm/support.h Thu Oct 11 20:10:30 2007 +0900 @@ -0,0 +1,28 @@ +/* + * xen/include/asm-ia64/hvm/support.h + * + * Copyright (c) 2007, Isaku Yamahata + * VA Linux Systems Japan K.K. + * IA64 support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_IA64_HVM_SUPPORT_H__ +#define __ASM_IA64_HVM_SUPPORT_H__ + +#include + +#endif /* __ASM_IA64_HVM_SUPPORT_H__ */ diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/asm-ia64/hvm/vacpi.h --- a/xen/include/asm-ia64/hvm/vacpi.h Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/include/asm-ia64/hvm/vacpi.h Thu Oct 11 20:10:30 2007 +0900 @@ -21,6 +21,7 @@ #ifndef __ASM_IA64_HVM_VACPI_H__ #define __ASM_IA64_HVM_VACPI_H__ +#include /* for struct vacpi_regs */ #include #define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40 @@ -30,17 +31,6 @@ #define IS_ACPI_ADDR(X) ((unsigned long)((X)-ACPI_PM1A_EVT_BLK_ADDRESS)<12) #define FREQUENCE_PMTIMER 3579545UL /* Timer should run at 3.579545 MHz */ - -struct vacpi_regs { - union { - struct { - uint32_t pm1a_sts:16; - uint32_t pm1a_en:16; - }; - uint32_t evt_blk; - }; - uint32_t tmr_val; -}; struct vacpi { struct vacpi_regs regs; diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/asm-ia64/viosapic.h --- a/xen/include/asm-ia64/viosapic.h Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/include/asm-ia64/viosapic.h Thu Oct 11 20:10:30 2007 +0900 @@ -29,6 +29,8 @@ #include #include #include +#include /* for VIOSAPIC_NUM_PINS and + union viosapic_rte */ /* Direct registers. */ #define VIOSAPIC_REG_SELECT 0x00 @@ -42,8 +44,6 @@ #define VIOSAPIC_VERSION_ID 0x21 /* IOSAPIC version */ -#define VIOSAPIC_NUM_PINS 48 - #define VIOSAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 #define VIOSAPIC_MEM_LENGTH 0x100 @@ -51,27 +51,6 @@ #define viosapic_domain(v) (container_of((v), struct domain, \ arch.hvm_domain.viosapic)) #define vcpu_viosapic(v) (&(v)->domain->arch.hvm_domain.viosapic) - -union viosapic_rte -{ - uint64_t bits; - struct { - uint8_t vector; - - uint8_t delivery_mode : 3; - uint8_t reserve1 : 1; - uint8_t delivery_status: 1; - uint8_t polarity : 1; - uint8_t reserve2 : 1; - uint8_t trig_mode : 1; - - uint8_t mask : 1; - uint8_t reserve3 : 7; - - uint8_t reserved[3]; - uint16_t dest_id; - }; -}; struct viosapic { uint64_t irr; diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/public/hvm/save-ia64.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/public/hvm/save-ia64.h Thu Oct 11 20:10:30 2007 +0900 @@ -0,0 +1,195 @@ +/****************************************************************************** + * save_types.h + * + * Copyright (c) 2007 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_IA64_HVM_SAVE_TYPES_H__ +#define __ASM_IA64_HVM_SAVE_TYPES_H__ + +#include +#include + +/* + * Save/restore header: general info about the save file. + */ + +/* x86 uses 0x54381286 */ +#define HVM_FILE_MAGIC 0x343641492f6e6558UL /* "Xen/IA64" */ +#define HVM_FILE_VERSION 0x0000000000000001UL + +struct hvm_save_header { + uint64_t magic; /* Must be HVM_FILE_MAGIC */ + uint64_t version; /* File format version */ + uint64_t changeset; /* Version of Xen that saved this file */ + uint64_t cpuid[5]; /* CPUID[0x01][%eax] on the saving machine */ +}; + +DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); + +/* + * CPU + */ +struct hvm_hw_ia64_cpu { + uint64_t ipsr; +}; +DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_ia64_cpu); + +/* + * CPU + */ +struct hvm_hw_ia64_vpd { + struct vpd vpd; +}; +DECLARE_HVM_SAVE_TYPE(VPD, 3, struct hvm_hw_ia64_vpd); + +/* + * device dependency + * vacpi => viosapic => vlsapic + */ +/* + * vlsapic + */ +struct hvm_hw_ia64_vlsapic { + uint64_t insvc[4]; + uint64_t vhpi; // ??? should this be saved in vpd + uint8_t xtp; + uint8_t pal_init_pending; + uint8_t pad[2]; +}; +DECLARE_HVM_SAVE_TYPE(VLSAPIC, 4, struct hvm_hw_ia64_vlsapic); +// unconditionaly set v->arch.irq_new_peding = 1 +// unconditionaly set v->arch.irq_new_condition = 0 + +/* + * vtime + */ +// itc, itm, itv are saved by arch vcpu context +struct hvm_hw_ia64_vtime { + uint64_t itc; + uint64_t itm; + + uint64_t last_itc; + uint64_t pending; +}; +DECLARE_HVM_SAVE_TYPE(VTIME, 5, struct hvm_hw_ia64_vtime); +// calculate v->vtm.vtm_offset +// ??? Or should vtm_offset be set by leave_hypervisor_tail()? +// start vtm_timer if necessary by vtm_set_itm(). +// ??? Or should vtm_timer be set by leave_hypervisor_tail()? +// +// ??? or should be done by schedule_tail() +// => schedule_tail() should do. + +/* + * viosapic + */ +#define VIOSAPIC_NUM_PINS 48 + +union viosapic_rte +{ + uint64_t bits; + struct { + uint8_t vector; + + uint8_t delivery_mode : 3; + uint8_t reserve1 : 1; + uint8_t delivery_status: 1; + uint8_t polarity : 1; + uint8_t reserve2 : 1; + uint8_t trig_mode : 1; + + uint8_t mask : 1; + uint8_t reserve3 : 7; + + uint8_t reserved[3]; + uint16_t dest_id; + }; +}; + +struct hvm_hw_ia64_viosapic { + uint64_t irr; + uint64_t isr; + uint32_t ioregsel; + uint32_t pad; + uint64_t lowest_vcpu_id; + uint64_t base_address; + union viosapic_rte redirtbl[VIOSAPIC_NUM_PINS]; +}; +DECLARE_HVM_SAVE_TYPE(VIOSAPIC, 6, struct hvm_hw_ia64_viosapic); + +/* + * vacpi + * PM timer + */ +#if 0 +struct hvm_hw_ia64_pmtimer { + uint32_t tmr_val; /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */ + uint16_t pm1a_sts; /* PM1a_EVT_BLK.PM1a_STS: status register */ + uint16_t pm1a_en; /* PM1a_EVT_BLK.PM1a_EN: enable register */ +}; +DECLARE_HVM_SAVE_TYPE(PMTIMER, 7, struct hvm_hw_ia64_pmtimer); +#else +struct vacpi_regs { + union { + struct { + uint32_t pm1a_sts:16; + uint32_t pm1a_en:16; + }; + uint32_t evt_blk; + }; + uint32_t tmr_val; +}; + +struct hvm_hw_ia64_vacpi { + struct vacpi_regs regs; +}; +DECLARE_HVM_SAVE_TYPE(VACPI, 7, struct hvm_hw_ia64_vacpi); +// update last_gtime and setup timer of struct vacpi +#endif + +#if 0 +/* + * guest os type + * XXX Xen guest os specific optimization + * This isn't hvm specific so this should be addressed genericly + * including paravirtualized domain. + */ +struct hvm_hw_ia64_gos { + uint64_t gos_type; +}; +DECLARE_HVM_SAVE_TYPE(GOS_TYPE, 8, struct hvm_hw_ia64_gos); +#endif + +/* + * Largest type-code in use + */ +#define HVM_SAVE_CODE_MAX 7 + +#endif /* __ASM_IA64_HVM_SAVE_TYPES_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/public/hvm/save.h --- a/xen/include/public/hvm/save.h Thu Oct 11 19:04:53 2007 +0900 +++ b/xen/include/public/hvm/save.h Thu Oct 11 20:10:30 2007 +0900 @@ -76,6 +76,8 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm #if defined(__i386__) || defined(__x86_64__) #include "save-x86.h" +#elif defined(__ia64__) +#include "save-ia64.h" #else #error "unsupported architecture" #endif