anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 0/6] firmware changes as part of QEMU/Xen merge.
From: Anthony PERARD <anthony.perard@citrix.com> This patches are for Xen-unstable and Qemu-DM. With the integration of Xen into QEMU, we would like to minimise the change and use the ACPI implementation of QEMU. So there are some change to make on the firmware to match the QEMU''s BIOS. Some IO Ports are different and the sleep state values are different. Change v4->v5: - fix save of data to save in xc save. Change v3->v4: - Rename HVM_PARAM_ACPI_NEW_IOPORT to HVM_PARAM_ACPI_IOPORTS_LOCATION - Better comment for HVM_PARAM_ACPI_IOPORTS_LOCATION. Change v2->v3: Xen will register the old ioport by default and switch to the new ioport if the HVM_PARAM_ACPI_NEW_IOPORT is set. So, this series come with a new function, unregister_io_handler, and a new HVM_PARAM. Change v1->v2: This time, both old and new ioport are handled. In QEMU-Xen, the choice between one or the other is made when a saved state is restored. In Xen, both ioports are registered. Anthony PERARD (5): firmware, Change ACPI IO addresses and values to match QEMU BIOS. xen, Introduce unregister_io_handler xen, Introduce pmtimer_change_ioport and HVM_PARAM_ACPI_IOPORTS_LOCATION. firmware, Set HVM_PARAM_ACPI_IOPORTS_LOCATION libxc, save/restore, Save the HVM_PARAM_ACPI_IOPORTS_LOCATION tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ tools/firmware/hvmloader/hvmloader.c | 11 +++++++++++ tools/libxc/xc_domain_restore.c | 20 ++++++++++++++++++++ tools/libxc/xc_domain_save.c | 10 ++++++++++ tools/libxc/xg_save_restore.h | 1 + xen/arch/x86/hvm/hvm.c | 9 +++++++++ xen/arch/x86/hvm/intercept.c | 26 ++++++++++++++++++++++++++ xen/arch/x86/hvm/pmtimer.c | 26 ++++++++++++++++++++++++-- xen/include/asm-x86/hvm/io.h | 8 ++++++++ xen/include/asm-x86/hvm/vpt.h | 1 + xen/include/public/hvm/ioreq.h | 16 +++++++++++++--- xen/include/public/hvm/params.h | 12 +++++++++++- 12 files changed, 140 insertions(+), 12 deletions(-) QEMU-Xen change: Anthony PERARD (1): piix4acpi: change in ACPI to match the change in the BIOS. hw/piix4acpi.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 82 insertions(+), 17 deletions(-) -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 1/6] firmware, Change ACPI IO addresses and values to match QEMU BIOS.
From: Anthony PERARD <anthony.perard@citrix.com> As part of the QEMU/Xen merge, this patch comes to change the IO Port adresses, the value of sleep states and add some information in the PCI registers to match the implementation of the BIOS of QEMU. This patch must be applied at the same time with an other patch for the piix4acpi of qemu-xen. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ tools/firmware/hvmloader/hvmloader.c | 4 ++++ xen/include/public/hvm/ioreq.h | 16 +++++++++++++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl b/tools/firmware/hvmloader/acpi/dsdt.asl index 03799d3..ea8e324 100644 --- a/tools/firmware/hvmloader/acpi/dsdt.asl +++ b/tools/firmware/hvmloader/acpi/dsdt.asl @@ -33,22 +33,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) */ Name (\_S3, Package (0x04) { - 0x05, /* PM1a_CNT.SLP_TYP */ - 0x05, /* PM1b_CNT.SLP_TYP */ + 0x01, /* PM1a_CNT.SLP_TYP */ + 0x01, /* PM1b_CNT.SLP_TYP */ 0x0, /* reserved */ 0x0 /* reserved */ }) Name (\_S4, Package (0x04) { - 0x06, /* PM1a_CNT.SLP_TYP */ - 0x06, /* PM1b_CNT.SLP_TYP */ + 0x00, /* PM1a_CNT.SLP_TYP */ + 0x00, /* PM1b_CNT.SLP_TYP */ 0x00, /* reserved */ 0x00 /* reserved */ }) Name (\_S5, Package (0x04) { - 0x07, /* PM1a_CNT.SLP_TYP */ - 0x07, /* PM1b_CNT.SLP_TYP */ + 0x00, /* PM1a_CNT.SLP_TYP */ + 0x00, /* PM1b_CNT.SLP_TYP */ 0x00, /* reserved */ 0x00 /* reserved */ }) diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index c4c5ddc..cfe026f 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -31,6 +31,7 @@ #include "option_rom.h" #include <xen/version.h> #include <xen/hvm/params.h> +#include <xen/hvm/ioreq.h> #include <xen/memory.h> asm ( @@ -222,9 +223,12 @@ static void pci_setup(void) /* PIIX4 ACPI PM. Special device with special PCI config space. */ ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ pci_writew(devfn, 0x22, 0x0000); pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ pci_writew(devfn, 0x3d, 0x0001); + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS | 1); + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ break; case 0x0101: if ( vendor_id == 0x8086 ) diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 0c10c08..8c11767 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -100,11 +100,21 @@ struct buffered_piopage { }; #endif /* defined(__ia64__) */ -#define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40 +/* + * Value used by old qemu-dm, there have been replace to match + * the QEMU BIOS. + */ +#define ACPI_PM1A_EVT_BLK_ADDRESS_OLD 0x0000000000001f40 +#define ACPI_PM1A_CNT_BLK_ADDRESS_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD + 0x04) +#define ACPI_PM_TMR_BLK_ADDRESS_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD + 0x08) +#define ACPI_GPE0_BLK_ADDRESS_OLD (ACPI_PM_TMR_BLK_ADDRESS_OLD + 0x20) +#define ACPI_GPE0_BLK_LEN_OLD 0x08 + +#define ACPI_PM1A_EVT_BLK_ADDRESS 0x000000000000b000 #define ACPI_PM1A_CNT_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04) #define ACPI_PM_TMR_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08) -#define ACPI_GPE0_BLK_ADDRESS (ACPI_PM_TMR_BLK_ADDRESS + 0x20) -#define ACPI_GPE0_BLK_LEN 0x08 +#define ACPI_GPE0_BLK_ADDRESS (0x000000000000afe0) +#define ACPI_GPE0_BLK_LEN 0x04 #endif /* _IOREQ_H_ */ -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 2/6] xen, Introduce unregister_io_handler
From: Anthony PERARD <anthony.perard@citrix.com> To remove a handler of the io handler list, by replacing it with the last one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- xen/arch/x86/hvm/intercept.c | 26 ++++++++++++++++++++++++++ xen/include/asm-x86/hvm/io.h | 8 ++++++++ 2 files changed, 34 insertions(+), 0 deletions(-) diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index 4af9e3d..93dffc2 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -244,6 +244,32 @@ void register_io_handler( handler->num_slot++; } +void unregister_io_handler( + struct domain *d, unsigned long addr, unsigned long size, int type) +{ + struct hvm_io_handler *handler = &d->arch.hvm_domain.io_handler; + int last = handler->num_slot - 1; + int i = 0; + + for (i = 0; i <= last; i++) { + if (handler->hdl_list[i].addr == addr + && handler->hdl_list[i].size == size + && handler->hdl_list[i].type == type) { + + handler->hdl_list[i].addr = handler->hdl_list[last].addr; + handler->hdl_list[i].size = handler->hdl_list[last].size; + handler->hdl_list[i].type = handler->hdl_list[last].type; + if (handler->hdl_list[i].type == HVM_PORTIO) { + handler->hdl_list[i].action.portio = handler->hdl_list[last].action.portio; + } else { + handler->hdl_list[i].action.mmio = handler->hdl_list[last].action.mmio; + } + handler->num_slot--; + return; + } + } +} + /* * Local variables: * mode: C diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h index c10a0be..2ce8bc9 100644 --- a/xen/include/asm-x86/hvm/io.h +++ b/xen/include/asm-x86/hvm/io.h @@ -68,6 +68,8 @@ int hvm_io_intercept(ioreq_t *p, int type); void register_io_handler( struct domain *d, unsigned long addr, unsigned long size, void *action, int type); +void unregister_io_handler( + struct domain *d, unsigned long addr, unsigned long size, int type); static inline int hvm_portio_intercept(ioreq_t *p) { @@ -89,6 +91,12 @@ static inline void register_portio_handler( register_io_handler(d, addr, size, action, HVM_PORTIO); } +static inline void unregister_portio_handler( + struct domain *d, unsigned long addr, unsigned long size) +{ + unregister_io_handler(d, addr, size, HVM_PORTIO); +} + static inline void register_buffered_io_handler( struct domain *d, unsigned long addr, unsigned long size, mmio_action_t action) -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 3/6] xen, Introduce pmtimer_change_ioport and HVM_PARAM_ACPI_IOPORTS_LOCATION.
From: Anthony PERARD <anthony.perard@citrix.com> By default, Xen will handle the old ACPI IO port. But it can switch to the new one by setting the HVM_PARAM_ACPI_IOPORTS_LOCATION to 1. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- xen/arch/x86/hvm/hvm.c | 9 +++++++++ xen/arch/x86/hvm/pmtimer.c | 26 ++++++++++++++++++++++++-- xen/include/asm-x86/hvm/vpt.h | 1 + xen/include/public/hvm/params.h | 12 +++++++++++- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 94190d3..4b85000 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2991,6 +2991,15 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) rc = -EINVAL; break; + case HVM_PARAM_ACPI_IOPORTS_LOCATION: + if (a.value == 1) + pmtimer_change_ioport(d, 1); + else if (a.value == 0) + pmtimer_change_ioport(d, 0); + else + rc = -EINVAL; + + break; } if ( rc == 0 ) diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c index 1b9ab7b..f046201 100644 --- a/xen/arch/x86/hvm/pmtimer.c +++ b/xen/arch/x86/hvm/pmtimer.c @@ -24,6 +24,9 @@ #include <asm/acpi.h> /* for hvm_acpi_power_button prototype */ /* Slightly more readable port I/O addresses for the registers we intercept */ +#define PM1a_STS_ADDR_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD) +#define PM1a_EN_ADDR_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD + 2) +#define TMR_VAL_ADDR_OLD (ACPI_PM_TMR_BLK_ADDRESS_OLD) #define PM1a_STS_ADDR (ACPI_PM1A_EVT_BLK_ADDRESS) #define PM1a_EN_ADDR (ACPI_PM1A_EVT_BLK_ADDRESS + 2) #define TMR_VAL_ADDR (ACPI_PM_TMR_BLK_ADDRESS) @@ -155,16 +158,20 @@ static int handle_evt_io( switch ( addr ) { /* PM1a_STS register bits are write-to-clear */ + case PM1a_STS_ADDR_OLD: case PM1a_STS_ADDR: s->pm.pm1a_sts &= ~byte; break; + case PM1a_STS_ADDR_OLD + 1: case PM1a_STS_ADDR + 1: s->pm.pm1a_sts &= ~(byte << 8); break; + case PM1a_EN_ADDR_OLD: case PM1a_EN_ADDR: s->pm.pm1a_en = (s->pm.pm1a_en & 0xff00) | byte; break; + case PM1a_EN_ADDR_OLD + 1: case PM1a_EN_ADDR + 1: s->pm.pm1a_en = (s->pm.pm1a_en & 0xff) | (byte << 8); break; @@ -272,6 +279,21 @@ static int pmtimer_load(struct domain *d, hvm_domain_context_t *h) HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtimer_save, pmtimer_load, 1, HVMSR_PER_DOM); +void pmtimer_change_ioport(struct domain *d, int use_new) +{ + if (use_new) { + register_portio_handler(d, TMR_VAL_ADDR, 4, handle_pmt_io); + register_portio_handler(d, PM1a_STS_ADDR, 4, handle_evt_io); + unregister_portio_handler(d, TMR_VAL_ADDR_OLD, 4); + unregister_portio_handler(d, PM1a_STS_ADDR_OLD, 4); + } else { + register_portio_handler(d, TMR_VAL_ADDR_OLD, 4, handle_pmt_io); + register_portio_handler(d, PM1a_STS_ADDR_OLD, 4, handle_evt_io); + unregister_portio_handler(d, TMR_VAL_ADDR, 4); + unregister_portio_handler(d, PM1a_STS_ADDR, 4); + } +} + void pmtimer_init(struct vcpu *v) { PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt; @@ -284,8 +306,8 @@ void pmtimer_init(struct vcpu *v) /* Intercept port I/O (need two handlers because PM1a_CNT is between * PM1a_EN and TMR_VAL and is handled by qemu) */ - register_portio_handler(v->domain, TMR_VAL_ADDR, 4, handle_pmt_io); - register_portio_handler(v->domain, PM1a_STS_ADDR, 4, handle_evt_io); + register_portio_handler(v->domain, TMR_VAL_ADDR_OLD, 4, handle_pmt_io); + register_portio_handler(v->domain, PM1a_STS_ADDR_OLD, 4, handle_evt_io); /* Set up callback to fire SCIs when the MSB of TMR_VAL changes */ init_timer(&s->timer, pmt_timer_callback, s, v->processor); diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h index 65b0dff..6b68888 100644 --- a/xen/include/asm-x86/hvm/vpt.h +++ b/xen/include/asm-x86/hvm/vpt.h @@ -179,6 +179,7 @@ void rtc_update_clock(struct domain *d); void pmtimer_init(struct vcpu *v); void pmtimer_deinit(struct domain *d); void pmtimer_reset(struct domain *d); +void pmtimer_change_ioport(struct domain *d, int use_new); void hpet_init(struct vcpu *v); void hpet_deinit(struct domain *d); diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 673148b..2558070 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -113,6 +113,16 @@ #define HVM_PARAM_CONSOLE_PFN 17 #define HVM_PARAM_CONSOLE_EVTCHN 18 -#define HVM_NR_PARAMS 19 +/* + * The firmware have changed to match the QEMU one, specifically, the addresses + * of the ACPI port I/O have changed. So, this parameter give the ability for + * Xen to handle both addresses. Possible values: + * - 0: default, use the old addresses (0x1f40, 0x1f48) + * - 1: use the qemu/new addresses (0xb000, 0xb0008) + * You can found the addresses in xen/include/public/hvm/ioreq.h. + */ +#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19 + +#define HVM_NR_PARAMS 20 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 4/6] firmware, Set HVM_PARAM_ACPI_IOPORTS_LOCATION
From: Anthony PERARD <anthony.perard@citrix.com> This will tell the Xen to use the new Port I/O instead of the old one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/hvmloader.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index cfe026f..bf23f80 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -763,8 +763,15 @@ int main(void) if ( hvm_info->acpi_enabled ) { + struct xen_hvm_param p = { + .domid = DOMID_SELF, + .index = HVM_PARAM_ACPI_IOPORTS_LOCATION, + .value = 1, + }; + printf("Loading ACPI ...\n"); acpi_build_tables(); + hypercall_hvm_op(HVMOP_set_param, &p); } init_vm86_tss(); -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 5/6] libxc, save/restore, Save the HVM_PARAM_ACPI_IOPORTS_LOCATION
From: Anthony PERARD <anthony.perard@citrix.com> This will save the acpi_ioport_location hvm_param in the checkpoint file and set the parameter in Xen at restore. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/libxc/xc_domain_restore.c | 20 ++++++++++++++++++++ tools/libxc/xc_domain_save.c | 10 ++++++++++ tools/libxc/xg_save_restore.h | 1 + 3 files changed, 31 insertions(+), 0 deletions(-) diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 316f32d..3c98fdc 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -647,6 +647,7 @@ typedef struct { uint64_t identpt; uint64_t vm86_tss; uint64_t console_pfn; + uint64_t acpi_ioport_location; } pagebuf_t; static int pagebuf_init(pagebuf_t* buf) @@ -771,6 +772,16 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx, // DPRINTF("last checkpoint indication received"); return pagebuf_get_one(xch, ctx, buf, fd, dom); + case XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION: + /* Skip padding 4 bytes then read the acpi ioport location. */ + if ( RDEXACT(fd, &buf->acpi_ioport_location, sizeof(uint32_t)) || + RDEXACT(fd, &buf->acpi_ioport_location, sizeof(uint64_t)) ) + { + PERROR("error read the acpi ioport location"); + return -1; + } + return pagebuf_get_one(xch, ctx, buf, fd, dom); + default: if ( (count > MAX_BATCH_SIZE) || (count < 0) ) { ERROR("Max batch size exceeded (%d). Giving up.", count); @@ -1317,6 +1328,15 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, fcntl(io_fd, F_SETFL, orig_io_fd_flags | O_NONBLOCK); } + if (pagebuf.acpi_ioport_location == 1) { + DBGPRINTF("Use new firmware ioport from the checkpoint\n"); + xc_set_hvm_param(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION, 1); + } else if (pagebuf.acpi_ioport_location == 0) { + DBGPRINTF("Use old firmware ioport from the checkpoint\n"); + } else { + ERROR("Error, unknow acpi ioport location (%i)", pagebuf.acpi_ioport_location); + } + if ( ctx->last_checkpoint ) { // DPRINTF("Last checkpoint, finishing\n"); diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index 47f8a79..dbc4abb 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -1618,6 +1618,16 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter PERROR("Error when writing the console pfn for guest"); goto out; } + + chunk.id = XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION; + xc_get_hvm_param(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION, + (unsigned long *)&chunk.data); + + if ((chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk))) + { + PERROR("Error when writing the firmware ioport version"); + goto out; + } } if ( !callbacks->checkpoint ) diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h index 2c82ce7..4c53f5b 100644 --- a/tools/libxc/xg_save_restore.h +++ b/tools/libxc/xg_save_restore.h @@ -132,6 +132,7 @@ #define XC_SAVE_ID_TSC_INFO -7 #define XC_SAVE_ID_HVM_CONSOLE_PFN -8 /* (HVM-only) */ #define XC_SAVE_ID_LAST_CHECKPOINT -9 /* Commit to restoring after completion of current iteration. */ +#define XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION -10 /* ** We process save/restore/migrate in batches of pages; the below -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-29 17:22 UTC
[Xen-devel] [PATCH V5 6/6] piix4acpi: change in ACPI to match the change in the BIOS.
From: Anthony PERARD <anthony.perard@citrix.com> Some change have been introduced in the firmware to match QEMU''s BIOS. So this patch adds the new sleep state values and handle old and new ACPI IOPort mapping. QEMU-Xen uses new ioport by default, but if it''s a saved state with old firmware, it unmaps the new ioport and maps the old one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- hw/piix4acpi.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 82 insertions(+), 17 deletions(-) diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c index 1efa77d..92e728e 100644 --- a/hw/piix4acpi.c +++ b/hw/piix4acpi.c @@ -52,9 +52,12 @@ /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */ /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */ -#define SLP_TYP_S4 (6 << 10) -#define SLP_TYP_S3 (5 << 10) -#define SLP_TYP_S5 (7 << 10) +#define SLP_TYP_S4_OLD (6 << 10) +#define SLP_TYP_S3_OLD (5 << 10) +#define SLP_TYP_S5_OLD (7 << 10) +#define SLP_TYP_S4 (0 << 10) +#define SLP_TYP_S3 (1 << 10) +#define SLP_TYP_S5 (0 << 10) #define ACPI_DBG_IO_ADDR 0xb044 #define ACPI_PHP_IO_ADDR 0x10c0 @@ -75,12 +78,15 @@ typedef struct PCIAcpiState { PCIDevice dev; uint16_t pm1_control; /* pm1a_ECNT_BLK */ + + /* if true, use old ioport of the firmware. */ + uint8_t use_old_ioport; } PCIAcpiState; typedef struct GPEState { /* GPE0 block */ - uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2]; - uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2]; + uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN_OLD / 2]; + uint8_t gpe0_en[ACPI_GPE0_BLK_LEN_OLD / 2]; /* CPU bitmap */ uint8_t cpus_sts[32]; @@ -88,6 +94,8 @@ typedef struct GPEState { /* SCI IRQ level */ uint8_t sci_asserted; + /* if true, use old ioport of the firmware. */ + uint8_t use_old_ioport; } GPEState; static GPEState gpe_state; @@ -100,6 +108,9 @@ typedef struct PHPDevFn { * PSTB in ASL */ } PHPDevFn; +static void acpi_map(PCIDevice *pci_dev, int region_num, + uint32_t addr, uint32_t size, int type); + static PHPDevFn php_devfn; int s3_shutdown_flag; static qemu_irq sci_irq; @@ -138,18 +149,36 @@ static void piix4acpi_save(QEMUFile *f, void *opaque) PCIAcpiState *s = opaque; pci_device_save(&s->dev, f); qemu_put_be16s(f, &s->pm1_control); + qemu_put_8s(f, &s->use_old_ioport); } static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id) { PCIAcpiState *s = opaque; int ret; - if (version_id > 1) + + if (version_id > 2) return -EINVAL; ret = pci_device_load(&s->dev, f); if (ret < 0) return ret; qemu_get_be16s(f, &s->pm1_control); + + if (version_id <= 1) { + /* map to old ioport instead of the new one */ + s->use_old_ioport = 1; + } else { + qemu_get_8s(f, &s->use_old_ioport); + } + + if (s->use_old_ioport) { + PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "ACPI: Use old firmware IOPorts.\n"); + /* unmap new ioport to use old ioport */ + isa_unassign_ioport(ACPI_PM1A_EVT_BLK_ADDRESS + 4, 2); + acpi_map((PCIDevice *)s, 0, ACPI_PM1A_EVT_BLK_ADDRESS_OLD, 0x10, PCI_ADDRESS_SPACE_IO); + } else { + PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "ACPI: Keep new firmware IOPorts.\n"); + } return 0; } @@ -172,6 +201,7 @@ static void acpi_shutdown(uint32_t val) return; switch (val & SLP_TYP_Sx) { + case SLP_TYP_S3_OLD: case SLP_TYP_S3: s3_shutdown_flag = 1; qemu_system_reset(); @@ -179,7 +209,8 @@ static void acpi_shutdown(uint32_t val) cmos_set_s3_resume(); xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3); break; - case SLP_TYP_S4: + case SLP_TYP_S4_OLD: + case SLP_TYP_S5_OLD: case SLP_TYP_S5: qemu_system_shutdown_request(); break; @@ -403,7 +434,10 @@ static uint32_t gpe_sts_read(void *opaque, uint32_t addr) { GPEState *s = opaque; - return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS]; + if (s->use_old_ioport) + return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS_OLD]; + else + return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS]; } /* write 1 to clear specific GPE bits */ @@ -415,7 +449,10 @@ static void gpe_sts_write(void *opaque, uint32_t addr, uint32_t val) PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_sts_write: addr=0x%x, val=0x%x.\n", addr, val); hotplugged = test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT); - s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val; + if (s->use_old_ioport) + s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS_OLD] &= ~val; + else + s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val; if ( s->sci_asserted && hotplugged && !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT)) { @@ -429,7 +466,10 @@ static uint32_t gpe_en_read(void *opaque, uint32_t addr) { GPEState *s = opaque; - return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)]; + if (s->use_old_ioport) + return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2)]; + else + return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)]; } /* write 0 to clear en bit */ @@ -439,7 +479,10 @@ static void gpe_en_write(void *opaque, uint32_t addr, uint32_t val) int reg_count; PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_en_write: addr=0x%x, val=0x%x.\n", addr, val); - reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2); + if (s->use_old_ioport) + reg_count = addr - (ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2); + else + reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2); s->gpe0_en[reg_count] = val; /* If disable GPE bit right after generating SCI on it, * need deassert the intr to avoid redundant intrs @@ -459,7 +502,7 @@ static void gpe_save(QEMUFile* f, void* opaque) GPEState *s = (GPEState*)opaque; int i; - for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) { + for ( i = 0; i < ACPI_GPE0_BLK_LEN_OLD / 2; i++ ) { qemu_put_8s(f, &s->gpe0_sts[i]); qemu_put_8s(f, &s->gpe0_en[i]); } @@ -468,21 +511,43 @@ static void gpe_save(QEMUFile* f, void* opaque) if ( s->sci_asserted ) { PIIX4ACPI_LOG(PIIX4ACPI_LOG_INFO, "gpe_save with sci asserted!\n"); } + + qemu_put_8s(f, &s->use_old_ioport); } static int gpe_load(QEMUFile* f, void* opaque, int version_id) { GPEState *s = (GPEState*)opaque; int i; - if (version_id != 1) + if (version_id > 2) return -EINVAL; - for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) { + for ( i = 0; i < ACPI_GPE0_BLK_LEN_OLD / 2; i++ ) { qemu_get_8s(f, &s->gpe0_sts[i]); qemu_get_8s(f, &s->gpe0_en[i]); } qemu_get_8s(f, &s->sci_asserted); + + if (version_id <= 1) { + s->use_old_ioport = 1; + } else { + qemu_get_8s(f, &s->use_old_ioport); + } + + if (s->use_old_ioport) { + isa_unassign_ioport(ACPI_GPE0_BLK_ADDRESS, ACPI_GPE0_BLK_LEN); + + register_ioport_read(ACPI_GPE0_BLK_ADDRESS_OLD, ACPI_GPE0_BLK_LEN_OLD / 2, + 1, gpe_sts_read, s); + register_ioport_read(ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2, + ACPI_GPE0_BLK_LEN_OLD / 2, 1, gpe_en_read, s); + register_ioport_write(ACPI_GPE0_BLK_ADDRESS_OLD, ACPI_GPE0_BLK_LEN_OLD / 2, + 1, gpe_sts_write, s); + register_ioport_write(ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2, + ACPI_GPE0_BLK_LEN_OLD / 2, 1, gpe_en_write, s); + } + return 0; } @@ -551,7 +616,7 @@ static void gpe_acpi_init(void) gpe_en_write, s); - register_savevm("gpe", 0, 1, gpe_save, gpe_load, s); + register_savevm("gpe", 0, 2, gpe_save, gpe_load, s); } #ifdef CONFIG_PASSTHROUGH @@ -703,7 +768,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, pci_conf[0x43] = 0x00; d->pm1_control = SCI_EN; - acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO); + acpi_map((PCIDevice *)d, 0, ACPI_PM1A_EVT_BLK_ADDRESS, 0x10, PCI_ADDRESS_SPACE_IO); gpe_acpi_init(); #ifdef CONFIG_PASSTHROUGH @@ -711,7 +776,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, #endif register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d); - register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d); + register_savevm("piix4acpi", 0, 2, piix4acpi_save, piix4acpi_load, d); return NULL; } -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2010-Nov-08 17:26 UTC
Re: [Xen-devel] [PATCH V5 5/6] libxc, save/restore, Save the HVM_PARAM_ACPI_IOPORTS_LOCATION
anthony.perard@citrix.com writes ("[Xen-devel] [PATCH V5 5/6] libxc, save/restore, Save the HVM_PARAM_ACPI_IOPORTS_LOCATION"):> From: Anthony PERARD <anthony.perard@citrix.com> > > This will save the acpi_ioport_location hvm_param in the checkpoint file > and set the parameter in Xen at restore.I''ve applied this patch, thanks. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2010-Nov-08 17:38 UTC
Re: [Xen-devel] [PATCH V5 6/6] piix4acpi: change in ACPI to match the change in the BIOS.
anthony.perard@citrix.com writes ("[Xen-devel] [PATCH V5 6/6] piix4acpi: change in ACPI to match the change in the BIOS."):> - reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2); > + if (s->use_old_ioport) > + reg_count = addr - (ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2); > + else > + reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2);There are lots of this kind of pattern in this patch. I think it would be better to make variables in GPEState called gpe0_blk_address and gpe0_blk_len and use them consistently. As well as being better style, that would make the patch less disruptive and so make it easier to cross-port changes in future. If I''m not mistaken, your 1/6, 4/6 and 6/6 all need to go in together ? In which case 1/6 and 4/6 should be one patch, not two. Re the qemu and xen patches, I can combine them. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Nov-09 15:34 UTC
[Xen-devel] [PATCH 1/2] firmware, Change ACPI IO values to match QEMU BIOS.
From: Anthony PERARD <anthony.perard@citrix.com> As part of the QEMU/Xen merge, this patch comes to change the value of sleep states and add some information in the PCI registers to match the implementation of the BIOS of QEMU. It also does a hypercall (HVM_PARAM_ACPI_IOPORTS_LOCATION) that tell the Xen to use the new Port I/O instead of the old one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ tools/firmware/hvmloader/hvmloader.c | 11 +++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl b/tools/firmware/hvmloader/acpi/dsdt.asl index 03799d3..ea8e324 100644 --- a/tools/firmware/hvmloader/acpi/dsdt.asl +++ b/tools/firmware/hvmloader/acpi/dsdt.asl @@ -33,22 +33,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) */ Name (\_S3, Package (0x04) { - 0x05, /* PM1a_CNT.SLP_TYP */ - 0x05, /* PM1b_CNT.SLP_TYP */ + 0x01, /* PM1a_CNT.SLP_TYP */ + 0x01, /* PM1b_CNT.SLP_TYP */ 0x0, /* reserved */ 0x0 /* reserved */ }) Name (\_S4, Package (0x04) { - 0x06, /* PM1a_CNT.SLP_TYP */ - 0x06, /* PM1b_CNT.SLP_TYP */ + 0x00, /* PM1a_CNT.SLP_TYP */ + 0x00, /* PM1b_CNT.SLP_TYP */ 0x00, /* reserved */ 0x00 /* reserved */ }) Name (\_S5, Package (0x04) { - 0x07, /* PM1a_CNT.SLP_TYP */ - 0x07, /* PM1b_CNT.SLP_TYP */ + 0x00, /* PM1a_CNT.SLP_TYP */ + 0x00, /* PM1b_CNT.SLP_TYP */ 0x00, /* reserved */ 0x00 /* reserved */ }) diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index c4c5ddc..bf23f80 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -31,6 +31,7 @@ #include "option_rom.h" #include <xen/version.h> #include <xen/hvm/params.h> +#include <xen/hvm/ioreq.h> #include <xen/memory.h> asm ( @@ -222,9 +223,12 @@ static void pci_setup(void) /* PIIX4 ACPI PM. Special device with special PCI config space. */ ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ pci_writew(devfn, 0x22, 0x0000); pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ pci_writew(devfn, 0x3d, 0x0001); + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS | 1); + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ break; case 0x0101: if ( vendor_id == 0x8086 ) @@ -759,8 +763,15 @@ int main(void) if ( hvm_info->acpi_enabled ) { + struct xen_hvm_param p = { + .domid = DOMID_SELF, + .index = HVM_PARAM_ACPI_IOPORTS_LOCATION, + .value = 1, + }; + printf("Loading ACPI ...\n"); acpi_build_tables(); + hypercall_hvm_op(HVMOP_set_param, &p); } init_vm86_tss(); -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Nov-09 15:34 UTC
[Xen-devel] [PATCH 2/2] piix4acpi: change in ACPI to match the change in the BIOS.
From: Anthony PERARD <anthony.perard@citrix.com> Some change have been introduced in the firmware to match QEMU''s BIOS. So this patch adds the new sleep state values and handle old and new ACPI IOPort mapping. QEMU-Xen uses new ioport by default, but if it''s a saved state with old firmware, it unmaps the new ioport and maps the old one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- hw/piix4acpi.c | 121 +++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 94 insertions(+), 27 deletions(-) diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c index 1efa77d..fb1e5c3 100644 --- a/hw/piix4acpi.c +++ b/hw/piix4acpi.c @@ -52,9 +52,12 @@ /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */ /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */ -#define SLP_TYP_S4 (6 << 10) -#define SLP_TYP_S3 (5 << 10) -#define SLP_TYP_S5 (7 << 10) +#define SLP_TYP_S4_V0 (6 << 10) +#define SLP_TYP_S3_V0 (5 << 10) +#define SLP_TYP_S5_V0 (7 << 10) +#define SLP_TYP_S4_V1 (0 << 10) +#define SLP_TYP_S3_V1 (1 << 10) +#define SLP_TYP_S5_V1 (0 << 10) #define ACPI_DBG_IO_ADDR 0xb044 #define ACPI_PHP_IO_ADDR 0x10c0 @@ -75,12 +78,14 @@ typedef struct PCIAcpiState { PCIDevice dev; uint16_t pm1_control; /* pm1a_ECNT_BLK */ + + uint32_t pm1a_evt_blk_address; } PCIAcpiState; typedef struct GPEState { /* GPE0 block */ - uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2]; - uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2]; + uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN_V0 / 2]; + uint8_t gpe0_en[ACPI_GPE0_BLK_LEN_V0 / 2]; /* CPU bitmap */ uint8_t cpus_sts[32]; @@ -88,6 +93,8 @@ typedef struct GPEState { /* SCI IRQ level */ uint8_t sci_asserted; + uint32_t gpe0_blk_address; + uint32_t gpe0_blk_half_len; } GPEState; static GPEState gpe_state; @@ -100,6 +107,9 @@ typedef struct PHPDevFn { * PSTB in ASL */ } PHPDevFn; +static void acpi_map(PCIDevice *pci_dev, int region_num, + uint32_t addr, uint32_t size, int type); + static PHPDevFn php_devfn; int s3_shutdown_flag; static qemu_irq sci_irq; @@ -138,18 +148,36 @@ static void piix4acpi_save(QEMUFile *f, void *opaque) PCIAcpiState *s = opaque; pci_device_save(&s->dev, f); qemu_put_be16s(f, &s->pm1_control); + qemu_put_be32s(f, &s->pm1a_evt_blk_address); } static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id) { PCIAcpiState *s = opaque; int ret; - if (version_id > 1) + uint32_t pm1a_evt_address_assigned; + + if (version_id > 2) return -EINVAL; ret = pci_device_load(&s->dev, f); if (ret < 0) return ret; qemu_get_be16s(f, &s->pm1_control); + + pm1a_evt_address_assigned = s->pm1a_evt_blk_address; + if (version_id <= 1) { + /* map to old ioport instead of the new one */ + s->pm1a_evt_blk_address = ACPI_PM1A_EVT_BLK_ADDRESS_V0; + } else { + qemu_get_be32s(f, &s->pm1a_evt_blk_address); + } + + if (s->pm1a_evt_blk_address != pm1a_evt_address_assigned) { + PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "ACPI: Change firmware IOPorts mapping.\n"); + /* unmap new ioport to use old ioport */ + isa_unassign_ioport(pm1a_evt_address_assigned + 4, 2); + acpi_map((PCIDevice *)s, 0, s->pm1a_evt_blk_address, 0x10, PCI_ADDRESS_SPACE_IO); + } return 0; } @@ -172,15 +200,17 @@ static void acpi_shutdown(uint32_t val) return; switch (val & SLP_TYP_Sx) { - case SLP_TYP_S3: + case SLP_TYP_S3_V0: + case SLP_TYP_S3_V1: s3_shutdown_flag = 1; qemu_system_reset(); s3_shutdown_flag = 0; cmos_set_s3_resume(); xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3); break; - case SLP_TYP_S4: - case SLP_TYP_S5: + case SLP_TYP_S4_V0: + case SLP_TYP_S5_V0: + case SLP_TYP_S5_V1: qemu_system_shutdown_request(); break; default: @@ -403,7 +433,7 @@ static uint32_t gpe_sts_read(void *opaque, uint32_t addr) { GPEState *s = opaque; - return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS]; + return s->gpe0_sts[addr - s->gpe0_blk_address]; } /* write 1 to clear specific GPE bits */ @@ -415,7 +445,7 @@ static void gpe_sts_write(void *opaque, uint32_t addr, uint32_t val) PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_sts_write: addr=0x%x, val=0x%x.\n", addr, val); hotplugged = test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT); - s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val; + s->gpe0_sts[addr - s->gpe0_blk_address] &= ~val; if ( s->sci_asserted && hotplugged && !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT)) { @@ -429,7 +459,7 @@ static uint32_t gpe_en_read(void *opaque, uint32_t addr) { GPEState *s = opaque; - return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)]; + return s->gpe0_en[addr - (s->gpe0_blk_address + s->gpe0_blk_half_len)]; } /* write 0 to clear en bit */ @@ -439,7 +469,7 @@ static void gpe_en_write(void *opaque, uint32_t addr, uint32_t val) int reg_count; PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_en_write: addr=0x%x, val=0x%x.\n", addr, val); - reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2); + reg_count = addr - (s->gpe0_blk_address + s->gpe0_blk_half_len); s->gpe0_en[reg_count] = val; /* If disable GPE bit right after generating SCI on it, * need deassert the intr to avoid redundant intrs @@ -459,7 +489,7 @@ static void gpe_save(QEMUFile* f, void* opaque) GPEState *s = (GPEState*)opaque; int i; - for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) { + for ( i = 0; i < ACPI_GPE0_BLK_LEN_V0 / 2; i++ ) { qemu_put_8s(f, &s->gpe0_sts[i]); qemu_put_8s(f, &s->gpe0_en[i]); } @@ -468,21 +498,54 @@ static void gpe_save(QEMUFile* f, void* opaque) if ( s->sci_asserted ) { PIIX4ACPI_LOG(PIIX4ACPI_LOG_INFO, "gpe_save with sci asserted!\n"); } + + qemu_put_be32s(f, &s->gpe0_blk_address); + qemu_put_be32s(f, &s->gpe0_blk_half_len); } static int gpe_load(QEMUFile* f, void* opaque, int version_id) { GPEState *s = (GPEState*)opaque; int i; - if (version_id != 1) + uint32_t gpe0_addr_assigned; + uint32_t gpe0_half_len_assigned; + + if (version_id > 2) return -EINVAL; - for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) { + for ( i = 0; i < ACPI_GPE0_BLK_LEN_V0 / 2; i++ ) { qemu_get_8s(f, &s->gpe0_sts[i]); qemu_get_8s(f, &s->gpe0_en[i]); } qemu_get_8s(f, &s->sci_asserted); + + gpe0_addr_assigned = s->gpe0_blk_address; + gpe0_half_len_assigned = s->gpe0_blk_half_len; + + if (version_id <= 1) { + s->gpe0_blk_address = ACPI_GPE0_BLK_ADDRESS_V0; + s->gpe0_blk_half_len = ACPI_GPE0_BLK_LEN_V0 / 2; + } else { + qemu_get_be32s(f, &s->gpe0_blk_address); + qemu_get_be32s(f, &s->gpe0_blk_half_len); + } + + if (gpe0_addr_assigned != s->gpe0_blk_address || + gpe0_half_len_assigned != s->gpe0_blk_half_len) { + isa_unassign_ioport(gpe0_addr_assigned, gpe0_half_len_assigned * 2); + + register_ioport_read(s->gpe0_blk_address, s->gpe0_blk_half_len, + 1, gpe_sts_read, s); + register_ioport_read(s->gpe0_blk_address + s->gpe0_blk_half_len, + s->gpe0_blk_half_len, 1, gpe_en_read, s); + + register_ioport_write(s->gpe0_blk_address, s->gpe0_blk_half_len, + 1, gpe_sts_write, s); + register_ioport_write(s->gpe0_blk_address + s->gpe0_blk_half_len, + s->gpe0_blk_half_len, 1, gpe_en_write, s); + } + return 0; } @@ -529,29 +592,32 @@ static void gpe_acpi_init(void) register_ioport_read(PROC_BASE, 32, 1, gpe_cpus_readb, s); register_ioport_write(PROC_BASE, 32, 1, gpe_cpus_writeb, s); - register_ioport_read(ACPI_GPE0_BLK_ADDRESS, - ACPI_GPE0_BLK_LEN / 2, + s->gpe0_blk_address = ACPI_GPE0_BLK_ADDRESS_V1; + s->gpe0_blk_half_len = ACPI_GPE0_BLK_LEN_V1 / 2; + + register_ioport_read(s->gpe0_blk_address, + s->gpe0_blk_half_len, 1, gpe_sts_read, s); - register_ioport_read(ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2, - ACPI_GPE0_BLK_LEN / 2, + register_ioport_read(s->gpe0_blk_address + s->gpe0_blk_half_len, + s->gpe0_blk_half_len, 1, gpe_en_read, s); - register_ioport_write(ACPI_GPE0_BLK_ADDRESS, - ACPI_GPE0_BLK_LEN / 2, + register_ioport_write(s->gpe0_blk_address, + s->gpe0_blk_half_len, 1, gpe_sts_write, s); - register_ioport_write(ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2, - ACPI_GPE0_BLK_LEN / 2, + register_ioport_write(s->gpe0_blk_address + s->gpe0_blk_half_len, + s->gpe0_blk_half_len, 1, gpe_en_write, s); - register_savevm("gpe", 0, 1, gpe_save, gpe_load, s); + register_savevm("gpe", 0, 2, gpe_save, gpe_load, s); } #ifdef CONFIG_PASSTHROUGH @@ -703,7 +769,8 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, pci_conf[0x43] = 0x00; d->pm1_control = SCI_EN; - acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO); + d->pm1a_evt_blk_address = ACPI_PM1A_EVT_BLK_ADDRESS_V1; + acpi_map((PCIDevice *)d, 0, d->pm1a_evt_blk_address, 0x10, PCI_ADDRESS_SPACE_IO); gpe_acpi_init(); #ifdef CONFIG_PASSTHROUGH @@ -711,7 +778,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, #endif register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d); - register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d); + register_savevm("piix4acpi", 0, 2, piix4acpi_save, piix4acpi_load, d); return NULL; } -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2010-Nov-09 15:52 UTC
Re: [Xen-devel] [PATCH 1/2] firmware, Change ACPI IO values to match QEMU BIOS.
Looks okay. This can be checked in at the same time as the qemu patch, plus QEMU_TAG update. Acked-by: Keir Fraser <keir@xen.org> -- Keir On 09/11/2010 15:34, "anthony.perard@citrix.com" <anthony.perard@citrix.com> wrote:> From: Anthony PERARD <anthony.perard@citrix.com> > > As part of the QEMU/Xen merge, this patch comes to change the value of > sleep states and add some information in the PCI registers to match the > implementation of the BIOS of QEMU. > > It also does a hypercall (HVM_PARAM_ACPI_IOPORTS_LOCATION) that tell the > Xen to use the new Port I/O instead of the old one. > > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> > --- > tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ > tools/firmware/hvmloader/hvmloader.c | 11 +++++++++++ > 2 files changed, 17 insertions(+), 6 deletions(-) > > diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl > b/tools/firmware/hvmloader/acpi/dsdt.asl > index 03799d3..ea8e324 100644 > --- a/tools/firmware/hvmloader/acpi/dsdt.asl > +++ b/tools/firmware/hvmloader/acpi/dsdt.asl > @@ -33,22 +33,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) > */ > Name (\_S3, Package (0x04) > { > - 0x05, /* PM1a_CNT.SLP_TYP */ > - 0x05, /* PM1b_CNT.SLP_TYP */ > + 0x01, /* PM1a_CNT.SLP_TYP */ > + 0x01, /* PM1b_CNT.SLP_TYP */ > 0x0, /* reserved */ > 0x0 /* reserved */ > }) > Name (\_S4, Package (0x04) > { > - 0x06, /* PM1a_CNT.SLP_TYP */ > - 0x06, /* PM1b_CNT.SLP_TYP */ > + 0x00, /* PM1a_CNT.SLP_TYP */ > + 0x00, /* PM1b_CNT.SLP_TYP */ > 0x00, /* reserved */ > 0x00 /* reserved */ > }) > Name (\_S5, Package (0x04) > { > - 0x07, /* PM1a_CNT.SLP_TYP */ > - 0x07, /* PM1b_CNT.SLP_TYP */ > + 0x00, /* PM1a_CNT.SLP_TYP */ > + 0x00, /* PM1b_CNT.SLP_TYP */ > 0x00, /* reserved */ > 0x00 /* reserved */ > }) > diff --git a/tools/firmware/hvmloader/hvmloader.c > b/tools/firmware/hvmloader/hvmloader.c > index c4c5ddc..bf23f80 100644 > --- a/tools/firmware/hvmloader/hvmloader.c > +++ b/tools/firmware/hvmloader/hvmloader.c > @@ -31,6 +31,7 @@ > #include "option_rom.h" > #include <xen/version.h> > #include <xen/hvm/params.h> > +#include <xen/hvm/ioreq.h> > #include <xen/memory.h> > > asm ( > @@ -222,9 +223,12 @@ static void pci_setup(void) > /* PIIX4 ACPI PM. Special device with special PCI config space. > */ > ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); > pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ > + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ > pci_writew(devfn, 0x22, 0x0000); > pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ > pci_writew(devfn, 0x3d, 0x0001); > + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS | 1); > + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ > break; > case 0x0101: > if ( vendor_id == 0x8086 ) > @@ -759,8 +763,15 @@ int main(void) > > if ( hvm_info->acpi_enabled ) > { > + struct xen_hvm_param p = { > + .domid = DOMID_SELF, > + .index = HVM_PARAM_ACPI_IOPORTS_LOCATION, > + .value = 1, > + }; > + > printf("Loading ACPI ...\n"); > acpi_build_tables(); > + hypercall_hvm_op(HVMOP_set_param, &p); > } > > init_vm86_tss();_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2010-Nov-09 18:04 UTC
Re: [Xen-devel] [PATCH 1/2] firmware, Change ACPI IO values to match QEMU BIOS.
Keir Fraser writes ("Re: [Xen-devel] [PATCH 1/2] firmware, Change ACPI IO values to match QEMU BIOS."):> Looks okay. This can be checked in at the same time as the qemu patch, plus > QEMU_TAG update. > > Acked-by: Keir Fraser <keir@xen.org>Thanks, I have indeed applied both patches and folded the QEMU_TAG update into the xen-unstable changeset. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2010-Nov-09 20:08 UTC
Re: [Xen-devel] [PATCH 1/2] firmware, Change ACPI IO values to match QEMU BIOS.
On Tue, 9 Nov 2010, Ian Jackson wrote:> Keir Fraser writes ("Re: [Xen-devel] [PATCH 1/2] firmware, Change ACPI IO values to match QEMU BIOS."): > > Looks okay. This can be checked in at the same time as the qemu patch, plus > > QEMU_TAG update. > > > > Acked-by: Keir Fraser <keir@xen.org> > > Thanks, I have indeed applied both patches and folded the QEMU_TAG > update into the xen-unstable changeset.I found that the guest use the old ioport. The FADT tables, from the firmware, gives wrong values. So a patch will follow this mail to fix the issues. -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Nov-09 20:09 UTC
[Xen-devel] [PATCH] firmware, Change in acpi static tables.
From: Anthony PERARD <anthony.perard@citrix.com> This change some fadt values -- the address of the acpi ioports -- and the pm1a_evt_address value wrote for the pci bus. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/static_tables.c | 16 ++++++++-------- tools/firmware/hvmloader/hvmloader.c | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/static_tables.c b/tools/firmware/hvmloader/acpi/static_tables.c index c263561..cf4b8dc 100644 --- a/tools/firmware/hvmloader/acpi/static_tables.c +++ b/tools/firmware/hvmloader/acpi/static_tables.c @@ -56,14 +56,14 @@ struct acpi_20_fadt Fadt = { .sci_int = 9, - .pm1a_evt_blk = ACPI_PM1A_EVT_BLK_ADDRESS, - .pm1a_cnt_blk = ACPI_PM1A_CNT_BLK_ADDRESS, - .pm_tmr_blk = ACPI_PM_TMR_BLK_ADDRESS, - .gpe0_blk = ACPI_GPE0_BLK_ADDRESS, + .pm1a_evt_blk = ACPI_PM1A_EVT_BLK_ADDRESS_V1, + .pm1a_cnt_blk = ACPI_PM1A_CNT_BLK_ADDRESS_V1, + .pm_tmr_blk = ACPI_PM_TMR_BLK_ADDRESS_V1, + .gpe0_blk = ACPI_GPE0_BLK_ADDRESS_V1, .pm1_evt_len = ACPI_PM1A_EVT_BLK_BIT_WIDTH / 8, .pm1_cnt_len = ACPI_PM1A_CNT_BLK_BIT_WIDTH / 8, .pm_tmr_len = ACPI_PM_TMR_BLK_BIT_WIDTH / 8, - .gpe0_blk_len = ACPI_GPE0_BLK_LEN, + .gpe0_blk_len = ACPI_GPE0_BLK_LEN_V1, .p_lvl2_lat = 0x0fff, /* >100, means we do not support C2 state */ .p_lvl3_lat = 0x0fff, /* >1000, means we do not support C3 state */ @@ -85,21 +85,21 @@ struct acpi_20_fadt Fadt = { .address_space_id = ACPI_SYSTEM_IO, .register_bit_width = ACPI_PM1A_EVT_BLK_BIT_WIDTH, .register_bit_offset = ACPI_PM1A_EVT_BLK_BIT_OFFSET, - .address = ACPI_PM1A_EVT_BLK_ADDRESS, + .address = ACPI_PM1A_EVT_BLK_ADDRESS_V1, }, .x_pm1a_cnt_blk = { .address_space_id = ACPI_SYSTEM_IO, .register_bit_width = ACPI_PM1A_CNT_BLK_BIT_WIDTH, .register_bit_offset = ACPI_PM1A_CNT_BLK_BIT_OFFSET, - .address = ACPI_PM1A_CNT_BLK_ADDRESS, + .address = ACPI_PM1A_CNT_BLK_ADDRESS_V1, }, .x_pm_tmr_blk = { .address_space_id = ACPI_SYSTEM_IO, .register_bit_width = ACPI_PM_TMR_BLK_BIT_WIDTH, .register_bit_offset = ACPI_PM_TMR_BLK_BIT_OFFSET, - .address = ACPI_PM_TMR_BLK_ADDRESS, + .address = ACPI_PM_TMR_BLK_ADDRESS_V1, } }; diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index bf23f80..6878674 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -227,7 +227,7 @@ static void pci_setup(void) pci_writew(devfn, 0x22, 0x0000); pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ pci_writew(devfn, 0x3d, 0x0001); - pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS | 1); + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1); pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ break; case 0x0101: -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel