[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 07/14] acpi_ich9 : Implement memory device hotplu
From: |
Hu Tao |
Subject: |
[Qemu-devel] [PATCH v5 07/14] acpi_ich9 : Implement memory device hotplug registers |
Date: |
Wed, 26 Jun 2013 17:13:30 +0800 |
From: Vasilis Liaskovitis <address@hidden>
This implements acpi dimm hot-add capability for q35 (ich9). The logic is the
same as for the pc machine (piix4).
TODO: Fix acpi irq delivery bug. Currently there is a flood of irqs when
delivering an acpi interrupt (should be just one). Guest complains as follows:
"irq 9: nobody cared
[...]
Disabling IRQ #9"
where #9 is the acpi irq
Signed-off-by: Vasilis Liaskovitis <address@hidden>
Signed-off-by: Hu Tao <address@hidden>
---
hw/acpi/ich9.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--
include/hw/acpi/ich9.h | 10 +++++++++
2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 4a17f32..0034aa2 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -33,6 +33,7 @@
#include "exec/address-spaces.h"
#include "hw/i386/ich9.h"
+#include "hw/mem-hotplug/dimm.h"
//#define DEBUG
@@ -49,11 +50,14 @@ static void pm_update_sci(ICH9LPCPMRegs *pm)
pm1a_sts = acpi_pm1_evt_get_sts(&pm->acpi_regs);
- sci_level = (((pm1a_sts & pm->acpi_regs.pm1.evt.en) &
+ sci_level = ((((pm1a_sts & pm->acpi_regs.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
- ACPI_BITMASK_TIMER_ENABLE)) != 0);
+ ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
+ (((pm->acpi_regs.gpe.sts[0] & pm->acpi_regs.gpe.en[0]) &
+ (ICH9_MEM_HOTPLUG_STATUS)) != 0));
+
qemu_set_irq(pm->irq, sci_level);
/* schedule a timer interruption if needed */
@@ -202,6 +206,47 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
acpi_pm1_evt_power_down(&pm->acpi_regs);
}
+static uint32_t mem_status_readb(void *opaque, uint32_t addr)
+{
+ ICH9LPCPMRegs *s = opaque;
+ uint32_t val = 0;
+ MemStatus *g = &s->gpe_mem;
+ if (addr < ICH9_MEM_LEN) {
+ val = (uint32_t) g->mems_sts[addr];
+ }
+ ICH9_DEBUG("memhp read %" PRIu32 " == %" PRIu32 "\n", addr, val);
+ return val;
+}
+
+static const MemoryRegionOps ich9_mem_hotplug_ops = {
+ .old_portio = (MemoryRegionPortio[]) {
+ {
+ .offset = 0, .len = ICH9_MEM_LEN, .size = 1,
+ .read = mem_status_readb,
+ },
+ PORTIO_END_OF_LIST()
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void enable_mem_device(ICH9LPCState *s, int memdevice)
+{
+ MemStatus *g = &s->pm.gpe_mem;
+ s->pm.acpi_regs.gpe.sts[0] |= ICH9_MEM_HOTPLUG_STATUS;
+ g->mems_sts[memdevice / 8] |= (1 << (memdevice % 8));
+}
+
+static int ich9_mem_hotplug(DeviceState *dev, DimmDevice *dimm, int add)
+{
+ ICH9LPCState *s = ICH9_LPC_DEVICE(dev);
+
+ if (add) {
+ enable_mem_device(s, dimm->idx);
+ }
+ pm_update_sci(&s->pm);
+ return 0;
+}
+
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
qemu_irq sci_irq)
{
@@ -227,4 +272,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
qemu_register_reset(pm_reset, pm);
pm->powerdown_notifier.notify = pm_powerdown_req;
qemu_register_powerdown_notifier(&pm->powerdown_notifier);
+
+ memory_region_init_io(&pm->io_mem, &ich9_mem_hotplug_ops, pm,
+ "acpi-memory-hotplug0", ICH9_MEM_BASE);
+ memory_region_add_subregion(get_system_io(), ICH9_MEM_BASE, &pm->io_mem);
+
+ dimm_bus_hotplug(ich9_mem_hotplug, &lpc_pci->qdev);
+
}
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index b1fe71f..300e07f 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -23,6 +23,14 @@
#include "hw/acpi/acpi.h"
+#define ICH9_MEM_BASE 0xaf80
+#define ICH9_MEM_LEN 32
+#define ICH9_MEM_HOTPLUG_STATUS 8
+
+typedef struct MemStatus {
+ uint8_t mems_sts[ICH9_MEM_LEN];
+} MemStatus;
+
typedef struct ICH9LPCPMRegs {
/*
* In ich9 spec says that pm1_cnt register is 32bit width and
@@ -34,6 +42,7 @@ typedef struct ICH9LPCPMRegs {
MemoryRegion io;
MemoryRegion io_gpe;
MemoryRegion io_smi;
+ MemoryRegion io_mem;
uint32_t smi_en;
uint32_t smi_sts;
@@ -42,6 +51,7 @@ typedef struct ICH9LPCPMRegs {
uint32_t pm_io_base;
Notifier powerdown_notifier;
+ MemStatus gpe_mem;
} ICH9LPCPMRegs;
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
--
1.8.3.1
- Re: [Qemu-devel] [PATCH v5 05/14] vl: handle "-device dimm", (continued)
[Qemu-devel] [PATCH v5 03/14] qemu-option: export parse_option_number, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 02/14] Add SIZE type to qdev properties, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 06/14] acpi_piix4 : Implement memory device hotplug registers, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 11/14] Introduce paravirt interface QEMU_CFG_PCI_WINDOW, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 09/14] memory controller: initialize dram controller., Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 04/14] Implement dimm device abstraction, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 13/14] balloon: update with hotplugged memory, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 07/14] acpi_ich9 : Implement memory device hotplug registers,
Hu Tao <=
[Qemu-devel] [PATCH v5 10/14] pc: Add dimm paravirt SRAT info, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 12/14] Implement "info memory" and "query-memory", Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 08/14] memory: record below_4g_mem_size, above_4g_mem_size, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 14/14] Implement dimm-info, Hu Tao, 2013/06/26
[Qemu-devel] [PATCH v5 0/7] support for ACPI memory hotplug, Hu Tao, 2013/06/26