Patchwork [RFC,v4,25/30] acpi_ich9: add hot-remove capability

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

Comments

Vasilis Liaskovitis - Dec. 18, 2012, 12:41 p.m.
---
 hw/acpi_ich9.c |   28 +++++++++++++++++++++++++++-
 hw/acpi_ich9.h |    1 +
 2 files changed, 28 insertions(+), 1 deletions(-)
Blue Swirl - Dec. 19, 2012, 7:48 p.m.
On Tue, Dec 18, 2012 at 12:41 PM, Vasilis Liaskovitis
<vasilis.liaskovitis@profitbricks.com> wrote:
> ---
>  hw/acpi_ich9.c |   28 +++++++++++++++++++++++++++-
>  hw/acpi_ich9.h |    1 +
>  2 files changed, 28 insertions(+), 1 deletions(-)
>
> diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
> index abafbb5..f5dc1c9 100644
> --- a/hw/acpi_ich9.c
> +++ b/hw/acpi_ich9.c
> @@ -105,12 +105,29 @@ static uint32_t memhp_readb(void *opaque, uint32_t addr)
>      return val;
>  }
>
> +static void memhp_writeb(void *opaque, uint32_t addr, uint32_t val)
> +{
> +    switch (addr) {
> +    case ICH9_MEM_EJ_BASE - ICH9_MEM_BASE:
> +        dimm_notify(val, DIMM_REMOVE_SUCCESS);
> +        break;
> +    default:
> +        ICH9_DEBUG("memhp write invalid %x <== %d\n", addr, val);
> +    }
> +    ICH9_DEBUG("memhp write %x <== %d\n", addr, val);
> +}
> +
>  static const MemoryRegionOps ich9_memhp_ops = {
>      .old_portio = (MemoryRegionPortio[]) {
>          {
>              .offset = 0,   .len = DIMM_BITMAP_BYTES, .size = 1,
>              .read = memhp_readb,
>          },
> +        {
> +            .offset = ICH9_MEM_EJ_BASE - ICH9_MEM_BASE,
> +            .len = 1, .size = 1,
> +            .write = memhp_writeb,
> +        },
>          PORTIO_END_OF_LIST()
>      },
>      .endianness = DEVICE_LITTLE_ENDIAN,
> @@ -234,6 +251,13 @@ static void enable_mem_device(ICH9LPCState *s, int memdevice)
>      g->mems_sts[memdevice/8] |= (1 << (memdevice%8));
>  }
>
> +static void disable_mem_device(ICH9LPCState *s, int memdevice)
> +{
> +    struct gpe_regs *g = &s->pm.gperegs;
> +    s->pm.acpi_regs.gpe.sts[0] |= ICH9_MEM_HOTPLUG_STATUS;
> +    g->mems_sts[memdevice/8] &= ~(1 << (memdevice%8));

Spaces around '/' and '%'.

> +}
> +
>  static int ich9_dimm_hotplug(DeviceState *qdev, DimmDevice *dev, int
>          add)
>  {
> @@ -243,6 +267,8 @@ static int ich9_dimm_hotplug(DeviceState *qdev, DimmDevice *dev, int
>
>      if (add) {
>          enable_mem_device(s, slot->idx);
> +    } else {
> +        disable_mem_device(s, slot->idx);
>      }
>      pm_update_sci(&s->pm);
>      return 0;
> @@ -270,7 +296,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);
> +                          DIMM_BITMAP_BYTES + 1);
>      memory_region_add_subregion(get_system_io(), ICH9_MEM_BASE, &pm->io_memhp);
>
>      dimm_bus_hotplug(ich9_dimm_hotplug, &lpc->d.qdev);
> diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
> index 4419247..af61a2d 100644
> --- a/hw/acpi_ich9.h
> +++ b/hw/acpi_ich9.h
> @@ -24,6 +24,7 @@
>  #include "acpi.h"
>
>  #define ICH9_MEM_BASE    0xaf80
> +#define ICH9_MEM_EJ_BASE    0xafa0
>  #define ICH9_MEM_HOTPLUG_STATUS 8
>
>  typedef struct ICH9LPCPMRegs {
> --
> 1.7.9
>

Patch

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index abafbb5..f5dc1c9 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -105,12 +105,29 @@  static uint32_t memhp_readb(void *opaque, uint32_t addr)
     return val;
 }
 
+static void memhp_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    switch (addr) {
+    case ICH9_MEM_EJ_BASE - ICH9_MEM_BASE:
+        dimm_notify(val, DIMM_REMOVE_SUCCESS);
+        break;
+    default:
+        ICH9_DEBUG("memhp write invalid %x <== %d\n", addr, val);
+    }
+    ICH9_DEBUG("memhp write %x <== %d\n", addr, val);
+}
+
 static const MemoryRegionOps ich9_memhp_ops = {
     .old_portio = (MemoryRegionPortio[]) {
         {
             .offset = 0,   .len = DIMM_BITMAP_BYTES, .size = 1,
             .read = memhp_readb,
         },
+        {
+            .offset = ICH9_MEM_EJ_BASE - ICH9_MEM_BASE,
+            .len = 1, .size = 1,
+            .write = memhp_writeb,
+        },
         PORTIO_END_OF_LIST()
     },
     .endianness = DEVICE_LITTLE_ENDIAN,
@@ -234,6 +251,13 @@  static void enable_mem_device(ICH9LPCState *s, int memdevice)
     g->mems_sts[memdevice/8] |= (1 << (memdevice%8));
 }
 
+static void disable_mem_device(ICH9LPCState *s, int memdevice)
+{
+    struct gpe_regs *g = &s->pm.gperegs;
+    s->pm.acpi_regs.gpe.sts[0] |= ICH9_MEM_HOTPLUG_STATUS;
+    g->mems_sts[memdevice/8] &= ~(1 << (memdevice%8));
+}
+
 static int ich9_dimm_hotplug(DeviceState *qdev, DimmDevice *dev, int
         add)
 {
@@ -243,6 +267,8 @@  static int ich9_dimm_hotplug(DeviceState *qdev, DimmDevice *dev, int
 
     if (add) {
         enable_mem_device(s, slot->idx);
+    } else {
+        disable_mem_device(s, slot->idx);
     }
     pm_update_sci(&s->pm);
     return 0;
@@ -270,7 +296,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);
+                          DIMM_BITMAP_BYTES + 1);
     memory_region_add_subregion(get_system_io(), ICH9_MEM_BASE, &pm->io_memhp);
 
     dimm_bus_hotplug(ich9_dimm_hotplug, &lpc->d.qdev);
diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
index 4419247..af61a2d 100644
--- a/hw/acpi_ich9.h
+++ b/hw/acpi_ich9.h
@@ -24,6 +24,7 @@ 
 #include "acpi.h"
 
 #define ICH9_MEM_BASE    0xaf80
+#define ICH9_MEM_EJ_BASE    0xafa0
 #define ICH9_MEM_HOTPLUG_STATUS 8
 
 typedef struct ICH9LPCPMRegs {