Patchwork [RFC,v4,30/30] Implement _PS3 for dimm

login
register
mail settings
Submitter Vasilis Liaskovitis
Date Dec. 18, 2012, 12:41 p.m.
Message ID <1355834518-17989-31-git-send-email-vasilis.liaskovitis@profitbricks.com>
Download mbox | patch
Permalink /patch/207095/
State New
Headers show

Comments

Vasilis Liaskovitis - Dec. 18, 2012, 12:41 p.m.
This will allow us to update dimm state on OSPM-initiated eject operations e.g.
with "echo 1 > /sys/bus/acpi/devices/PNP0C80\:00/eject"

v3->v4: Add support for ich9
---
 docs/specs/acpi_hotplug.txt |    7 +++++++
 hw/acpi_ich9.c              |    7 +++++--
 hw/acpi_ich9.h              |    1 +
 hw/acpi_piix4.c             |    9 ++++++---
 hw/dimm.c                   |    4 ++++
 hw/dimm.h                   |    3 ++-
 6 files changed, 25 insertions(+), 6 deletions(-)

Patch

diff --git a/docs/specs/acpi_hotplug.txt b/docs/specs/acpi_hotplug.txt
index 536da16..69868fe 100644
--- a/docs/specs/acpi_hotplug.txt
+++ b/docs/specs/acpi_hotplug.txt
@@ -45,3 +45,10 @@  insertion failed.
 Written by ACPI memory device _OST method to notify qemu of failed
 hot-add.  Write-only.
 
+Memory Dimm _PS3 power-off initiated by OSPM (IO port 0xafa4, 1-byte access):
+---------------------------------------------------------------
+Dimm hot-add _PS3 initiated by OSPM. Byte value indicates Dimm slot which
+entered D3 state.
+
+Written by ACPI memory device _PS3 method to notify qemu of power-off state for
+the dimm.  Write-only.
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 2705230..5e7fca6 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -120,6 +120,9 @@  static void memhp_writeb(void *opaque, uint32_t addr, uint32_t val)
     case ICH9_MEM_OST_ADD_FAIL - ICH9_MEM_BASE:
         dimm_notify(val, DIMM_ADD_FAIL);
         break;
+    case ICH9_MEM_PS3 - ICH9_MEM_BASE:
+         dimm_notify(val, DIMM_OSPM_POWEROFF);
+         break;
     default:
         ICH9_DEBUG("memhp write invalid %x <== %d\n", addr, val);
     }
@@ -134,7 +137,7 @@  static const MemoryRegionOps ich9_memhp_ops = {
         },
         {
             .offset = ICH9_MEM_EJ_BASE - ICH9_MEM_BASE,
-            .len = 4, .size = 1,
+            .len = 5, .size = 1,
             .write = memhp_writeb,
         },
         PORTIO_END_OF_LIST()
@@ -321,7 +324,7 @@  void ich9_pm_init(void *device, qemu_irq sci_irq, qemu_irq cmos_s3)
     memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
 
     memory_region_init_io(&pm->io_memhp, &ich9_memhp_ops, pm, "apci-memhp0",
-                          DIMM_BITMAP_BYTES + 4);
+                          DIMM_BITMAP_BYTES + 5);
     memory_region_add_subregion(get_system_io(), ICH9_MEM_BASE, &pm->io_memhp);
 
     dimm_bus_hotplug(ich9_dimm_hotplug, ich9_dimm_revert, &lpc->d.qdev);
diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
index 8f57cd8..816d453 100644
--- a/hw/acpi_ich9.h
+++ b/hw/acpi_ich9.h
@@ -29,6 +29,7 @@ 
 #define ICH9_MEM_OST_REMOVE_FAIL 0xafa1
 #define ICH9_MEM_OST_ADD_SUCCESS 0xafa2
 #define ICH9_MEM_OST_ADD_FAIL 0xafa3
+#define ICH9_MEM_PS3 0xafa4
 
 typedef struct ICH9LPCPMRegs {
     /*
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 70aa480..6c953c2 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -54,6 +54,7 @@ 
 #define MEM_OST_REMOVE_FAIL 0xafa1
 #define MEM_OST_ADD_SUCCESS 0xafa2
 #define MEM_OST_ADD_FAIL 0xafa3
+#define MEM_PS3 0xafa4
 
 #define PIIX4_MEM_HOTPLUG_STATUS 8
 #define PIIX4_PCI_HOTPLUG_STATUS 2
@@ -564,6 +565,9 @@  static void memhp_writeb(void *opaque, uint32_t addr, uint32_t val)
     case MEM_OST_ADD_FAIL - MEM_BASE:
         dimm_notify(val, DIMM_ADD_FAIL);
         break;
+    case MEM_PS3 - MEM_BASE:
+        dimm_notify(val, DIMM_OSPM_POWEROFF);
+        break;
     default:
         PIIX4_DPRINTF("memhp write invalid %x <== %d\n", addr, val);
     }
@@ -577,7 +581,7 @@  static const MemoryRegionOps piix4_memhp_ops = {
             .read = memhp_readb,
         },
         {
-            .offset = MEM_EJ_BASE - MEM_BASE, .len = 4,
+            .offset = MEM_EJ_BASE - MEM_BASE, .len = 5,
             .size = 1,
             .write = memhp_writeb,
         },
@@ -666,7 +670,7 @@  static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
     memory_region_add_subregion(get_system_io(), PCI_HOTPLUG_ADDR,
                                 &s->io_pci);
     memory_region_init_io(&s->io_memhp, &piix4_memhp_ops, s, "apci-memhp0",
-                          DIMM_BITMAP_BYTES + 4);
+                          DIMM_BITMAP_BYTES + 5);
     memory_region_add_subregion(get_system_io(), MEM_BASE, &s->io_memhp);
 
     for (i = 0; i < DIMM_BITMAP_BYTES; i++) {
@@ -726,7 +730,6 @@  static int piix4_dimm_revert(DeviceState *qdev, DimmDevice *dev, int add)
     struct gpe_regs *g = &s->gperegs;
     DimmDevice *slot = DIMM(dev);
     int idx = slot->idx;
-
     if (add) {
         g->mems_sts[idx/8] &= ~(1 << (idx%8));
     } else {
diff --git a/hw/dimm.c b/hw/dimm.c
index 69b97b6..2454e38 100644
--- a/hw/dimm.c
+++ b/hw/dimm.c
@@ -407,6 +407,10 @@  void dimm_notify(uint32_t idx, uint32_t event)
         qdev_unplug_complete((DeviceState *)slot, NULL);
         QTAILQ_REMOVE(&bus->dimmlist, slot, nextdimm);
         QTAILQ_INSERT_TAIL(&bus->dimm_hp_result_queue, result, next);
+    case DIMM_OSPM_POWEROFF:
+        if (bus->dimm_revert) {
+            bus->dimm_revert(bus->dimm_hotplug_qdev, slot, 1);
+        }
     default:
         g_free(result);
         break;
diff --git a/hw/dimm.h b/hw/dimm.h
index f43f745..081f2db 100644
--- a/hw/dimm.h
+++ b/hw/dimm.h
@@ -15,7 +15,8 @@  typedef enum {
     DIMM_REMOVE_SUCCESS = 0,
     DIMM_REMOVE_FAIL = 1,
     DIMM_ADD_SUCCESS = 2,
-    DIMM_ADD_FAIL = 3
+    DIMM_ADD_FAIL = 3,
+    DIMM_OSPM_POWEROFF = 4
 } dimm_hp_result_code;
 
 typedef enum {