[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 06/14] acpi_piix4 : Implement memory device hotpl
From: |
Hu Tao |
Subject: |
[Qemu-devel] [PATCH v5 06/14] acpi_piix4 : Implement memory device hotplug registers |
Date: |
Wed, 26 Jun 2013 17:13:29 +0800 |
From: Vasilis Liaskovitis <address@hidden>
A 32-byte register is used to present up to 256 hotplug-able memory devices
to BIOS and OSPM. Hot-add and hot-remove functions trigger an ACPI hotplug
event through these. Only reads are allowed from these registers.
An ACPI hot-remove event but needs to wait for OSPM to eject the device.
We use a single-byte register to know when OSPM has called the _EJ function
for a particular dimm. A write to this byte will depopulate the respective dimm.
Only writes are allowed to this byte.
v1->v2:
mems_sts address moved from 0xaf20 to 0xaf80 (to accomodate more space for
cpu-hotplugging in the future).
_EJ array is reduced to a single byte.
Add documentation in docs/specs/acpi_hotplug.txt
v3->v4: Removed hot-remove functions, will be added separately. Updated for
memory API.
Signed-off-by: Vasilis Liaskovitis <address@hidden>
Signed-off-by: Hu Tao <address@hidden>
---
docs/specs/acpi_mem_hotplug.txt | 14 ++++++++
hw/acpi/piix4.c | 72 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 85 insertions(+), 1 deletion(-)
create mode 100644 docs/specs/acpi_mem_hotplug.txt
diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
new file mode 100644
index 0000000..8391713
--- /dev/null
+++ b/docs/specs/acpi_mem_hotplug.txt
@@ -0,0 +1,14 @@
+QEMU<->ACPI BIOS hotplug interface
+--------------------------------------
+This document describes the interface between QEMU and the ACPI BIOS for
non-PCI
+space. For the PCI interface please look at docs/specs/acpi_pci_hotplug.txt
+
+QEMU<->ACPI BIOS memory hotplug interface
+--------------------------------------
+
+Memory Dimm status array (IO port 0xaf80-0xaf9f, 1-byte access):
+---------------------------------------------------------------
+Dimm hot-plug notification pending. One bit per slot.
+
+Read by ACPI BIOS GPE.3 handler to notify OS of memory hot-add or hot-remove
+events. Read-only.
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 756df3b..2795ab0 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -29,6 +29,7 @@
#include "exec/ioport.h"
#include "hw/nvram/fw_cfg.h"
#include "exec/address-spaces.h"
+#include "hw/mem-hotplug/dimm.h"
//#define DEBUG
@@ -50,9 +51,12 @@
#define PIIX4_PROC_BASE 0xaf00
#define PIIX4_PROC_LEN 32
+#define PIIX4_MEM_BASE 0xaf80
+#define PIIX4_MEM_LEN 32
#define PIIX4_PCI_HOTPLUG_STATUS 2
#define PIIX4_CPU_HOTPLUG_STATUS 4
+#define PIIX4_MEM_HOTPLUG_STATUS 8
struct pci_status {
uint32_t up; /* deprecated, maintained for migration compatibility */
@@ -63,6 +67,10 @@ typedef struct CPUStatus {
uint8_t sts[PIIX4_PROC_LEN];
} CPUStatus;
+typedef struct MemStatus {
+ uint8_t mems_sts[PIIX4_MEM_LEN];
+} MemStatus;
+
typedef struct PIIX4PMState {
PCIDevice dev;
@@ -70,6 +78,7 @@ typedef struct PIIX4PMState {
MemoryRegion io_gpe;
MemoryRegion io_pci;
MemoryRegion io_cpu;
+ MemoryRegion io_mem;
ACPIREGS ar;
APMState apm;
@@ -94,6 +103,8 @@ typedef struct PIIX4PMState {
CPUStatus gpe_cpu;
Notifier cpu_added_notifier;
+
+ MemStatus gpe_mem;
} PIIX4PMState;
static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
@@ -113,7 +124,8 @@ static void pm_update_sci(PIIX4PMState *s)
ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
(((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
- (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) != 0);
+ (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS |
+ PIIX4_MEM_HOTPLUG_STATUS)) != 0);
qemu_set_irq(s->irq, sci_level);
/* schedule a timer interruption if needed */
@@ -664,8 +676,40 @@ static void piix4_init_cpu_status(CPUState *cpu, void
*data)
g->sts[id / 8] |= (1 << (id % 8));
}
+static uint32_t mem_status_readb(void *opaque, uint32_t addr)
+{
+ PIIX4PMState *s = opaque;
+ uint32_t val = 0;
+ MemStatus *g = &s->gpe_mem;
+ if (addr < PIIX4_MEM_LEN) {
+ val = (uint32_t) g->mems_sts[addr];
+ }
+ PIIX4_DPRINTF("memhp read %" PRIu32 " == %" PRIu32 "\n", addr, val);
+ return val;
+}
+
+static const MemoryRegionOps mem_hotplug_ops = {
+ .old_portio = (MemoryRegionPortio[]) {
+ {
+ .offset = 0, .len = PIIX4_MEM_LEN, .size = 1,
+ .read = mem_status_readb,
+ },
+ PORTIO_END_OF_LIST()
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void piix4_init_mem_status(PIIX4PMState *s)
+{
+ int i;
+ for (i = 0; i < PIIX4_MEM_LEN; i++) {
+ s->gpe_mem.mems_sts[i] = 0;
+ }
+}
+
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
PCIHotplugState state);
+static int piix4_mem_hotplug(DeviceState *qdev, DimmDevice *dev, int add);
static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
@@ -686,6 +730,13 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion
*parent,
memory_region_add_subregion(parent, PIIX4_PROC_BASE, &s->io_cpu);
s->cpu_added_notifier.notify = piix4_cpu_added_req;
qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
+
+ piix4_init_mem_status(s);
+ memory_region_init_io(&s->io_mem, &mem_hotplug_ops, s, "apci-mem-hotplug",
+ PIIX4_MEM_LEN);
+ memory_region_add_subregion(parent, PIIX4_MEM_BASE, &s->io_mem);
+
+ dimm_bus_hotplug(piix4_mem_hotplug, &s->dev.qdev);
}
static void enable_device(PIIX4PMState *s, int slot)
@@ -725,3 +776,22 @@ static int piix4_device_hotplug(DeviceState *qdev,
PCIDevice *dev,
return 0;
}
+
+static void enable_mem_device(PIIX4PMState *s, int memdevice)
+{
+ MemStatus *g = &s->gpe_mem;
+ s->ar.gpe.sts[0] |= PIIX4_MEM_HOTPLUG_STATUS;
+ g->mems_sts[memdevice / 8] |= (1 << (memdevice % 8));
+}
+
+static int piix4_mem_hotplug(DeviceState *dev, DimmDevice *dimm, int add)
+{
+ PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
+ PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, pci_dev);
+
+ if (add) {
+ enable_mem_device(s, dimm->idx);
+ }
+ pm_update_sci(s);
+ return 0;
+}
--
1.8.3.1
- [Qemu-devel] [PATCH v5 00/14] ACPI memory hotplug, Hu Tao, 2013/06/26
- [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 <=
- [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, 2013/06/26
- [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