All of lore.kernel.org
 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: gleb@redhat.com, avi@redhat.com,
	Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
Subject: [RFC PATCH 5/9] acpi_piix4: Implement memory device hotplug registers
Date: Thu, 19 Apr 2012 16:08:43 +0200	[thread overview]
Message-ID: <1334844527-18869-6-git-send-email-vasilis.liaskovitis@profitbricks.com> (raw)
In-Reply-To: <1334844527-18869-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 (from
 BIOS/OSPM perspective). "memslot id add" will immediately populate the new
 memslot (a new MemoryRegion is created and attached to system memory), and
 then trigger the ACPI hot-add event. "memslot id delete" triggers the ACPI
 hot-remove event but needs to wait for OSPM to eject the device.  We use a
 second set of eject registers to know when OSPM has called the _EJ function
 for a particular memslot. A write to these will depopulate the corresponding
 memslot i.e. detach and free the MemoryRegion. Only writes to the eject
 registers are allowed.

 A new property mem_acpi_hotplug should enable these memory hotplug registers
 for future machine types (not yet implemented in this version).

Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
---
 hw/acpi_piix4.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 797ed24..a14dd3c 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -27,6 +27,8 @@
 #include "sysemu.h"
 #include "range.h"
 #include "ioport.h"
+#include "sysbus.h"
+#include "memslot.h"
 
 //#define DEBUG
 
@@ -43,9 +45,16 @@
 #define PCI_BASE 0xae00
 #define PCI_EJ_BASE 0xae08
 #define PCI_RMV_BASE 0xae0c
+#define MEM_BASE 0xaf20
+#define MEM_EJ_BASE 0xaf40
 
+#define PIIX4_MEM_HOTPLUG_STATUS 8
 #define PIIX4_PCI_HOTPLUG_STATUS 2
 
+struct gpe_regs {
+    uint8_t mems_sts[32];
+};
+
 struct pci_status {
     uint32_t up;
     uint32_t down;
@@ -66,6 +75,7 @@ typedef struct PIIX4PMState {
     int kvm_enabled;
     Notifier machine_ready;
 
+    struct gpe_regs    gpe;
     /* for pci hotplug */
     struct pci_status pci0_status;
     uint32_t pci0_hotplug_enable;
@@ -86,8 +96,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 */
@@ -432,17 +442,34 @@ 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->gpe;
+
+    switch (addr) {
+        case MEM_BASE ... MEM_BASE+31:
+            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;
 }
 
+static void piix4_memslot_eject(uint32_t addr, uint32_t val);
+
 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 ... MEM_EJ_BASE+31:
+            piix4_memslot_eject(addr, val);
+            break;
+        default:
+            acpi_gpe_ioport_writeb(&s->ar, addr, val);
+    }
     pm_update_sci(s);
 
     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
@@ -521,9 +548,12 @@ static void pcirmv_write(void *opaque, uint32_t addr, uint32_t val)
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
 
+static int piix4_memslot_hotplug(DeviceState *qdev, SysBusDevice *dev, int add);
+
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
     struct pci_status *pci0_status = &s->pci0_status;
+    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);
@@ -538,6 +568,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
     register_ioport_write(PCI_RMV_BASE, 4, 4, pcirmv_write, s);
     register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
 
+    register_ioport_read(MEM_BASE, 32, 1,  gpe_readb, s);
+    register_ioport_write(MEM_EJ_BASE, 32, 1,  gpe_writeb, s);
+    for(i = 0; i < 32; i++) {
+        s->gpe.mems_sts[i] = 0;
+    }
+    memslot_register_hotplug(piix4_memslot_hotplug, &s->dev.qdev);
+
     pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
 }
 
@@ -553,6 +590,54 @@ static void disable_device(PIIX4PMState *s, int slot)
     s->pci0_status.down |= (1 << slot);
 }
 
+static void enable_mem_device(PIIX4PMState *s, int memdevice)
+{
+    struct gpe_regs *g = &s->gpe;
+    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->gpe;
+    s->ar.gpe.sts[0] |= PIIX4_MEM_HOTPLUG_STATUS;
+    g->mems_sts[memdevice/8] &= ~(1 << (memdevice%8));
+}
+
+static void piix4_memslot_eject(uint32_t addr, uint32_t val)
+{
+    uint32_t start = 8 * (addr - MEM_EJ_BASE);
+    uint32_t idx = 0;
+    MemSlotState *s;
+    PIIX4_DPRINTF("memej write %x <= %d\n", addr, val);
+    while (val) {
+        if (val & 1) {
+            s = memslot_find_from_idx(start + idx);
+            assert(s != NULL);
+            memslot_depopulate(s);
+        }
+        val = val >> 1;
+        idx++;
+    }
+}
+
+static int piix4_memslot_hotplug(DeviceState *qdev, SysBusDevice *dev, int
+        add)
+{
+    PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev,
+                                PCI_DEVICE(qdev));
+    MemSlotState *slot = MEMSLOT(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-04-19 14:09 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-19 14:08 [RFC PATCH 0/9] ACPI memory hotplug Vasilis Liaskovitis
2012-04-19 14:08 ` [RFC PATCH 1/9][SeaBIOS] Add SSDT memory device support Vasilis Liaskovitis
2012-04-19 14:08 ` [RFC PATCH 2/9][SeaBIOS] Implement acpi-dsdt functions for memory hotplug Vasilis Liaskovitis
2012-04-20 10:55   ` Igor Mammedov
2012-04-20 14:11     ` [Qemu-devel] " Vasilis Liaskovitis
2012-04-19 14:08 ` [RFC PATCH 3/9][SeaBIOS] acpi: generate hotplug memory devices Vasilis Liaskovitis
2012-04-23 23:37   ` Kevin O'Connor
2012-04-24  8:27     ` Vasilis Liaskovitis
2012-04-19 14:08 ` [RFC PATCH 4/9] Implement memslot device abstraction Vasilis Liaskovitis
2012-04-19 14:08 ` Vasilis Liaskovitis [this message]
2012-04-19 14:08 ` [RFC PATCH 6/9] pc: pass paravirt info for hotplug memory slots to BIOS Vasilis Liaskovitis
2012-04-19 14:21   ` Avi Kivity
2012-04-20 10:33   ` Igor Mammedov
2012-04-20 16:35     ` [Qemu-devel] " Vasilis Liaskovitis
2012-04-19 14:08 ` [RFC PATCH 7/9] Implement memslot command-line option and memslot hmp command Vasilis Liaskovitis
2012-04-19 14:22   ` Avi Kivity
2012-04-19 18:10     ` Vasilis Liaskovitis
2012-04-19 14:08 ` [RFC PATCH 8/9] pc: adjust e820 map on hot-add and hot-remove Vasilis Liaskovitis
2012-04-22 13:58   ` Gleb Natapov
2012-04-23 11:27     ` Vasilis Liaskovitis
2012-04-23 11:30       ` Gleb Natapov
2012-04-19 14:08 ` [RFC PATCH 9/9][SeaBIOS] enable memory devices if e820 entry is present Vasilis Liaskovitis
2012-04-26  0:58   ` [SeaBIOS] [RFC PATCH 9/9] " Wen Congyang
2012-04-19 14:49 ` [Qemu-devel] [RFC PATCH 0/9] ACPI memory hotplug Anthony Liguori
2012-04-19 18:09   ` Vasilis Liaskovitis
2012-04-20 14:20 ` Vasilis Liaskovitis
2012-04-22 13:56 ` Gleb Natapov
2012-04-22 14:06   ` Avi Kivity
2012-04-22 14:09     ` Gleb Natapov
2012-04-22 14:13       ` Avi Kivity
2012-04-22 14:20         ` Gleb Natapov
2012-04-23 12:31           ` Vasilis Liaskovitis
2012-04-24  7:52             ` Gleb Natapov
2012-04-24  8:24               ` Vasilis Liaskovitis
2012-04-24  8:34                 ` Gleb Natapov
2012-04-23 13:31           ` Avi Kivity
2012-04-24  7:21             ` Gleb Natapov
2012-04-24  9:09               ` Avi Kivity

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=1334844527-18869-6-git-send-email-vasilis.liaskovitis@profitbricks.com \
    --to=vasilis.liaskovitis@profitbricks.com \
    --cc=avi@redhat.com \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=qemu-devel@nongnu.org \
    --cc=seabios@seabios.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.