qemu: initialize hot add system / acpi gpe (Marcelo Tosatti)
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 11 Feb 2009 15:21:35 +0000 (15:21 +0000)
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 11 Feb 2009 15:21:35 +0000 (15:21 +0000)
ACPI GPE support, used by PCI (and CPU) hotplug.

From: Glauber Costa <gcosta@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6607 c046a42c-6fe2-441c-8c8c-71466251a162

hw/acpi.c
hw/pc.c
sysemu.h

index 4338d02..a6284bf 100644 (file)
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -561,3 +561,71 @@ void qemu_system_powerdown(void)
     }
 }
 #endif
+
+#define GPE_BASE 0xafe0
+
+struct gpe_regs {
+    uint16_t sts; /* status */
+    uint16_t en;  /* enabled */
+};
+
+static struct gpe_regs gpe;
+
+static uint32_t gpe_readb(void *opaque, uint32_t addr)
+{
+    uint32_t val = 0;
+    struct gpe_regs *g = opaque;
+    switch (addr) {
+        case GPE_BASE:
+            val = g->sts & 0xFF;
+            break;
+        case GPE_BASE + 1:
+            val =  (g->sts >> 8) & 0xFF;
+            break;
+        case GPE_BASE + 2:
+            val =  g->en & 0xFF;
+            break;
+        case GPE_BASE + 3:
+            val =  (g->en >> 8) & 0xFF;
+            break;
+        default:
+            break;
+    }
+
+#if defined(DEBUG)
+    printf("gpe read %lx == %lx\n", addr, val);
+#endif
+    return val;
+}
+
+static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    struct gpe_regs *g = opaque;
+    switch (addr) {
+        case GPE_BASE:
+            g->sts = (g->sts & ~0xFFFF) | (val & 0xFFFF);
+            break;
+        case GPE_BASE + 1:
+            g->sts = (g->sts & 0xFFFF) | (val << 8);
+            break;
+        case GPE_BASE + 2:
+            g->en = (g->en & ~0xFFFF) | (val & 0xFFFF);
+            break;
+        case GPE_BASE + 3:
+            g->en = (g->en & 0xFFFF) | (val << 8);
+            break;
+        default:
+            break;
+   }
+
+#if defined(DEBUG)
+    printf("gpe write %lx <== %d\n", addr, val);
+#endif
+}
+
+void qemu_system_hot_add_init(void)
+{
+    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
+    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
+
+}
diff --git a/hw/pc.c b/hw/pc.c
index 176730e..57ba803 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1010,6 +1010,8 @@ vga_bios_error:
             pci_nic_init(pci_bus, nd, -1, "ne2k_pci");
     }
 
+    qemu_system_hot_add_init();
+
     if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
         fprintf(stderr, "qemu: too many IDE bus\n");
         exit(1);
index 2cd16b1..44bfd60 100644 (file)
--- a/sysemu.h
+++ b/sysemu.h
@@ -166,6 +166,9 @@ extern int nb_drives_opt;
 extern int drive_add(const char *file, const char *fmt, ...);
 extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
 
+/* acpi */
+void qemu_system_hot_add_init(void);
+
 /* serial ports */
 
 #define MAX_SERIAL_PORTS 4