From af11110bb83166473064389faa27e8c6703b2008 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 11:34:44 +0100 Subject: [PATCH 01/18] apci: switch piix4 to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 519269a013..320e045938 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -28,6 +28,7 @@ #include "range.h" #include "ioport.h" #include "fw_cfg.h" +#include "exec-memory.h" //#define DEBUG @@ -55,7 +56,7 @@ struct pci_status { typedef struct PIIX4PMState { PCIDevice dev; - IORange ioport; + MemoryRegion io; ACPIREGS ar; APMState apm; @@ -109,10 +110,10 @@ static void pm_tmr_timer(ACPIREGS *ar) pm_update_sci(s); } -static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width, - uint64_t val) +static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val, + unsigned width) { - PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport); + PIIX4PMState *s = opaque; if (width != 2) { PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n", @@ -138,10 +139,9 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width, (unsigned int)val); } -static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, - uint64_t *data) +static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width) { - PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport); + PIIX4PMState *s = opaque; uint32_t val; switch(addr) { @@ -162,12 +162,17 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, break; } PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val); - *data = val; + return val; } -static const IORangeOps pm_iorange_ops = { +static const MemoryRegionOps pm_io_ops = { .read = pm_ioport_read, .write = pm_ioport_write, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void apm_ctrl_changed(uint32_t val, void *arg) @@ -193,15 +198,13 @@ static void pm_io_space_update(PIIX4PMState *s) { uint32_t pm_io_base; - if (s->dev.config[0x80] & 1) { - pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40)); - pm_io_base &= 0xffc0; + pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40)); + pm_io_base &= 0xffc0; - /* XXX: need to improve memory and ioport allocation */ - PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base); - iorange_init(&s->ioport, &pm_iorange_ops, pm_io_base, 64); - ioport_register(&s->ioport); - } + memory_region_transaction_begin(); + memory_region_set_enabled(&s->io, s->dev.config[0x80] & 1); + memory_region_set_address(&s->io, pm_io_base); + memory_region_transaction_commit(); } static void pm_write_config(PCIDevice *d, @@ -456,6 +459,10 @@ static int piix4_pm_initfn(PCIDevice *dev) register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb); register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb); + memory_region_init_io(&s->io, &pm_io_ops, s, "piix4-pm", 64); + memory_region_set_enabled(&s->io, false); + memory_region_add_subregion(get_system_io(), 0, &s->io); + acpi_pm_tmr_init(&s->ar, pm_tmr_timer); acpi_gpe_init(&s->ar, GPE_LEN); From cacaab8bdd74608361a488aac600d609dafd53e5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 12:08:22 +0100 Subject: [PATCH 02/18] apci: switch ich9 to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_ich9.c | 44 +++++++++++++++++++++++++++----------------- hw/acpi_ich9.h | 1 + 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index 61034d3bd7..bf361ece5d 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -29,6 +29,7 @@ #include "sysemu.h" #include "acpi.h" #include "kvm.h" +#include "exec-memory.h" #include "ich9.h" @@ -217,30 +218,34 @@ static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len) return val; } +static const MemoryRegionOps pm_io_ops = { + .old_portio = (MemoryRegionPortio[]) { + { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 1, + .read = pm_ioport_readb, .write = pm_ioport_writeb }, + { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 2, + .read = pm_ioport_readw, .write = pm_ioport_writew }, + { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 4, + .read = pm_ioport_readl, .write = pm_ioport_writel }, + PORTIO_END_OF_LIST(), + }, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base) { ICH9_DEBUG("to 0x%x\n", pm_io_base); assert((pm_io_base & ICH9_PMIO_MASK) == 0); - if (pm->pm_io_base != 0) { - isa_unassign_ioport(pm->pm_io_base, ICH9_PMIO_SIZE); - } - - /* don't map at 0 */ - if (pm_io_base == 0) { - return; - } - - register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 1, pm_ioport_writeb, pm); - register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 1, pm_ioport_readb, pm); - register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 2, pm_ioport_writew, pm); - register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 2, pm_ioport_readw, pm); - register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_writel, pm); - register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_readl, pm); - pm->pm_io_base = pm_io_base; - acpi_gpe_blk(&pm->acpi_regs, pm_io_base + ICH9_PMIO_GPE0_STS); + memory_region_transaction_begin(); + memory_region_set_enabled(&pm->io, pm->pm_io_base != 0); + memory_region_set_address(&pm->io, pm->pm_io_base); + memory_region_transaction_commit(); } static int ich9_pm_post_load(void *opaque, int version_id) @@ -311,9 +316,14 @@ static void pm_powerdown_req(Notifier *n, void *opaque) void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) { + memory_region_init_io(&pm->io, &pm_io_ops, pm, "ich9-pm", ICH9_PMIO_SIZE); + memory_region_set_enabled(&pm->io, false); + memory_region_add_subregion(get_system_io(), 0, &pm->io); + acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn); acpi_pm1_cnt_init(&pm->acpi_regs); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); + acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS); pm->irq = sci_irq; qemu_register_reset(pm_reset, pm); diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h index 180c40673b..0a2ee6c83d 100644 --- a/hw/acpi_ich9.h +++ b/hw/acpi_ich9.h @@ -30,6 +30,7 @@ typedef struct ICH9LPCPMRegs { * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t. */ ACPIREGS acpi_regs; + MemoryRegion io; uint32_t smi_en; uint32_t smi_sts; From a29028214c1d5d3571b27e6745f14534e6d8a662 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 08:29:27 +0100 Subject: [PATCH 03/18] apci: switch vt82c686 to memory api Signed-off-by: Gerd Hoffmann --- hw/vt82c686.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 5d7c00cf4b..3fc6063d7d 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -24,6 +24,7 @@ #include "pm_smbus.h" #include "sysemu.h" #include "qemu-timer.h" +#include "exec-memory.h" typedef uint32_t pci_addr_t; #include "pci_host.h" @@ -159,6 +160,7 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address, typedef struct VT686PMState { PCIDevice dev; + MemoryRegion io; ACPIREGS ar; APMState apm; PMSMBus smb; @@ -266,21 +268,32 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) return val; } +static const MemoryRegionOps pm_io_ops = { + .old_portio = (MemoryRegionPortio[]) { + { .offset = 0, .len = 64, .size = 2, + .read = pm_ioport_readw, .write = pm_ioport_writew }, + { .offset = 0, .len = 64, .size = 4, + .read = pm_ioport_readl, .write = pm_ioport_writel }, + PORTIO_END_OF_LIST(), + }, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void pm_io_space_update(VT686PMState *s) { uint32_t pm_io_base; - if (s->dev.config[0x80] & 1) { - pm_io_base = pci_get_long(s->dev.config + 0x40); - pm_io_base &= 0xffc0; + pm_io_base = pci_get_long(s->dev.config + 0x40); + pm_io_base &= 0xffc0; - /* XXX: need to improve memory and ioport allocation */ - DPRINTF("PM: mapping to 0x%x\n", pm_io_base); - register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s); - register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s); - register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s); - register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s); - } + memory_region_transaction_begin(); + memory_region_set_enabled(&s->io, s->dev.config[0x80] & 1); + memory_region_set_address(&s->io, pm_io_base); + memory_region_transaction_commit(); } static void pm_write_config(PCIDevice *d, @@ -429,6 +442,10 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) apm_init(&s->apm, NULL, s); + memory_region_init_io(&s->io, &pm_io_ops, s, "vt82c686-pm", 64); + memory_region_set_enabled(&s->io, false); + memory_region_add_subregion(get_system_io(), 0, &s->io); + acpi_pm_tmr_init(&s->ar, pm_tmr_timer); acpi_pm1_cnt_init(&s->ar); From 77d58b1e47c8d1c661f98f12b47ab519d3561488 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 12:12:30 +0100 Subject: [PATCH 04/18] apci: switch timer to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi.c | 19 +++++++++++++++++-- hw/acpi.h | 5 +++-- hw/acpi_ich9.c | 5 +---- hw/acpi_piix4.c | 5 +---- hw/vt82c686.c | 6 +----- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index f4aca493fc..ba25c23bed 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -331,7 +331,7 @@ void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar) ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL; } -uint32_t acpi_pm_tmr_get(ACPIREGS *ar) +static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) { uint32_t d = acpi_pm_tmr_get_clock(); return d & 0xffffff; @@ -344,10 +344,25 @@ static void acpi_pm_tmr_timer(void *opaque) ar->tmr.update_sci(ar); } -void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci) +static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) +{ + return acpi_pm_tmr_get(opaque); +} + +static const MemoryRegionOps acpi_pm_tmr_ops = { + .read = acpi_pm_tmr_read, + .valid.min_access_size = 4, + .valid.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, + MemoryRegion *parent) { ar->tmr.update_sci = update_sci; ar->tmr.timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, ar); + memory_region_init_io(&ar->tmr.io, &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); + memory_region_add_subregion(parent, 8, &ar->tmr.io); } void acpi_pm_tmr_reset(ACPIREGS *ar) diff --git a/hw/acpi.h b/hw/acpi.h index 7337f41857..91f42c3db1 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -84,6 +84,7 @@ typedef void (*acpi_update_sci_fn)(ACPIREGS *ar); struct ACPIPMTimer { QEMUTimer *timer; + MemoryRegion io; int64_t overflow_time; acpi_update_sci_fn update_sci; @@ -119,8 +120,8 @@ struct ACPIREGS { /* PM_TMR */ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable); void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar); -uint32_t acpi_pm_tmr_get(ACPIREGS *ar); -void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci); +void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, + MemoryRegion *parent); void acpi_pm_tmr_reset(ACPIREGS *ar); #include "qemu-timer.h" diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index bf361ece5d..ec6d5f2b5a 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -170,9 +170,6 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) uint32_t val; switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_PM1_TMR: - val = acpi_pm_tmr_get(&pm->acpi_regs); - break; case ICH9_PMIO_SMI_EN: val = pm->smi_en; break; @@ -320,7 +317,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) memory_region_set_enabled(&pm->io, false); memory_region_add_subregion(get_system_io(), 0, &pm->io); - acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn); + acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); acpi_pm1_cnt_init(&pm->acpi_regs); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS); diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 320e045938..75761a08a7 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -154,9 +154,6 @@ static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width) case 0x04: val = s->ar.pm1.cnt.cnt; break; - case 0x08: - val = acpi_pm_tmr_get(&s->ar); - break; default: val = 0; break; @@ -463,7 +460,7 @@ static int piix4_pm_initfn(PCIDevice *dev) memory_region_set_enabled(&s->io, false); memory_region_add_subregion(get_system_io(), 0, &s->io); - acpi_pm_tmr_init(&s->ar, pm_tmr_timer); + acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); acpi_gpe_init(&s->ar, GPE_LEN); s->powerdown_notifier.notify = piix4_pm_powerdown_req; diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 3fc6063d7d..219cfaec72 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -252,14 +252,10 @@ static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val) static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) { - VT686PMState *s = opaque; uint32_t val; addr &= 0x0f; switch (addr) { - case 0x08: - val = acpi_pm_tmr_get(&s->ar); - break; default: val = 0; break; @@ -446,7 +442,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) memory_region_set_enabled(&s->io, false); memory_region_add_subregion(get_system_io(), 0, &s->io); - acpi_pm_tmr_init(&s->ar, pm_tmr_timer); + acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar); pm_smbus_init(&s->dev.qdev, &s->smb); From afafe4bbe0cf7d3318e1ac7b40925561f86a6bd4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 13:17:57 +0100 Subject: [PATCH 05/18] apci: switch cnt to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi.c | 38 ++++++++++++++++++++++++++++++-------- hw/acpi.h | 5 +++-- hw/acpi_ich9.c | 8 +------- hw/acpi_piix4.c | 8 +------- hw/vt82c686.c | 8 +------- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index ba25c23bed..956db95be4 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -372,13 +372,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar) } /* ACPI PM1aCNT */ -void acpi_pm1_cnt_init(ACPIREGS *ar) -{ - ar->wakeup.notify = acpi_notify_wakeup; - qemu_register_wakeup_notifier(&ar->wakeup); -} - -void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4) +static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) { ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); @@ -393,7 +387,7 @@ void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4) qemu_system_suspend_request(); break; default: - if (sus_typ == s4) { /* S4 request */ + if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ monitor_protocol_event(QEVENT_SUSPEND_DISK, NULL); qemu_system_shutdown_request(); } @@ -413,6 +407,34 @@ void acpi_pm1_cnt_update(ACPIREGS *ar, } } +static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) +{ + ACPIREGS *ar = opaque; + return ar->pm1.cnt.cnt; +} + +static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, + unsigned width) +{ + acpi_pm1_cnt_write(opaque, val); +} + +static const MemoryRegionOps acpi_pm_cnt_ops = { + .read = acpi_pm_cnt_read, + .write = acpi_pm_cnt_write, + .valid.min_access_size = 2, + .valid.max_access_size = 2, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent) +{ + ar->wakeup.notify = acpi_notify_wakeup; + qemu_register_wakeup_notifier(&ar->wakeup); + memory_region_init_io(&ar->pm1.cnt.io, &acpi_pm_cnt_ops, ar, "acpi-cnt", 2); + memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io); +} + void acpi_pm1_cnt_reset(ACPIREGS *ar) { ar->pm1.cnt.cnt = 0; diff --git a/hw/acpi.h b/hw/acpi.h index 91f42c3db1..97aaab847c 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -96,7 +96,9 @@ struct ACPIPM1EVT { }; struct ACPIPM1CNT { + MemoryRegion io; uint16_t cnt; + uint8_t s4_val; }; struct ACPIGPE { @@ -139,8 +141,7 @@ void acpi_pm1_evt_power_down(ACPIREGS *ar); void acpi_pm1_evt_reset(ACPIREGS *ar); /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */ -void acpi_pm1_cnt_init(ACPIREGS *ar); -void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4); +void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent); void acpi_pm1_cnt_update(ACPIREGS *ar, bool sci_enable, bool sci_disable); void acpi_pm1_cnt_reset(ACPIREGS *ar); diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index ec6d5f2b5a..7b6c2ef4dc 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -116,9 +116,6 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) pm->acpi_regs.pm1.evt.en = val; pm_update_sci(pm); break; - case ICH9_PMIO_PM1_CNT: - acpi_pm1_cnt_write(&pm->acpi_regs, val, 0); - break; default: pm_ioport_write_fallback(opaque, addr, 2, val); break; @@ -138,9 +135,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) case ICH9_PMIO_PM1_EN: val = pm->acpi_regs.pm1.evt.en; break; - case ICH9_PMIO_PM1_CNT: - val = pm->acpi_regs.pm1.cnt.cnt; - break; default: val = pm_ioport_read_fallback(opaque, addr, 2); break; @@ -318,7 +312,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) memory_region_add_subregion(get_system_io(), 0, &pm->io); acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); - acpi_pm1_cnt_init(&pm->acpi_regs); + acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS); diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 75761a08a7..9d5e346ef3 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -129,9 +129,6 @@ static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val, acpi_pm1_evt_write_en(&s->ar, val); pm_update_sci(s); break; - case 0x04: - acpi_pm1_cnt_write(&s->ar, val, s->s4_val); - break; default: break; } @@ -151,9 +148,6 @@ static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width) case 0x02: val = s->ar.pm1.evt.en; break; - case 0x04: - val = s->ar.pm1.cnt.cnt; - break; default: val = 0; break; @@ -461,6 +455,7 @@ static int piix4_pm_initfn(PCIDevice *dev) memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); + acpi_pm1_cnt_init(&s->ar, &s->io); acpi_gpe_init(&s->ar, GPE_LEN); s->powerdown_notifier.notify = piix4_pm_powerdown_req; @@ -487,7 +482,6 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, s = DO_UPCAST(PIIX4PMState, dev, dev); s->irq = sci_irq; - acpi_pm1_cnt_init(&s->ar); s->smi_irq = smi_irq; s->kvm_enabled = kvm_enabled; diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 219cfaec72..15f0b6a91c 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -211,9 +211,6 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) acpi_pm1_evt_write_en(&s->ar, val); pm_update_sci(s); break; - case 0x04: - acpi_pm1_cnt_write(&s->ar, val, 0); - break; default: break; } @@ -233,9 +230,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) case 0x02: val = s->ar.pm1.evt.en; break; - case 0x04: - val = s->ar.pm1.cnt.cnt; - break; default: val = 0; break; @@ -443,7 +437,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); - acpi_pm1_cnt_init(&s->ar); + acpi_pm1_cnt_init(&s->ar, &s->io); pm_smbus_init(&s->dev.qdev, &s->smb); From b5a7c024d2606e84e0bbe4a0e87d252dfda41479 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 13:25:10 +0100 Subject: [PATCH 06/18] apci: switch evt to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- hw/acpi.h | 6 ++++-- hw/acpi_ich9.c | 18 +----------------- hw/acpi_piix4.c | 18 +----------------- hw/vt82c686.c | 18 +----------------- 5 files changed, 54 insertions(+), 55 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index 956db95be4..e58e45f301 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -275,7 +275,7 @@ uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar) return ar->pm1.evt.sts; } -void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) +static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) { uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { @@ -285,7 +285,7 @@ void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) ar->pm1.evt.sts &= ~val; } -void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) +static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) { ar->pm1.evt.en = val; qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, @@ -310,6 +310,51 @@ void acpi_pm1_evt_reset(ACPIREGS *ar) qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, 0); } +static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) +{ + ACPIREGS *ar = opaque; + switch (addr) { + case 0: + return acpi_pm1_evt_get_sts(ar); + case 2: + return ar->pm1.evt.en; + default: + return 0; + } +} + +static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, + unsigned width) +{ + ACPIREGS *ar = opaque; + switch (addr) { + case 0: + acpi_pm1_evt_write_sts(ar, val); + ar->pm1.evt.update_sci(ar); + break; + case 2: + acpi_pm1_evt_write_en(ar, val); + ar->pm1.evt.update_sci(ar); + break; + } +} + +static const MemoryRegionOps acpi_pm_evt_ops = { + .read = acpi_pm_evt_read, + .write = acpi_pm_evt_write, + .valid.min_access_size = 2, + .valid.max_access_size = 2, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, + MemoryRegion *parent) +{ + ar->pm1.evt.update_sci = update_sci; + memory_region_init_io(&ar->pm1.evt.io, &acpi_pm_evt_ops, ar, "acpi-evt", 4); + memory_region_add_subregion(parent, 0, &ar->pm1.evt.io); +} + /* ACPI PM_TMR */ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable) { diff --git a/hw/acpi.h b/hw/acpi.h index 97aaab847c..918d7f5bca 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -91,8 +91,10 @@ struct ACPIPMTimer { }; struct ACPIPM1EVT { + MemoryRegion io; uint16_t sts; uint16_t en; + acpi_update_sci_fn update_sci; }; struct ACPIPM1CNT { @@ -135,10 +137,10 @@ static inline int64_t acpi_pm_tmr_get_clock(void) /* PM1a_EVT: piix and ich9 don't implement PM1b. */ uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar); -void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val); -void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val); void acpi_pm1_evt_power_down(ACPIREGS *ar); void acpi_pm1_evt_reset(ACPIREGS *ar); +void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, + MemoryRegion *parent); /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */ void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent); diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index 7b6c2ef4dc..3b5bac6d49 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -105,17 +105,7 @@ static uint32_t pm_ioport_readb(void *opaque, uint32_t addr) static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) { - ICH9LPCPMRegs *pm = opaque; - switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_PM1_STS: - acpi_pm1_evt_write_sts(&pm->acpi_regs, val); - pm_update_sci(pm); - break; - case ICH9_PMIO_PM1_EN: - pm->acpi_regs.pm1.evt.en = val; - pm_update_sci(pm); - break; default: pm_ioport_write_fallback(opaque, addr, 2, val); break; @@ -125,16 +115,9 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) { - ICH9LPCPMRegs *pm = opaque; uint32_t val; switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_PM1_STS: - val = acpi_pm1_evt_get_sts(&pm->acpi_regs); - break; - case ICH9_PMIO_PM1_EN: - val = pm->acpi_regs.pm1.evt.en; - break; default: val = pm_ioport_read_fallback(opaque, addr, 2); break; @@ -312,6 +295,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) memory_region_add_subregion(get_system_io(), 0, &pm->io); acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); + acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS); diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 9d5e346ef3..d4e28c4fff 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -113,22 +113,12 @@ static void pm_tmr_timer(ACPIREGS *ar) static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val, unsigned width) { - PIIX4PMState *s = opaque; - if (width != 2) { PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n", (unsigned)addr, width, (unsigned)val); } switch(addr) { - case 0x00: - acpi_pm1_evt_write_sts(&s->ar, val); - pm_update_sci(s); - break; - case 0x02: - acpi_pm1_evt_write_en(&s->ar, val); - pm_update_sci(s); - break; default: break; } @@ -138,16 +128,9 @@ static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val, static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width) { - PIIX4PMState *s = opaque; uint32_t val; switch(addr) { - case 0x00: - val = acpi_pm1_evt_get_sts(&s->ar); - break; - case 0x02: - val = s->ar.pm1.evt.en; - break; default: val = 0; break; @@ -455,6 +438,7 @@ static int piix4_pm_initfn(PCIDevice *dev) memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); + acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar, &s->io); acpi_gpe_init(&s->ar, GPE_LEN); diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 15f0b6a91c..52f46f10ce 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -199,18 +199,8 @@ static void pm_tmr_timer(ACPIREGS *ar) static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) { - VT686PMState *s = opaque; - addr &= 0x0f; switch (addr) { - case 0x00: - acpi_pm1_evt_write_sts(&s->ar, val); - pm_update_sci(s); - break; - case 0x02: - acpi_pm1_evt_write_en(&s->ar, val); - pm_update_sci(s); - break; default: break; } @@ -219,17 +209,10 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) { - VT686PMState *s = opaque; uint32_t val; addr &= 0x0f; switch (addr) { - case 0x00: - val = acpi_pm1_evt_get_sts(&s->ar); - break; - case 0x02: - val = s->ar.pm1.evt.en; - break; default: val = 0; break; @@ -437,6 +420,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); + acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar, &s->io); pm_smbus_init(&s->dev.qdev, &s->smb); From ca5d64b4b4fbb01e403f89ec9b399aaa69104b1e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 13:27:04 +0100 Subject: [PATCH 07/18] acpi: cleanup piix4 memory region Nothing left to do, everything handled by subregions, we can zap the reaw/write handlers now. Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index d4e28c4fff..cf8aa3d7d7 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -110,45 +110,6 @@ static void pm_tmr_timer(ACPIREGS *ar) pm_update_sci(s); } -static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val, - unsigned width) -{ - if (width != 2) { - PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n", - (unsigned)addr, width, (unsigned)val); - } - - switch(addr) { - default: - break; - } - PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", (unsigned int)addr, - (unsigned int)val); -} - -static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width) -{ - uint32_t val; - - switch(addr) { - default: - val = 0; - break; - } - PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val); - return val; -} - -static const MemoryRegionOps pm_io_ops = { - .read = pm_ioport_read, - .write = pm_ioport_write, - .valid.min_access_size = 1, - .valid.max_access_size = 4, - .impl.min_access_size = 1, - .impl.max_access_size = 4, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - static void apm_ctrl_changed(uint32_t val, void *arg) { PIIX4PMState *s = arg; @@ -433,7 +394,7 @@ static int piix4_pm_initfn(PCIDevice *dev) register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb); register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb); - memory_region_init_io(&s->io, &pm_io_ops, s, "piix4-pm", 64); + memory_region_init(&s->io, "piix4-pm", 64); memory_region_set_enabled(&s->io, false); memory_region_add_subregion(get_system_io(), 0, &s->io); From a0f95659da77c8818ebd146bb1546ad152d0833e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 09:00:25 +0100 Subject: [PATCH 08/18] acpi: cleanup vt82c686 memory region Nothing left to do, everything handled by subregions, we can zap the reaw/write handlers now. Signed-off-by: Gerd Hoffmann --- hw/vt82c686.c | 61 +-------------------------------------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 52f46f10ce..99e6b2f9a9 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -197,65 +197,6 @@ static void pm_tmr_timer(ACPIREGS *ar) pm_update_sci(s); } -static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) -{ - addr &= 0x0f; - switch (addr) { - default: - break; - } - DPRINTF("PM writew port=0x%04x val=0x%02x\n", addr, val); -} - -static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) -{ - uint32_t val; - - addr &= 0x0f; - switch (addr) { - default: - val = 0; - break; - } - DPRINTF("PM readw port=0x%04x val=0x%02x\n", addr, val); - return val; -} - -static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val) -{ - addr &= 0x0f; - DPRINTF("PM writel port=0x%04x val=0x%08x\n", addr, val); -} - -static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) -{ - uint32_t val; - - addr &= 0x0f; - switch (addr) { - default: - val = 0; - break; - } - DPRINTF("PM readl port=0x%04x val=0x%08x\n", addr, val); - return val; -} - -static const MemoryRegionOps pm_io_ops = { - .old_portio = (MemoryRegionPortio[]) { - { .offset = 0, .len = 64, .size = 2, - .read = pm_ioport_readw, .write = pm_ioport_writew }, - { .offset = 0, .len = 64, .size = 4, - .read = pm_ioport_readl, .write = pm_ioport_writel }, - PORTIO_END_OF_LIST(), - }, - .valid.min_access_size = 1, - .valid.max_access_size = 4, - .impl.min_access_size = 1, - .impl.max_access_size = 4, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - static void pm_io_space_update(VT686PMState *s) { uint32_t pm_io_base; @@ -415,7 +356,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) apm_init(&s->apm, NULL, s); - memory_region_init_io(&s->io, &pm_io_ops, s, "vt82c686-pm", 64); + memory_region_init(&s->io, "vt82c686-pm", 64); memory_region_set_enabled(&s->io, false); memory_region_add_subregion(get_system_io(), 0, &s->io); From 76a7daf97458c55b8d8e6d4eadc5c46b16c705ce Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 13:43:17 +0100 Subject: [PATCH 09/18] apci: switch ich9 gpe to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_ich9.c | 38 ++++++++++++++++++++++++++++---------- hw/acpi_ich9.h | 1 + 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index 3b5bac6d49..5fc160a971 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -73,12 +73,7 @@ static void ich9_pm_update_sci_fn(ACPIREGS *regs) static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) { - ICH9LPCPMRegs *pm = opaque; - switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1): - acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); - break; default: break; } @@ -88,13 +83,9 @@ static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) static uint32_t pm_ioport_readb(void *opaque, uint32_t addr) { - ICH9LPCPMRegs *pm = opaque; uint32_t val = 0; switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1): - val = acpi_gpe_ioport_readb(&pm->acpi_regs, addr); - break; default: val = 0; break; @@ -209,6 +200,29 @@ static const MemoryRegionOps pm_io_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width) +{ + ICH9LPCPMRegs *pm = opaque; + return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); +} + +static void ich9_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, + unsigned width) +{ + ICH9LPCPMRegs *pm = opaque; + acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); +} + +static const MemoryRegionOps ich9_gpe_ops = { + .read = ich9_gpe_readb, + .write = ich9_gpe_writeb, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 1, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base) { ICH9_DEBUG("to 0x%x\n", pm_io_base); @@ -297,8 +311,12 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io); + acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); - acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS); + acpi_gpe_blk(&pm->acpi_regs, 0); + memory_region_init_io(&pm->io_gpe, &ich9_gpe_ops, pm, "apci-gpe0", + ICH9_PMIO_GPE0_LEN); + memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe); pm->irq = sci_irq; qemu_register_reset(pm_reset, pm); diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h index 0a2ee6c83d..f3b05d7229 100644 --- a/hw/acpi_ich9.h +++ b/hw/acpi_ich9.h @@ -31,6 +31,7 @@ typedef struct ICH9LPCPMRegs { */ ACPIREGS acpi_regs; MemoryRegion io; + MemoryRegion io_gpe; uint32_t smi_en; uint32_t smi_sts; From 10cc69b0de8e1756e6fbda4592c9d0ba3bce58fc Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 13:51:35 +0100 Subject: [PATCH 10/18] apci: switch ich9 smi to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_ich9.c | 46 ++++++++++++++++++++++++++++++++++++---------- hw/acpi_ich9.h | 1 + 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index 5fc160a971..0ed17da1eb 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -119,12 +119,7 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val) { - ICH9LPCPMRegs *pm = opaque; - switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_SMI_EN: - pm->smi_en = val; - break; default: pm_ioport_write_fallback(opaque, addr, 4, val); break; @@ -134,14 +129,9 @@ static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val) static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) { - ICH9LPCPMRegs *pm = opaque; uint32_t val; switch (addr & ICH9_PMIO_MASK) { - case ICH9_PMIO_SMI_EN: - val = pm->smi_en; - break; - default: val = pm_ioport_read_fallback(opaque, addr, 4); break; @@ -223,6 +213,38 @@ static const MemoryRegionOps ich9_gpe_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static uint64_t ich9_smi_readl(void *opaque, hwaddr addr, unsigned width) +{ + ICH9LPCPMRegs *pm = opaque; + switch (addr) { + case 0: + return pm->smi_en; + case 4: + return pm->smi_sts; + default: + return 0; + } +} + +static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val, + unsigned width) +{ + ICH9LPCPMRegs *pm = opaque; + switch (addr) { + case 0: + pm->smi_en = val; + break; + } +} + +static const MemoryRegionOps ich9_smi_ops = { + .read = ich9_smi_readl, + .write = ich9_smi_writel, + .valid.min_access_size = 4, + .valid.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base) { ICH9_DEBUG("to 0x%x\n", pm_io_base); @@ -318,6 +340,10 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) ICH9_PMIO_GPE0_LEN); memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe); + memory_region_init_io(&pm->io_smi, &ich9_smi_ops, pm, "apci-smi", + 8); + memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi); + pm->irq = sci_irq; qemu_register_reset(pm_reset, pm); pm->powerdown_notifier.notify = pm_powerdown_req; diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h index f3b05d7229..bc221d3cbc 100644 --- a/hw/acpi_ich9.h +++ b/hw/acpi_ich9.h @@ -32,6 +32,7 @@ typedef struct ICH9LPCPMRegs { ACPIREGS acpi_regs; MemoryRegion io; MemoryRegion io_gpe; + MemoryRegion io_smi; uint32_t smi_en; uint32_t smi_sts; From 4a522de0905c88160b6f93eb5d35883382a0c333 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 22 Nov 2012 14:01:20 +0100 Subject: [PATCH 11/18] acpi: cleanup ich9 memory region Nothing left to do, everything handled by subregions, we can zap the reaw/write handlers now. Signed-off-by: Gerd Hoffmann --- hw/acpi_ich9.c | 125 +------------------------------------------------ 1 file changed, 1 insertion(+), 124 deletions(-) diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index 0ed17da1eb..db0d7a5063 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -42,10 +42,6 @@ do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0) #define ICH9_DEBUG(fmt, ...) do { } while (0) #endif -static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len, - uint32_t val); -static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len); - static void pm_update_sci(ICH9LPCPMRegs *pm) { int sci_level, pm1a_sts; @@ -71,125 +67,6 @@ static void ich9_pm_update_sci_fn(ACPIREGS *regs) pm_update_sci(pm); } -static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) -{ - switch (addr & ICH9_PMIO_MASK) { - default: - break; - } - - ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); -} - -static uint32_t pm_ioport_readb(void *opaque, uint32_t addr) -{ - uint32_t val = 0; - - switch (addr & ICH9_PMIO_MASK) { - default: - val = 0; - break; - } - ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); - return val; -} - -static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) -{ - switch (addr & ICH9_PMIO_MASK) { - default: - pm_ioport_write_fallback(opaque, addr, 2, val); - break; - } - ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); -} - -static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) -{ - uint32_t val; - - switch (addr & ICH9_PMIO_MASK) { - default: - val = pm_ioport_read_fallback(opaque, addr, 2); - break; - } - ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); - return val; -} - -static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val) -{ - switch (addr & ICH9_PMIO_MASK) { - default: - pm_ioport_write_fallback(opaque, addr, 4, val); - break; - } - ICH9_DEBUG("port=0x%04x val=0x%08x\n", addr, val); -} - -static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) -{ - uint32_t val; - - switch (addr & ICH9_PMIO_MASK) { - default: - val = pm_ioport_read_fallback(opaque, addr, 4); - break; - } - ICH9_DEBUG("port=0x%04x val=0x%08x\n", addr, val); - return val; -} - -static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len, - uint32_t val) - { - int subsize = (len == 4) ? 2 : 1; - IOPortWriteFunc *ioport_write = - (subsize == 2) ? pm_ioport_writew : pm_ioport_writeb; - - int i; - - for (i = 0; i < len; i += subsize) { - ioport_write(opaque, addr, val); - val >>= 8 * subsize; - } -} - -static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len) -{ - int subsize = (len == 4) ? 2 : 1; - IOPortReadFunc *ioport_read = - (subsize == 2) ? pm_ioport_readw : pm_ioport_readb; - - uint32_t val; - int i; - - val = 0; - for (i = 0; i < len; i += subsize) { - val <<= 8 * subsize; - val |= ioport_read(opaque, addr); - } - - return val; -} - -static const MemoryRegionOps pm_io_ops = { - .old_portio = (MemoryRegionPortio[]) { - { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 1, - .read = pm_ioport_readb, .write = pm_ioport_writeb }, - { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 2, - .read = pm_ioport_readw, .write = pm_ioport_writew }, - { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 4, - .read = pm_ioport_readl, .write = pm_ioport_writel }, - PORTIO_END_OF_LIST(), - }, - .valid.min_access_size = 1, - .valid.max_access_size = 4, - .impl.min_access_size = 1, - .impl.max_access_size = 4, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width) { ICH9LPCPMRegs *pm = opaque; @@ -326,7 +203,7 @@ static void pm_powerdown_req(Notifier *n, void *opaque) void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) { - memory_region_init_io(&pm->io, &pm_io_ops, pm, "ich9-pm", ICH9_PMIO_SIZE); + memory_region_init(&pm->io, "ich9-pm", ICH9_PMIO_SIZE); memory_region_set_enabled(&pm->io, false); memory_region_add_subregion(get_system_io(), 0, &pm->io); From 798512e5522685163c8d5fc5093aea19ae9cce06 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 14:57:01 +0100 Subject: [PATCH 12/18] acpi: switch smbus to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 5 ++--- hw/pm_smbus.c | 17 ++++++++++++---- hw/pm_smbus.h | 3 +-- hw/smbus_ich9.c | 52 ++++++++++++++----------------------------------- hw/vt82c686.c | 6 ++---- 5 files changed, 33 insertions(+), 50 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index cf8aa3d7d7..9e6c97ebd3 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -391,8 +391,8 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x09; - register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb); - register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb); + pm_smbus_init(&s->dev.qdev, &s->smb); + memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io); memory_region_init(&s->io, "piix4-pm", 64); memory_region_set_enabled(&s->io, false); @@ -406,7 +406,6 @@ static int piix4_pm_initfn(PCIDevice *dev) s->powerdown_notifier.notify = piix4_pm_powerdown_req; qemu_register_powerdown_notifier(&s->powerdown_notifier); - pm_smbus_init(&s->dev.qdev, &s->smb); s->machine_ready.notify = piix4_pm_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); qemu_register_reset(piix4_reset, s); diff --git a/hw/pm_smbus.c b/hw/pm_smbus.c index 5d6046de5a..ea1380ca68 100644 --- a/hw/pm_smbus.c +++ b/hw/pm_smbus.c @@ -94,10 +94,11 @@ static void smb_transaction(PMSMBus *s) s->smb_stat |= 0x04; } -void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) +static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val, + unsigned width) { PMSMBus *s = opaque; - addr &= 0x3f; + SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val); switch(addr) { case SMBHSTSTS: @@ -131,12 +132,11 @@ void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) } } -uint32_t smb_ioport_readb(void *opaque, uint32_t addr) +static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width) { PMSMBus *s = opaque; uint32_t val; - addr &= 0x3f; switch(addr) { case SMBHSTSTS: val = s->smb_stat; @@ -170,7 +170,16 @@ uint32_t smb_ioport_readb(void *opaque, uint32_t addr) return val; } +static const MemoryRegionOps pm_smbus_ops = { + .read = smb_ioport_readb, + .write = smb_ioport_writeb, + .valid.min_access_size = 1, + .valid.max_access_size = 1, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + void pm_smbus_init(DeviceState *parent, PMSMBus *smb) { smb->smbus = i2c_init_bus(parent, "i2c"); + memory_region_init_io(&smb->io, &pm_smbus_ops, smb, "pm-smbus", 64); } diff --git a/hw/pm_smbus.h b/hw/pm_smbus.h index 4750a409f9..e3069bf7d4 100644 --- a/hw/pm_smbus.h +++ b/hw/pm_smbus.h @@ -3,6 +3,7 @@ typedef struct PMSMBus { i2c_bus *smbus; + MemoryRegion io; uint8_t smb_stat; uint8_t smb_ctl; @@ -15,7 +16,5 @@ typedef struct PMSMBus { } PMSMBus; void pm_smbus_init(DeviceState *parent, PMSMBus *smb); -void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val); -uint32_t smb_ioport_readb(void *opaque, uint32_t addr); #endif /* !PM_SMBUS_H */ diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c index 6940583bb6..54e7e1252d 100644 --- a/hw/smbus_ich9.c +++ b/hw/smbus_ich9.c @@ -40,7 +40,6 @@ typedef struct ICH9SMBState { PCIDevice dev; PMSMBus smb; - MemoryRegion mem_bar; } ICH9SMBState; static const VMStateDescription vmstate_ich9_smbus = { @@ -54,42 +53,23 @@ static const VMStateDescription vmstate_ich9_smbus = { } }; -static void ich9_smb_ioport_writeb(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static void ich9_smbus_write_config(PCIDevice *d, uint32_t address, + uint32_t val, int len) { - ICH9SMBState *s = opaque; - uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC]; + ICH9SMBState *s = ICH9_SMB_DEVICE(d); - if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { - uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr; - smb_ioport_writeb(&s->smb, offset, val); + pci_default_write_config(d, address, val, len); + if (range_covers_byte(address, len, ICH9_SMB_HOSTC)) { + uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC]; + if ((hostc & ICH9_SMB_HOSTC_HST_EN) && + !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { + memory_region_set_enabled(&s->smb.io, true); + } else { + memory_region_set_enabled(&s->smb.io, false); + } } } -static uint64_t ich9_smb_ioport_readb(void *opaque, hwaddr addr, - unsigned size) -{ - ICH9SMBState *s = opaque; - uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC]; - - if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { - uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr; - return smb_ioport_readb(&s->smb, offset); - } - - return 0xff; -} - -static const MemoryRegionOps lpc_smb_mmio_ops = { - .read = ich9_smb_ioport_readb, - .write = ich9_smb_ioport_writeb, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, -}; - static int ich9_smbus_initfn(PCIDevice *d) { ICH9SMBState *s = ICH9_SMB_DEVICE(d); @@ -109,15 +89,12 @@ static int ich9_smbus_initfn(PCIDevice *d) * Is there any OS that depends on them? */ - /* TODO smb_io_base */ pci_set_byte(d->config + ICH9_SMB_HOSTC, 0); /* TODO bar0, bar1: 64bit BAR support*/ - memory_region_init_io(&s->mem_bar, &lpc_smb_mmio_ops, s, "ich9-smbus-bar", - ICH9_SMB_SMB_BASE_SIZE); - pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO, - &s->mem_bar); pm_smbus_init(&d->qdev, &s->smb); + pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO, + &s->smb.io); return 0; } @@ -134,6 +111,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_ich9_smbus; dc->desc = "ICH9 SMBUS Bridge"; k->init = ich9_smbus_initfn; + k->config_write = ich9_smbus_write_config; } i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base) diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 99e6b2f9a9..5016e954d3 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -351,8 +351,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x90; - register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb); - register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb); + pm_smbus_init(&s->dev.qdev, &s->smb); + memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io); apm_init(&s->apm, NULL, s); @@ -364,8 +364,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar, &s->io); - pm_smbus_init(&s->dev.qdev, &s->smb); - return 0; } From 24fe083de67e0f736c54da4abda05f23ec37c51d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 14:58:04 +0100 Subject: [PATCH 13/18] acpi: fix piix4 smbus mapping Make write to the smbus base register and enable bit actually work. Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 9e6c97ebd3..b1d5bf3d61 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -142,12 +142,29 @@ static void pm_io_space_update(PIIX4PMState *s) memory_region_transaction_commit(); } +static void smbus_io_space_update(PIIX4PMState *s) +{ + s->smb_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x90)); + s->smb_io_base &= 0xffc0; + + memory_region_transaction_begin(); + memory_region_set_enabled(&s->smb.io, s->dev.config[0xd2] & 1); + memory_region_set_address(&s->smb.io, s->smb_io_base); + memory_region_transaction_commit(); +} + static void pm_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { pci_default_write_config(d, address, val, len); - if (range_covers_byte(address, len, 0x80)) + if (range_covers_byte(address, len, 0x80) || + ranges_overlap(address, len, 0x40, 4)) { pm_io_space_update((PIIX4PMState *)d); + } + if (range_covers_byte(address, len, 0xd2) || + ranges_overlap(address, len, 0x90, 4)) { + smbus_io_space_update((PIIX4PMState *)d); + } } static void vmstate_pci_status_pre_save(void *opaque) @@ -392,6 +409,7 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x09; pm_smbus_init(&s->dev.qdev, &s->smb); + memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1); memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io); memory_region_init(&s->io, "piix4-pm", 64); From b65b93f24cb84923d2d7d43cf87d40bc88b6bdcd Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 15:35:13 +0100 Subject: [PATCH 14/18] apci: switch piix4 gpe to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index b1d5bf3d61..c1a58d32c7 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -57,6 +57,7 @@ struct pci_status { typedef struct PIIX4PMState { PCIDevice dev; MemoryRegion io; + MemoryRegion io_gpe; ACPIREGS ar; APMState apm; @@ -500,7 +501,7 @@ static void piix4_pm_register_types(void) type_init(piix4_pm_register_types) -static uint32_t gpe_readb(void *opaque, uint32_t addr) +static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width) { PIIX4PMState *s = opaque; uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr); @@ -509,7 +510,8 @@ static uint32_t gpe_readb(void *opaque, uint32_t addr) return val; } -static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) +static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val, + unsigned width) { PIIX4PMState *s = opaque; @@ -519,6 +521,16 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val); } +static const MemoryRegionOps piix4_gpe_ops = { + .read = gpe_readb, + .write = gpe_writeb, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 1, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static uint32_t pci_up_read(void *opaque, uint32_t addr) { PIIX4PMState *s = opaque; @@ -567,10 +579,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) { - - register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s); - register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s); - acpi_gpe_blk(&s->ar, GPE_BASE); + memory_region_init_io(&s->io_gpe, &piix4_gpe_ops, s, "apci-gpe0", + GPE_LEN); + memory_region_add_subregion(get_system_io(), GPE_BASE, &s->io_gpe); + acpi_gpe_blk(&s->ar, 0); register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s); register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s); From c84649ca66a32aadba20a8202062b02247270ee5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 15:37:05 +0100 Subject: [PATCH 15/18] acpi: remove acpi_gpe_blk With gpe being switched to memory api this is no longer needed. Signed-off-by: Gerd Hoffmann --- hw/acpi.c | 7 ------- hw/acpi.h | 2 -- hw/acpi_ich9.c | 1 - hw/acpi_piix4.c | 1 - 4 files changed, 11 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index e58e45f301..ae29a59077 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -493,11 +493,6 @@ void acpi_gpe_init(ACPIREGS *ar, uint8_t len) ar->gpe.en = g_malloc0(len / 2); } -void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk) -{ - ar->gpe.blk = blk; -} - void acpi_gpe_reset(ACPIREGS *ar) { memset(ar->gpe.sts, 0, ar->gpe.len / 2); @@ -523,7 +518,6 @@ void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val) { uint8_t *cur; - addr -= ar->gpe.blk; cur = acpi_gpe_ioport_get_ptr(ar, addr); if (addr < ar->gpe.len / 2) { /* GPE_STS */ @@ -541,7 +535,6 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr) uint8_t *cur; uint32_t val; - addr -= ar->gpe.blk; cur = acpi_gpe_ioport_get_ptr(ar, addr); val = 0; if (cur != NULL) { diff --git a/hw/acpi.h b/hw/acpi.h index 918d7f5bca..afda153d09 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -104,7 +104,6 @@ struct ACPIPM1CNT { }; struct ACPIGPE { - uint32_t blk; uint8_t len; uint8_t *sts; @@ -150,7 +149,6 @@ void acpi_pm1_cnt_reset(ACPIREGS *ar); /* GPE0 */ void acpi_gpe_init(ACPIREGS *ar, uint8_t len); -void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk); void acpi_gpe_reset(ACPIREGS *ar); void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val); diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index db0d7a5063..c5978d33cc 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -212,7 +212,6 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); - acpi_gpe_blk(&pm->acpi_regs, 0); memory_region_init_io(&pm->io_gpe, &ich9_gpe_ops, pm, "apci-gpe0", ICH9_PMIO_GPE0_LEN); memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe); diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index c1a58d32c7..d2ba56e5bf 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -582,7 +582,6 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) memory_region_init_io(&s->io_gpe, &piix4_gpe_ops, s, "apci-gpe0", GPE_LEN); memory_region_add_subregion(get_system_io(), GPE_BASE, &s->io_gpe); - acpi_gpe_blk(&s->ar, 0); register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s); register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s); From c177684c753a0b1337acebb7dbc6f3f3a9700321 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 16:03:19 +0100 Subject: [PATCH 16/18] apci: switch piix4 pci hotplug to memory api Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index d2ba56e5bf..263338aa20 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -42,6 +42,9 @@ #define GPE_BASE 0xafe0 #define GPE_LEN 4 + +#define PCI_HOTPLUG_ADDR 0xae00 +#define PCI_HOTPLUG_SIZE 0x000f #define PCI_UP_BASE 0xae00 #define PCI_DOWN_BASE 0xae04 #define PCI_EJ_BASE 0xae08 @@ -58,6 +61,7 @@ typedef struct PIIX4PMState { PCIDevice dev; MemoryRegion io; MemoryRegion io_gpe; + MemoryRegion io_pci; ACPIREGS ar; APMState apm; @@ -574,6 +578,27 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr) return s->pci0_hotplug_enable; } +static const MemoryRegionOps piix4_pci_ops = { + .old_portio = (MemoryRegionPortio[]) { + { + .offset = PCI_UP_BASE - PCI_HOTPLUG_ADDR, .len = 4, .size = 4, + .read = pci_up_read, + },{ + .offset = PCI_DOWN_BASE - PCI_HOTPLUG_ADDR, .len = 4, .size = 4, + .read = pci_down_read, + },{ + .offset = PCI_EJ_BASE - PCI_HOTPLUG_ADDR, .len = 4, .size = 4, + .read = pci_features_read, + .write = pciej_write, + },{ + .offset = PCI_RMV_BASE - PCI_HOTPLUG_ADDR, .len = 4, .size = 4, + .read = pcirmv_read, + }, + PORTIO_END_OF_LIST() + }, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, PCIHotplugState state); @@ -583,14 +608,10 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) GPE_LEN); memory_region_add_subregion(get_system_io(), GPE_BASE, &s->io_gpe); - register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s); - register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s); - - register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s); - register_ioport_read(PCI_EJ_BASE, 4, 4, pci_features_read, s); - - register_ioport_read(PCI_RMV_BASE, 4, 4, pcirmv_read, s); - + memory_region_init_io(&s->io_pci, &piix4_pci_ops, s, "apci-pci-hotplug", + PCI_HOTPLUG_SIZE); + memory_region_add_subregion(get_system_io(), PCI_HOTPLUG_ADDR, + &s->io_pci); pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev); } From 3f5bc9e8af8c9ee617b143e42ad4bd2feb379a19 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 23 Nov 2012 15:02:18 +0100 Subject: [PATCH 17/18] q35: update lpc pci config space according to configured devices Signed-off-by: Gerd Hoffmann --- hw/ich9.h | 1 + hw/lpc_ich9.c | 29 +++++++++++++++++++++++++++++ hw/smbus_ich9.c | 12 ------------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/hw/ich9.h b/hw/ich9.h index de491350c3..34e216f142 100644 --- a/hw/ich9.h +++ b/hw/ich9.h @@ -51,6 +51,7 @@ typedef struct ICH9LPCState { /* isa bus */ ISABus *isa_bus; MemoryRegion rbca_mem; + Notifier machine_ready; qemu_irq *pic; qemu_irq *ioapic; diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c index 2fc83a496f..6585236148 100644 --- a/hw/lpc_ich9.c +++ b/hw/lpc_ich9.c @@ -60,6 +60,7 @@ #include "pam.h" #include "pci_internals.h" #include "exec-memory.h" +#include "sysemu.h" static int ich9_lpc_sci_irq(ICH9LPCState *lpc); @@ -456,6 +457,30 @@ static const MemoryRegionOps rbca_mmio_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static void ich9_lpc_machine_ready(Notifier *n, void *opaque) +{ + ICH9LPCState *s = container_of(n, ICH9LPCState, machine_ready); + uint8_t *pci_conf; + + pci_conf = s->d.config; + if (isa_is_ioport_assigned(0x3f8)) { + /* com1 */ + pci_conf[0x82] |= 0x01; + } + if (isa_is_ioport_assigned(0x2f8)) { + /* com2 */ + pci_conf[0x82] |= 0x02; + } + if (isa_is_ioport_assigned(0x378)) { + /* lpt */ + pci_conf[0x82] |= 0x04; + } + if (isa_is_ioport_assigned(0x3f0)) { + /* floppy */ + pci_conf[0x82] |= 0x08; + } +} + static int ich9_lpc_initfn(PCIDevice *d) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(d); @@ -473,6 +498,10 @@ static int ich9_lpc_initfn(PCIDevice *d) ich9_cc_init(lpc); apm_init(&lpc->apm, ich9_apm_ctrl_changed, lpc); + + lpc->machine_ready.notify = ich9_lpc_machine_ready; + qemu_add_machine_init_done_notifier(&lpc->machine_ready); + return 0; } diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c index 54e7e1252d..4194785d71 100644 --- a/hw/smbus_ich9.c +++ b/hw/smbus_ich9.c @@ -77,18 +77,6 @@ static int ich9_smbus_initfn(PCIDevice *d) /* TODO? D31IP.SMIP in chipset configuration space */ pci_config_set_interrupt_pin(d->config, 0x01); /* interrupt pin 1 */ - pci_set_byte(d->config + ICH9_SMB_HOSTC, 0); - - /* - * update parameters based on - * paralell_hds[0] - * serial_hds[0] - * serial_hds[0] - * fdc - * - * Is there any OS that depends on them? - */ - pci_set_byte(d->config + ICH9_SMB_HOSTC, 0); /* TODO bar0, bar1: 64bit BAR support*/ From 3e43749882c558875f70ac5deda39cdc9797e245 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 27 Nov 2012 08:24:42 +0100 Subject: [PATCH 18/18] acpi: drop debug port I'm pretty sure this isn't needed any more. I think this predates the switch to seabios, and the seabios DSDT table has a DBUG() aml macro which writes stuff to the seabios debug port (0x402). Signed-off-by: Gerd Hoffmann --- hw/acpi_piix4.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 263338aa20..b03454e6c0 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -38,8 +38,6 @@ # define PIIX4_DPRINTF(format, ...) do { } while (0) #endif -#define ACPI_DBG_IO_ADDR 0xb044 - #define GPE_BASE 0xafe0 #define GPE_LEN 4 @@ -129,11 +127,6 @@ static void apm_ctrl_changed(uint32_t val, void *arg) } } -static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val) -{ - PIIX4_DPRINTF("ACPI: DBG: 0x%08x\n", val); -} - static void pm_io_space_update(PIIX4PMState *s) { uint32_t pm_io_base; @@ -400,8 +393,6 @@ static int piix4_pm_initfn(PCIDevice *dev) /* APM */ apm_init(&s->apm, apm_ctrl_changed, s); - register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s); - if (s->kvm_enabled) { /* Mark SMM as already inited to prevent SMM from running. KVM does not * support SMM mode. */