kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
To: qemu-devel@nongnu.org, kvm@vger.kernel.org, seabios@seabios.org
Cc: avi@redhat.com, anthony@codemonkey.ws, gleb@redhat.com,
	imammedo@redhat.com, kevin@koconnor.net, wency@cn.fujitsu.com,
	Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
Subject: [RFC PATCH v2 07/21] acpi_piix4: Implement memory device hotplug registers
Date: Wed, 11 Jul 2012 12:31:52 +0200	[thread overview]
Message-ID: <1342002726-18258-8-git-send-email-vasilis.liaskovitis@profitbricks.com> (raw)
In-Reply-To: <1342002726-18258-1-git-send-email-vasilis.liaskovitis@profitbricks.com>

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

Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
---
 docs/specs/acpi_hotplug.txt |   22 +++++++++++++
 hw/acpi_piix4.c             |   73 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 91 insertions(+), 4 deletions(-)
 create mode 100644 docs/specs/acpi_hotplug.txt

diff --git a/docs/specs/acpi_hotplug.txt b/docs/specs/acpi_hotplug.txt
new file mode 100644
index 0000000..cf86242
--- /dev/null
+++ b/docs/specs/acpi_hotplug.txt
@@ -0,0 +1,22 @@
+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.
+
+Memory Dimm ejection success notification (IO port 0xafa0, 1-byte access):
+---------------------------------------------------------------
+Dimm hot-remove _EJ0 notification. Byte value indicates Dimm slot that was
+ejected.
+
+Written by ACPI memory device _EJ0 method to notify qemu of successfull
+hot-removal.  Write-only.
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 0aace60..b988597 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -28,6 +28,8 @@
 #include "range.h"
 #include "ioport.h"
 #include "fw_cfg.h"
+#include "sysbus.h"
+#include "dimm.h"
 
 //#define DEBUG
 
@@ -45,9 +47,15 @@
 #define PCI_DOWN_BASE 0xae04
 #define PCI_EJ_BASE 0xae08
 #define PCI_RMV_BASE 0xae0c
+#define MEM_BASE 0xaf80
+#define MEM_EJ_BASE 0xafa0
 
+#define PIIX4_MEM_HOTPLUG_STATUS 8
 #define PIIX4_PCI_HOTPLUG_STATUS 2
 
+struct gpe_regs {
+    uint8_t mems_sts[DIMM_BITMAP_BYTES];
+};
 struct pci_status {
     uint32_t up; /* deprecated, maintained for migration compatibility */
     uint32_t down;
@@ -69,6 +77,7 @@ typedef struct PIIX4PMState {
     Notifier machine_ready;
 
     /* for pci hotplug */
+    struct gpe_regs gperegs;
     struct pci_status pci0_status;
     uint32_t pci0_hotplug_enable;
     uint32_t pci0_slot_device_present;
@@ -93,8 +102,8 @@ static void pm_update_sci(PIIX4PMState *s)
                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
                    ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
-        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0])
-          & PIIX4_PCI_HOTPLUG_STATUS) != 0);
+        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
+          (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_MEM_HOTPLUG_STATUS)) != 0);
 
     qemu_set_irq(s->irq, sci_level);
     /* schedule a timer interruption if needed */
@@ -499,7 +508,16 @@ type_init(piix4_pm_register_types)
 static uint32_t gpe_readb(void *opaque, uint32_t addr)
 {
     PIIX4PMState *s = opaque;
-    uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
+    uint32_t val = 0;
+    struct gpe_regs *g = &s->gperegs;
+
+    switch (addr) {
+        case MEM_BASE ... MEM_BASE+DIMM_BITMAP_BYTES:
+            val = g->mems_sts[addr - MEM_BASE];
+            break;
+        default:
+            val = acpi_gpe_ioport_readb(&s->ar, addr);
+    }
 
     PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
     return val;
@@ -509,7 +527,13 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     PIIX4PMState *s = opaque;
 
-    acpi_gpe_ioport_writeb(&s->ar, addr, val);
+    switch (addr) {
+        case MEM_EJ_BASE:
+            dimm_notify(val, DIMM_REMOVE_SUCCESS);
+            break;
+        default:
+            acpi_gpe_ioport_writeb(&s->ar, addr, val);
+    }
     pm_update_sci(s);
 
     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
@@ -560,9 +584,11 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr)
 
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
+static int piix4_dimm_hotplug(DeviceState *qdev, SysBusDevice *dev, int add);
 
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
+    int i = 0;
 
     register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
     register_ioport_read(GPE_BASE, GPE_LEN, 1,  gpe_readb, s);
@@ -576,7 +602,15 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 
     register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
 
+    register_ioport_read(MEM_BASE, DIMM_BITMAP_BYTES, 1,  gpe_readb, s);
+    register_ioport_write(MEM_EJ_BASE, 1, 1,  gpe_writeb, s);
+
+    for(i = 0; i < DIMM_BITMAP_BYTES; i++) {
+        s->gperegs.mems_sts[i] = 0;
+    }
+
     pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
+    dimm_register_hotplug(piix4_dimm_hotplug, &s->dev.qdev);
 }
 
 static void enable_device(PIIX4PMState *s, int slot)
@@ -591,6 +625,37 @@ static void disable_device(PIIX4PMState *s, int slot)
     s->pci0_status.down |= (1U << slot);
 }
 
+static void enable_mem_device(PIIX4PMState *s, int memdevice)
+{
+    struct gpe_regs *g = &s->gperegs;
+    s->ar.gpe.sts[0] |= PIIX4_MEM_HOTPLUG_STATUS;
+    g->mems_sts[memdevice/8] |= (1 << (memdevice%8));
+}
+
+static void disable_mem_device(PIIX4PMState *s, int memdevice)
+{
+    struct gpe_regs *g = &s->gperegs;
+    s->ar.gpe.sts[0] |= PIIX4_MEM_HOTPLUG_STATUS;
+    g->mems_sts[memdevice/8] &= ~(1 << (memdevice%8));
+}
+
+static int piix4_dimm_hotplug(DeviceState *qdev, SysBusDevice *dev, int
+        add)
+{
+    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, qdev);
+    PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, pci_dev);
+    DimmState *slot = DIMM(dev);
+
+    if (add) {
+        enable_mem_device(s, slot->idx);
+    }
+    else {
+        disable_mem_device(s, slot->idx);
+    }
+    pm_update_sci(s);
+    return 0;
+}
+
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
 				PCIHotplugState state)
 {
-- 
1.7.9


  parent reply	other threads:[~2012-07-11 10:32 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-11 10:31 [RFC PATCH v2 00/21] ACPI memory hotplug Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 01/21][SeaBIOS] Add ACPI_EXTRACT_DEVICE* macros Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 02/21][SeaBIOS] Add SSDT memory device support Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 03/21][SeaBIOS] acpi-dsdt: Implement functions for memory hotplug Vasilis Liaskovitis
2012-07-17  7:23   ` Wen Congyang
2012-07-20  8:48     ` Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 04/21][SeaBIOS] acpi: generate hotplug memory devices Vasilis Liaskovitis
2012-07-11 10:48   ` Wen Congyang
2012-07-11 16:39     ` Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 05/21][SeaBIOS] pciinit: Fix pcimem_start value Vasilis Liaskovitis
2012-07-11 11:56   ` Gerd Hoffmann
2012-07-11 16:45     ` Vasilis Liaskovitis
2012-07-12  7:22       ` Gerd Hoffmann
2012-07-12  9:09         ` Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 06/21] dimm: Implement memory device abstraction Vasilis Liaskovitis
2012-07-12 19:55   ` Blue Swirl
2012-07-13 17:39     ` Vasilis Liaskovitis
2012-07-11 10:31 ` Vasilis Liaskovitis [this message]
2012-07-11 10:31 ` [RFC PATCH v2 08/21] pc: calculate dimm physical addresses and adjust memory map Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 09/21] pc: Add dimm paravirt SRAT info Vasilis Liaskovitis
2012-07-12 19:48   ` Blue Swirl
2012-07-13 17:40     ` [Qemu-devel] " Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 10/21] Implement "-dimm" command line option Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 11/21] Implement dimm_add and dimm_del hmp/qmp commands Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 12/21] fix live-migration when "populated=on" is missing Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 13/21] Implement memory hotplug notification lists Vasilis Liaskovitis
2012-07-11 14:59   ` [Qemu-devel] " Eric Blake
2012-07-11 16:47     ` Vasilis Liaskovitis
2012-07-11 10:31 ` [RFC PATCH v2 14/21][SeaBIOS] acpi_dsdt: Support _OST dimm method Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 15/21] acpi_piix4: _OST dimm support Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 16/21] acpi_piix4: Update dimm state on VM reboot Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 17/21][SeaBIOS] acpi_dsdt: Revert internal dimm state on _OST failure Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 18/21] acpi_piix4: Update dimm bitmap state on hot-remove fail Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 19/21] Implement "info memtotal" and "query-memtotal" Vasilis Liaskovitis
2012-07-11 15:14   ` Eric Blake
2012-07-11 16:55     ` [Qemu-devel] " Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 20/21] Implement -dimms, -dimmspop command line options Vasilis Liaskovitis
2012-07-11 14:55   ` Avi Kivity
2012-07-11 16:57     ` Vasilis Liaskovitis
2012-07-11 10:32 ` [RFC PATCH v2 21/21] Implement mem_increase, mem_decrease hmp/qmp commands Vasilis Liaskovitis
2012-07-12 20:04 ` [Qemu-devel] [RFC PATCH v2 00/21] ACPI memory hotplug Blue Swirl
2012-07-13 17:49   ` Vasilis Liaskovitis
2012-07-14  9:08     ` Blue Swirl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1342002726-18258-8-git-send-email-vasilis.liaskovitis@profitbricks.com \
    --to=vasilis.liaskovitis@profitbricks.com \
    --cc=anthony@codemonkey.ws \
    --cc=avi@redhat.com \
    --cc=gleb@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=kevin@koconnor.net \
    --cc=kvm@vger.kernel.org \
    --cc=qemu-devel@nongnu.org \
    --cc=seabios@seabios.org \
    --cc=wency@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).