All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support
@ 2015-02-17 10:09 Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller Shannon Zhao
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:09 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add cpu-add hotplug support in machine virt. As there are some properties
which are set out of arm_cpu_initfn, so the way of device_add is not
supported now. This will add at next version. Some good suggestion?

This patchset is based on below patch:
[RFC PATCH v3 00/11] Generate ACPI v5.1 tables and	expose it to guest over fw_cfg on ARM
http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg03290.html

Have done compile test and start a Linux guest, execute cpu-add in monitor, use info cpu
to check a new cpu created. But as the guest kernel driver is not ready, so it can't be
used by guest now.

Any comments are welcome.
Thanks,
Shannon

Shannon Zhao (7):
  hw/arm/virt: Add a GPIO controller
  hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table
  hw/acpi/virt-hotplug: Add a hotplug device for machine virt
  topology: Move topology.h to an arch-independent location
  target-arm/cpu: Add apic_id property for ARMCPU
  hw/arm/virt: Add cpu hotplug support
  hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI

 default-configs/arm-softmmu.mak  |    2 +
 hw/acpi/Makefile.objs            |    1 +
 hw/acpi/aml-build.c              |  135 ++++++++++++++++++++++++++
 hw/acpi/cpu_hotplug.c            |   16 +---
 hw/acpi/ich9.c                   |   12 +++
 hw/acpi/piix4.c                  |   12 +++
 hw/acpi/virt-hotplug.c           |  141 +++++++++++++++++++++++++++
 hw/arm/virt-acpi-build.c         |  198 +++++++++++++++++++++++++++++++++++++-
 hw/arm/virt.c                    |  190 ++++++++++++++++++++++++++++++++++++-
 include/hw/acpi/aml-build.h      |   13 +++
 include/hw/acpi/cpu_hotplug.h    |    6 +-
 include/hw/acpi/topology.h       |  134 +++++++++++++++++++++++++
 include/hw/acpi/virt-hotplug.h   |   11 ++
 include/hw/arm/virt-acpi-build.h |    3 +
 target-arm/cpu-qom.h             |    1 +
 target-arm/cpu.c                 |   77 +++++++++++++++
 target-arm/cpu.h                 |    2 +
 target-i386/cpu.c                |    4 +-
 target-i386/topology.h           |  134 -------------------------
 tests/test-x86-cpuid.c           |   10 +-
 20 files changed, 940 insertions(+), 162 deletions(-)
 create mode 100644 hw/acpi/virt-hotplug.c
 create mode 100644 include/hw/acpi/topology.h
 create mode 100644 include/hw/acpi/virt-hotplug.h
 delete mode 100644 target-i386/topology.h

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-18 17:52   ` Wei Huang
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 2/7] hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table Shannon Zhao
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add a GPIO controller in machine virt, in order to support cpu hotplug.
Here we use pl061.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 hw/arm/virt.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8a00574..43c0260 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -75,6 +75,7 @@ enum {
     VIRT_MMIO,
     VIRT_RTC,
     VIRT_FW_CFG,
+    VIRT_GPIO,
 };
 
 typedef struct MemMapEntry {
@@ -133,6 +134,7 @@ static const MemMapEntry a15memmap[] = {
     [VIRT_UART] =       { 0x09000000, 0x00001000 },
     [VIRT_RTC] =        { 0x09010000, 0x00001000 },
     [VIRT_FW_CFG] =     { 0x09020000, 0x0000000a },
+    [VIRT_GPIO] =       { 0x09500000, 0x00001000 },
     [VIRT_MMIO] =       { 0x0a000000, 0x00000200 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
     /* 0x10000000 .. 0x40000000 reserved for PCI */
@@ -142,6 +144,7 @@ static const MemMapEntry a15memmap[] = {
 static const int a15irqmap[] = {
     [VIRT_UART] = 1,
     [VIRT_RTC] = 2,
+    [VIRT_GPIO] = 3,
     [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
 };
 
@@ -465,6 +468,29 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
     g_free(nodename);
 }
 
+static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename;
+    hwaddr base = vbi->memmap[VIRT_GPIO].base;
+    hwaddr size = vbi->memmap[VIRT_GPIO].size;
+    int irq = vbi->irqmap[VIRT_GPIO];
+    const char compat[] = "arm,pl061\0arm,primecell";
+
+    sysbus_create_simple("pl061", base, pic[irq]);
+
+    nodename = g_strdup_printf("/pl061@%" PRIx64, base);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                 2, base, 2, size);
+    qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
+    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#gpio-cells", 2);
+    qemu_fdt_setprop(vbi->fdt, nodename, "gpio-controller", NULL, 0);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
+                           GIC_FDT_IRQ_TYPE_SPI, irq,
+                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+    g_free(nodename);
+}
+
 static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
 {
     int i;
@@ -680,6 +706,8 @@ static void machvirt_init(MachineState *machine)
 
     create_rtc(vbi, pic);
 
+    create_gpio(vbi, pic);
+
     /* Create mmio transports, so the user can create virtio backends
      * (which will be automatically plugged in to the transports). If
      * no backend is created the transport will just sit harmlessly idle.
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 2/7] hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 3/7] hw/acpi/virt-hotplug: Add a hotplug device for machine virt Shannon Zhao
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add GPIO controller in ACPI DSDT table. It can be used
for device hotplug.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 hw/arm/virt-acpi-build.c         |   21 +++++++++++++++++++++
 hw/arm/virt.c                    |    2 ++
 include/hw/arm/virt-acpi-build.h |    2 ++
 3 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index bfbddbe..4f26551 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -176,6 +176,26 @@ static void acpi_dsdt_add_virtio(Aml *scope, const hwaddr *mmio_addrs,
     }
 }
 
+static void acpi_dsdt_add_gpio(Aml *scope, const hwaddr *gpio_addrs,
+                                           const int *gpio_irq)
+{
+    Aml *dev, *crs;
+
+    dev = aml_device("GPO0");
+    aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0009")));
+    aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
+    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+    crs = aml_resource_template();
+    aml_append(crs,
+               aml_memory32_fixed(gpio_addrs[0], gpio_addrs[1], 0x01));
+    aml_append(crs,
+               aml_interrupt(0x01, *gpio_irq + 32));
+    aml_append(dev, aml_name_decl("_CRS", crs));
+
+    aml_append(scope, dev);
+}
+
 /* RSDP */
 static GArray *
 build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
@@ -343,6 +363,7 @@ build_dsdt(Aml *table_data, GArray *linker, VirtGuestInfo *guest_info)
     acpi_dsdt_add_flash(scope, info->flash_addr);
     acpi_dsdt_add_virtio(scope, info->virtio_mmio_addr,
              info->virtio_mmio_irq, info->virtio_mmio_num);
+    acpi_dsdt_add_gpio(scope, info->gpio_addr, info->gpio_irq);
 
     aml_append(dsdt, scope);
     aml_append(table_data, dsdt);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 43c0260..f689bc3 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -159,6 +159,8 @@ static const struct acpi_dsdt_info dsdt_info = {
     .virtio_mmio_addr = &a15memmap[VIRT_MMIO].base,
     .virtio_mmio_irq = &a15irqmap[VIRT_MMIO],
     .virtio_mmio_num = NUM_VIRTIO_TRANSPORTS,
+    .gpio_addr = &a15memmap[VIRT_GPIO].base,
+    .gpio_irq = &a15irqmap[VIRT_GPIO],
     .rtc_addr = &a15memmap[VIRT_RTC].base,
     .rtc_irq = &a15irqmap[VIRT_RTC],
     .flash_addr = &a15memmap[VIRT_FLASH].base,
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index 451edc9..de8d4c6 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -47,6 +47,8 @@ struct acpi_dsdt_info {
     const hwaddr *virtio_mmio_addr;
     const int *virtio_mmio_irq;
     int virtio_mmio_num;
+    const hwaddr *gpio_addr;
+    const int *gpio_irq;
     const hwaddr *rtc_addr;
     const int *rtc_irq;
     const hwaddr *flash_addr;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 3/7] hw/acpi/virt-hotplug: Add a hotplug device for machine virt
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 2/7] hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 4/7] topology: Move topology.h to an arch-independent location Shannon Zhao
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add a hotplug device for machine virt. This can be used for virt
to support device hotplug. At the moment this hotplug device just
include a mmio region which shows the present status of cpus.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 default-configs/arm-softmmu.mak |    2 +
 hw/acpi/Makefile.objs           |    1 +
 hw/acpi/cpu_hotplug.c           |   16 +----
 hw/acpi/ich9.c                  |   12 ++++
 hw/acpi/piix4.c                 |   12 ++++
 hw/acpi/virt-hotplug.c          |  130 +++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/cpu_hotplug.h   |    6 +-
 include/hw/acpi/virt-hotplug.h  |   10 +++
 8 files changed, 172 insertions(+), 17 deletions(-)
 create mode 100644 hw/acpi/virt-hotplug.c
 create mode 100644 include/hw/acpi/virt-hotplug.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 3c89f53..bb74707 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -89,3 +89,5 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 CONFIG_ACPI=y
+CONFIG_VIRT_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 511771a..4bc5a4d 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -4,3 +4,4 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
 common-obj-$(CONFIG_ACPI) += aml-build.o
+common-obj-$(CONFIG_VIRT_HOTPLUG) += virt-hotplug.o
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index b8ebfad..dbc7e94 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,7 +36,7 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
     },
 };
 
-static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
+void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
                                      Error **errp)
 {
     CPUClass *k = CPU_GET_CLASS(cpu);
@@ -51,20 +51,8 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
     g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 }
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
-{
-    acpi_set_cpu_present_bit(g, CPU(dev), errp);
-    if (*errp != NULL) {
-        return;
-    }
-
-    ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
-    acpi_update_sci(ar, irq);
-}
-
 void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
-                           AcpiCpuHotplug *gpe_cpu, uint16_t base)
+                           AcpiCpuHotplug *gpe_cpu, uint64_t base)
 {
     CPUState *cpu;
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 5352e19..6c4422a 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -383,6 +383,18 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
                         NULL, pm, NULL);
 }
 
+static void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+    acpi_set_cpu_present_bit(g, CPU(dev), errp);
+    if (*errp != NULL) {
+        return;
+    }
+
+    ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+    acpi_update_sci(ar, irq);
+}
+
 void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
 {
     if (pm->acpi_memory_hotplug.is_enabled &&
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index d1f1179..6faca8a 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -337,6 +337,18 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
     acpi_pm1_evt_power_down(&s->ar);
 }
 
+static void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+    acpi_set_cpu_present_bit(g, CPU(dev), errp);
+    if (*errp != NULL) {
+        return;
+    }
+
+    ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+    acpi_update_sci(ar, irq);
+}
+
 static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
                                  DeviceState *dev, Error **errp)
 {
diff --git a/hw/acpi/virt-hotplug.c b/hw/acpi/virt-hotplug.c
new file mode 100644
index 0000000..47da078
--- /dev/null
+++ b/hw/acpi/virt-hotplug.c
@@ -0,0 +1,130 @@
+/*
+ *
+ * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * Author: Shannon Zhao <zhaoshenglong@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/hw.h"
+#include "hw/acpi/acpi.h"
+#include "sysemu/sysemu.h"
+#include "qemu/range.h"
+#include "exec/address-spaces.h"
+#include "hw/acpi/cpu_hotplug.h"
+#include "hw/hotplug.h"
+#include "hw/acpi/acpi_dev_interface.h"
+#include "hw/sysbus.h"
+#include "hw/acpi/virt-hotplug.h"
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+# define VIRT_HOTPLUG_DPRINTF(format, ...)     printf(format, ## __VA_ARGS__)
+#else
+# define VIRT_HOTPLUG_DPRINTF(format, ...)     do { } while (0)
+#endif
+
+typedef struct VIRTHOTPLUGState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+    AcpiCpuHotplug gpe_cpu;
+} VIRTHOTPLUGState;
+
+#define TYPE_VIRT_HOTPLUG "VIRT_HOTPLUG"
+
+#define VIRT_HOTPLUG(obj) \
+    OBJECT_CHECK(VIRTHOTPLUGState, (obj), TYPE_VIRT_HOTPLUG)
+
+static void virt_acpi_cpu_plug_cb(AcpiCpuHotplug *g,
+                                  DeviceState *dev, Error **errp)
+{
+    acpi_set_cpu_present_bit(g, CPU(dev), errp);
+    if (*errp != NULL) {
+        return;
+    }
+
+    bool ambig;
+    Object *o = object_resolve_path_type("", "pl061", &ambig);
+    /* use gpio 2 for cpu plug event */
+    qemu_set_irq(qdev_get_gpio_in(DEVICE(o), 2), 1);
+}
+
+static void virt_device_plug_cb(HotplugHandler *hotplug_dev,
+                                 DeviceState *dev, Error **errp)
+{
+    VIRTHOTPLUGState *s = VIRT_HOTPLUG(hotplug_dev);
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+        virt_acpi_cpu_plug_cb(&s->gpe_cpu, dev, errp);
+    } else {
+        error_setg(errp, "acpi: device plug request for not supported device"
+                   " type: %s", object_get_typename(OBJECT(dev)));
+    }
+}
+
+static int virt_hotplug_initfn(SysBusDevice *sbd)
+{
+    DeviceState *dev = DEVICE(sbd);
+    VIRTHOTPLUGState *s = VIRT_HOTPLUG(dev);
+
+    acpi_cpu_hotplug_init(get_system_memory(), OBJECT(s),
+                          &s->gpe_cpu, VIRT_CPU_HOTPLUG_MMIO_BASE);
+    return 0;
+}
+
+void virt_hotplug_init(DeviceState **virt_hotplug)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, TYPE_VIRT_HOTPLUG);
+    if (virt_hotplug) {
+        *virt_hotplug = dev;
+    }
+    qdev_init_nofail(dev);
+}
+
+static void virt_hotplug_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
+
+    k->init = virt_hotplug_initfn;
+
+    dc->desc = "VIRT_HOTPLUG";
+    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->hotpluggable = false;
+    hc->plug = virt_device_plug_cb;
+}
+
+static const TypeInfo virt_hotplug_info = {
+    .name          = TYPE_VIRT_HOTPLUG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(VIRTHOTPLUGState),
+    .class_init    = virt_hotplug_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_HOTPLUG_HANDLER },
+        { TYPE_ACPI_DEVICE_IF },
+        { }
+    }
+};
+
+static void virt_hotplug_register_types(void)
+{
+    type_register_static(&virt_hotplug_info);
+}
+
+type_init(virt_hotplug_register_types)
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index f6d358d..5cb43f4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,9 +20,9 @@ typedef struct AcpiCpuHotplug {
     uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
+void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
+                                     Error **errp);
 
 void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
-                           AcpiCpuHotplug *gpe_cpu, uint16_t base);
+                           AcpiCpuHotplug *gpe_cpu, uint64_t base);
 #endif
diff --git a/include/hw/acpi/virt-hotplug.h b/include/hw/acpi/virt-hotplug.h
new file mode 100644
index 0000000..a668d16
--- /dev/null
+++ b/include/hw/acpi/virt-hotplug.h
@@ -0,0 +1,10 @@
+#ifndef HW_ACPI_VIRT_HOTPLUG_H
+#define HW_ACPI_VIRT_HOTPLUG_H
+
+#include "qemu/typedefs.h"
+
+#define VIRT_CPU_HOTPLUG_MMIO_BASE 0x09600000
+
+void virt_hotplug_init(DeviceState **virt_hotplug);
+
+#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 4/7] topology: Move topology.h to an arch-independent location
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
                   ` (2 preceding siblings ...)
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 3/7] hw/acpi/virt-hotplug: Add a hotplug device for machine virt Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU Shannon Zhao
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Move topology.h to an arch-independent location and the apicid_foo
can be reused by other architectures. And remove the x86 prefix.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 include/hw/acpi/topology.h |  134 ++++++++++++++++++++++++++++++++++++++++++++
 target-i386/cpu.c          |    4 +-
 target-i386/topology.h     |  134 --------------------------------------------
 tests/test-x86-cpuid.c     |   10 ++--
 4 files changed, 141 insertions(+), 141 deletions(-)
 create mode 100644 include/hw/acpi/topology.h
 delete mode 100644 target-i386/topology.h

diff --git a/include/hw/acpi/topology.h b/include/hw/acpi/topology.h
new file mode 100644
index 0000000..f341190
--- /dev/null
+++ b/include/hw/acpi/topology.h
@@ -0,0 +1,134 @@
+/*
+ *  CPU topology data structures and functions
+ *
+ *  Copyright (c) 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef TARGET_ACPI_TOPOLOGY_H
+#define TARGET_ACPI_TOPOLOGY_H
+
+/* This file implements the APIC-ID-based CPU topology enumeration logic,
+ * documented at the following document:
+ *   Intel® 64 Architecture Processor Topology Enumeration
+ *   http://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/
+ *
+ * This code should be compatible with AMD's "Extended Method" described at:
+ *   AMD CPUID Specification (Publication #25481)
+ *   Section 3: Multiple Core Calcuation
+ * as long as:
+ *  nr_threads is set to 1;
+ *  OFFSET_IDX is assumed to be 0;
+ *  CPUID Fn8000_0008_ECX[ApicIdCoreIdSize[3:0]] is set to apicid_core_width().
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include "qemu/bitops.h"
+
+/* APIC IDs can be 32-bit, but beware: APIC IDs > 255 require x2APIC support
+ */
+typedef uint32_t apic_id_t;
+
+/* Return the bit width needed for 'count' IDs
+ */
+static unsigned apicid_bitwidth_for_count(unsigned count)
+{
+    g_assert(count >= 1);
+    count -= 1;
+    return count ? 32 - clz32(count) : 0;
+}
+
+/* Bit width of the SMT_ID (thread ID) field on the APIC ID
+ */
+static inline unsigned apicid_smt_width(unsigned nr_cores, unsigned nr_threads)
+{
+    return apicid_bitwidth_for_count(nr_threads);
+}
+
+/* Bit width of the Core_ID field
+ */
+static inline unsigned apicid_core_width(unsigned nr_cores, unsigned nr_threads)
+{
+    return apicid_bitwidth_for_count(nr_cores);
+}
+
+/* Bit offset of the Core_ID field
+ */
+static inline unsigned apicid_core_offset(unsigned nr_cores,
+                                          unsigned nr_threads)
+{
+    return apicid_smt_width(nr_cores, nr_threads);
+}
+
+/* Bit offset of the Pkg_ID (socket ID) field
+ */
+static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned nr_threads)
+{
+    return apicid_core_offset(nr_cores, nr_threads) +
+           apicid_core_width(nr_cores, nr_threads);
+}
+
+/* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
+ *
+ * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
+ */
+static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores,
+                                             unsigned nr_threads,
+                                             unsigned pkg_id,
+                                             unsigned core_id,
+                                             unsigned smt_id)
+{
+    return (pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
+           (core_id << apicid_core_offset(nr_cores, nr_threads)) |
+           smt_id;
+}
+
+/* Calculate thread/core/package IDs for a specific topology,
+ * based on (contiguous) CPU index
+ */
+static inline void topo_ids_from_idx(unsigned nr_cores,
+                                         unsigned nr_threads,
+                                         unsigned cpu_index,
+                                         unsigned *pkg_id,
+                                         unsigned *core_id,
+                                         unsigned *smt_id)
+{
+    unsigned core_index = cpu_index / nr_threads;
+    *smt_id = cpu_index % nr_threads;
+    *core_id = core_index % nr_cores;
+    *pkg_id = core_index / nr_cores;
+}
+
+/* Make APIC ID for the CPU 'cpu_index'
+ *
+ * 'cpu_index' is a sequential, contiguous ID for the CPU.
+ */
+static inline apic_id_t apicid_from_cpu_idx(unsigned nr_cores,
+                                                unsigned nr_threads,
+                                                unsigned cpu_index)
+{
+    unsigned pkg_id, core_id, smt_id;
+    topo_ids_from_idx(nr_cores, nr_threads, cpu_index,
+                          &pkg_id, &core_id, &smt_id);
+    return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
+}
+
+#endif /* TARGET_I386_TOPOLOGY_H */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 3a9b32e..739c447 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -25,7 +25,7 @@
 #include "sysemu/kvm.h"
 #include "sysemu/cpus.h"
 #include "kvm_i386.h"
-#include "topology.h"
+#include "hw/acpi/topology.h"
 
 #include "qemu/option.h"
 #include "qemu/config-file.h"
@@ -2865,7 +2865,7 @@ uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
     uint32_t correct_id;
     static bool warned;
 
-    correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
+    correct_id = apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
     if (compat_apic_id_mode) {
         if (cpu_index != correct_id && !warned) {
             error_report("APIC IDs set in compatibility mode, "
diff --git a/target-i386/topology.h b/target-i386/topology.h
deleted file mode 100644
index 07a6c5f..0000000
--- a/target-i386/topology.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  x86 CPU topology data structures and functions
- *
- *  Copyright (c) 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef TARGET_I386_TOPOLOGY_H
-#define TARGET_I386_TOPOLOGY_H
-
-/* This file implements the APIC-ID-based CPU topology enumeration logic,
- * documented at the following document:
- *   Intel® 64 Architecture Processor Topology Enumeration
- *   http://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/
- *
- * This code should be compatible with AMD's "Extended Method" described at:
- *   AMD CPUID Specification (Publication #25481)
- *   Section 3: Multiple Core Calcuation
- * as long as:
- *  nr_threads is set to 1;
- *  OFFSET_IDX is assumed to be 0;
- *  CPUID Fn8000_0008_ECX[ApicIdCoreIdSize[3:0]] is set to apicid_core_width().
- */
-
-#include <stdint.h>
-#include <string.h>
-
-#include "qemu/bitops.h"
-
-/* APIC IDs can be 32-bit, but beware: APIC IDs > 255 require x2APIC support
- */
-typedef uint32_t apic_id_t;
-
-/* Return the bit width needed for 'count' IDs
- */
-static unsigned apicid_bitwidth_for_count(unsigned count)
-{
-    g_assert(count >= 1);
-    count -= 1;
-    return count ? 32 - clz32(count) : 0;
-}
-
-/* Bit width of the SMT_ID (thread ID) field on the APIC ID
- */
-static inline unsigned apicid_smt_width(unsigned nr_cores, unsigned nr_threads)
-{
-    return apicid_bitwidth_for_count(nr_threads);
-}
-
-/* Bit width of the Core_ID field
- */
-static inline unsigned apicid_core_width(unsigned nr_cores, unsigned nr_threads)
-{
-    return apicid_bitwidth_for_count(nr_cores);
-}
-
-/* Bit offset of the Core_ID field
- */
-static inline unsigned apicid_core_offset(unsigned nr_cores,
-                                          unsigned nr_threads)
-{
-    return apicid_smt_width(nr_cores, nr_threads);
-}
-
-/* Bit offset of the Pkg_ID (socket ID) field
- */
-static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned nr_threads)
-{
-    return apicid_core_offset(nr_cores, nr_threads) +
-           apicid_core_width(nr_cores, nr_threads);
-}
-
-/* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
- *
- * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
- */
-static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores,
-                                             unsigned nr_threads,
-                                             unsigned pkg_id,
-                                             unsigned core_id,
-                                             unsigned smt_id)
-{
-    return (pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
-           (core_id << apicid_core_offset(nr_cores, nr_threads)) |
-           smt_id;
-}
-
-/* Calculate thread/core/package IDs for a specific topology,
- * based on (contiguous) CPU index
- */
-static inline void x86_topo_ids_from_idx(unsigned nr_cores,
-                                         unsigned nr_threads,
-                                         unsigned cpu_index,
-                                         unsigned *pkg_id,
-                                         unsigned *core_id,
-                                         unsigned *smt_id)
-{
-    unsigned core_index = cpu_index / nr_threads;
-    *smt_id = cpu_index % nr_threads;
-    *core_id = core_index % nr_cores;
-    *pkg_id = core_index / nr_cores;
-}
-
-/* Make APIC ID for the CPU 'cpu_index'
- *
- * 'cpu_index' is a sequential, contiguous ID for the CPU.
- */
-static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_cores,
-                                                unsigned nr_threads,
-                                                unsigned cpu_index)
-{
-    unsigned pkg_id, core_id, smt_id;
-    x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index,
-                          &pkg_id, &core_id, &smt_id);
-    return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
-}
-
-#endif /* TARGET_I386_TOPOLOGY_H */
diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c
index 8d9f96a..d37e0c1 100644
--- a/tests/test-x86-cpuid.c
+++ b/tests/test-x86-cpuid.c
@@ -24,7 +24,7 @@
 
 #include <glib.h>
 
-#include "topology.h"
+#include "hw/acpi/topology.h"
 
 static void test_topo_bits(void)
 {
@@ -32,10 +32,10 @@ static void test_topo_bits(void)
     g_assert_cmpuint(apicid_smt_width(1, 1), ==, 0);
     g_assert_cmpuint(apicid_core_width(1, 1), ==, 0);
 
-    g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 0), ==, 0);
-    g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1), ==, 1);
-    g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 2), ==, 2);
-    g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 3), ==, 3);
+    g_assert_cmpuint(apicid_from_cpu_idx(1, 1, 0), ==, 0);
+    g_assert_cmpuint(apicid_from_cpu_idx(1, 1, 1), ==, 1);
+    g_assert_cmpuint(apicid_from_cpu_idx(1, 1, 2), ==, 2);
+    g_assert_cmpuint(apicid_from_cpu_idx(1, 1, 3), ==, 3);
 
 
     /* Test field width calculation for multiple values
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
                   ` (3 preceding siblings ...)
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 4/7] topology: Move topology.h to an arch-independent location Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-18 17:45   ` Andreas Färber
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 6/7] hw/arm/virt: Add cpu hotplug support Shannon Zhao
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add apic_id property for ARMCPU. It can be used for cpu hotplug.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 target-arm/cpu-qom.h |    1 +
 target-arm/cpu.c     |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h     |    2 +
 3 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index ed5a644..d4560e2 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -59,6 +59,7 @@ typedef struct ARMCPU {
     /*< public >*/
 
     CPUARMState env;
+    uint32_t apic_id;
 
     /* Coprocessor information */
     GHashTable *cp_regs;
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 285947f..9202b07 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -23,12 +23,17 @@
 #include "qemu-common.h"
 #include "hw/qdev-properties.h"
 #include "qapi/qmp/qerror.h"
+#include "qapi-visit.h"
+#include "qapi/visitor.h"
+#include "hw/acpi/topology.h"
+
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/loader.h"
 #endif
 #include "hw/arm/arm.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
+#include "sysemu/cpus.h"
 #include "kvm_arm.h"
 
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
@@ -332,6 +337,65 @@ static inline void unset_feature(CPUARMState *env, int feature)
     env->features &= ~(1ULL << feature);
 }
 
+static void arm_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
+                                  const char *name, Error **errp)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+    int64_t value = cpu->apic_id;
+
+    visit_type_int(v, &value, name, errp);
+}
+
+static void arm_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
+                                  const char *name, Error **errp)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+    DeviceState *dev = DEVICE(obj);
+    const int64_t min = 0;
+    const int64_t max = UINT32_MAX;
+    Error *error = NULL;
+    int64_t value;
+
+    if (dev->realized) {
+        error_setg(errp, "Attempt to set property '%s' on '%s' after "
+                   "it was realized", name, object_get_typename(obj));
+        return;
+    }
+
+    visit_type_int(v, &value, name, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    if (value < min || value > max) {
+        error_setg(errp, "Property %s.%s doesn't take value %" PRId64
+                   " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
+                   object_get_typename(obj), name, value, min, max);
+        return;
+    }
+
+    if ((value != cpu->apic_id) && cpu_exists(value)) {
+        error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
+        return;
+    }
+    cpu->apic_id = value;
+}
+
+/* Calculates initial APIC ID for a specific CPU index
+ *
+ * Currently we need to be able to calculate the APIC ID from the CPU index
+ * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
+ * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
+ * all CPUs up to max_cpus.
+ */
+uint32_t arm_cpu_apic_id_from_index(unsigned int cpu_index)
+{
+    uint32_t correct_id;
+
+    correct_id = apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
+    return correct_id;
+}
+
 static void arm_cpu_initfn(Object *obj)
 {
     CPUState *cs = CPU(obj);
@@ -343,6 +407,11 @@ static void arm_cpu_initfn(Object *obj)
     cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
                                          g_free, g_free);
 
+    object_property_add(obj, "apic-id", "int",
+                    arm_cpuid_get_apic_id,
+                    arm_cpuid_set_apic_id, NULL, NULL, NULL);
+
+     cpu->apic_id = arm_cpu_apic_id_from_index(cs->cpu_index);
 #ifndef CONFIG_USER_ONLY
     /* Our inbound IRQ and FIQ lines */
     if (kvm_enabled()) {
@@ -379,6 +448,13 @@ static void arm_cpu_initfn(Object *obj)
     }
 }
 
+static int64_t arm_cpu_get_arch_id(CPUState *cs)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    return cpu->apic_id;
+}
+
 static Property arm_cpu_reset_cbar_property =
             DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
 
@@ -1183,6 +1259,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->set_pc = arm_cpu_set_pc;
     cc->gdb_read_register = arm_cpu_gdb_read_register;
     cc->gdb_write_register = arm_cpu_gdb_write_register;
+    cc->get_arch_id = arm_cpu_get_arch_id;
 #ifdef CONFIG_USER_ONLY
     cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
 #else
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index cd7a9e8..9e60972 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1819,4 +1819,6 @@ enum {
     QEMU_PSCI_CONDUIT_HVC = 2,
 };
 
+uint32_t arm_cpu_apic_id_from_index(unsigned int cpu_index);
+
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 6/7] hw/arm/virt: Add cpu hotplug support
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
                   ` (4 preceding siblings ...)
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 7/7] hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI Shannon Zhao
  2015-02-18 17:19 ` [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Wei Huang
  7 siblings, 0 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add a hotplug device in machine virt and add cpu hotplug support
using cpu-add.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 hw/arm/virt.c                  |  159 +++++++++++++++++++++++++++++++++++++++-
 include/hw/acpi/virt-hotplug.h |    1 +
 2 files changed, 159 insertions(+), 1 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f689bc3..760afbb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -43,6 +43,8 @@
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
 #include "hw/arm/virt-acpi-build.h"
+#include "hw/acpi/virt-hotplug.h"
+#include "hw/hotplug.h"
 
 #define NUM_VIRTIO_TRANSPORTS 32
 
@@ -76,6 +78,7 @@ enum {
     VIRT_RTC,
     VIRT_FW_CFG,
     VIRT_GPIO,
+    VIRT_CPU_HOTPLUG,
 };
 
 typedef struct MemMapEntry {
@@ -102,8 +105,11 @@ typedef struct {
 typedef struct {
     MachineState parent;
     bool secure;
+    HotplugHandler *acpi_dev;
 } VirtMachineState;
 
+#define VIRT_MACHINE_ACPI_DEVICE_PROP "acpi-device"
+
 #define TYPE_VIRT_MACHINE   "virt"
 #define VIRT_MACHINE(obj) \
     OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
@@ -135,6 +141,7 @@ static const MemMapEntry a15memmap[] = {
     [VIRT_RTC] =        { 0x09010000, 0x00001000 },
     [VIRT_FW_CFG] =     { 0x09020000, 0x0000000a },
     [VIRT_GPIO] =       { 0x09500000, 0x00001000 },
+    [VIRT_CPU_HOTPLUG] =       { 0x09600000, 0x00000020 },
     [VIRT_MMIO] =       { 0x0a000000, 0x00000200 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
     /* 0x10000000 .. 0x40000000 reserved for PCI */
@@ -381,7 +388,7 @@ static void create_gic(const VirtBoardInfo *vbi, qemu_irq *pic)
 
     gicdev = qdev_create(NULL, gictype);
     qdev_prop_set_uint32(gicdev, "revision", 2);
-    qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
+    qdev_prop_set_uint32(gicdev, "num-cpu", max_cpus);
     /* Note that the num-irq property counts both internal and external
      * interrupts; there are always 32 of the former (mandated by GIC spec).
      */
@@ -630,6 +637,136 @@ void virt_guest_info_machine_done(Notifier *notifier, void *data)
     virt_acpi_setup(&guest_info_state->info);
 }
 
+static void virt_new_cpu(const char *cpu_model, int64_t apic_id,
+                          Error **errp)
+{
+    ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
+    Object *cpuobj;
+    VirtBoardInfo *vbi;
+    SysBusDevice *gicbusdev;
+
+    vbi = find_machine_info(cpu_model);
+
+    if (!oc) {
+        fprintf(stderr, "Unable to find CPU definition\n");
+        exit(1);
+    }
+    cpuobj = object_new(object_class_get_name(oc));
+
+    object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC, "psci-conduit",
+                            NULL);
+
+    /* Secondary CPUs start in PSCI powered-down state */
+    object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
+
+    if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+        object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base,
+                            "reset-cbar", &error_abort);
+    }
+
+    object_property_set_bool(cpuobj, true, "realized", NULL);
+
+    const char *gictype = "arm_gic";
+    if (kvm_irqchip_in_kernel()) {
+        gictype = "kvm-arm-gic";
+    }
+
+    bool ambig;
+    Object *o = object_resolve_path_type("", gictype, &ambig);
+    DeviceState *gicdev = DEVICE(o);
+    DeviceState *cpudev = DEVICE(cpuobj);
+    gicbusdev = SYS_BUS_DEVICE(gicdev);
+    int ppibase = NUM_IRQS + apic_id * 32;
+    /* physical timer; we wire it up to the non-secure timer's ID,
+     * since a real A15 always has TrustZone but QEMU doesn't.
+     */
+    qdev_connect_gpio_out(cpudev, 0,
+                          qdev_get_gpio_in(gicdev, ppibase + 30));
+    /* virtual timer */
+    qdev_connect_gpio_out(cpudev, 1,
+                          qdev_get_gpio_in(gicdev, ppibase + 27));
+
+    sysbus_connect_irq(gicbusdev, apic_id,
+                       qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+}
+
+static const char *current_cpu_model;
+
+static void virt_hot_add_cpu(const int64_t id, Error **errp)
+{
+    int64_t apic_id = arm_cpu_apic_id_from_index(id);
+    if (id < 0) {
+        error_setg(errp, "Invalid CPU id: %" PRIi64, id);
+        return;
+    }
+
+    if (cpu_exists(apic_id)) {
+        error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", it already exists", id);
+        return;
+    }
+
+    if (id >= max_cpus) {
+        error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", max allowed: %d", id, max_cpus - 1);
+        return;
+    }
+
+    if (apic_id >= VIRT_ACPI_CPU_HOTPLUG_ID_LIMIT) {
+        error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", resulting APIC ID (%" PRIi64 ") is too large",
+                   id, apic_id);
+        return;
+    }
+
+    virt_new_cpu(current_cpu_model, apic_id, errp);
+}
+
+static void virt_cpu_plug(HotplugHandler *hotplug_dev,
+                        DeviceState *dev, Error **errp)
+{
+    HotplugHandlerClass *hhc;
+    Error *local_err = NULL;
+    VirtMachineState *virtms = VIRT_MACHINE(hotplug_dev);
+
+    if (!dev->hotplugged) {
+        goto out;
+    }
+
+    if (!virtms->acpi_dev) {
+        error_setg(&local_err,
+                   "cpu hotplug is not enabled: missing acpi device");
+        goto out;
+    }
+
+    hhc = HOTPLUG_HANDLER_GET_CLASS(virtms->acpi_dev);
+    hhc->plug(HOTPLUG_HANDLER(virtms->acpi_dev), dev, &local_err);
+    if (local_err) {
+        goto out;
+    }
+
+out:
+    error_propagate(errp, local_err);
+}
+
+static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
+                                      DeviceState *dev, Error **errp)
+{
+    if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+        virt_cpu_plug(hotplug_dev, dev, errp);
+    }
+}
+
+static HotplugHandler *virt_get_hotpug_handler(MachineState *machine,
+                                             DeviceState *dev)
+{
+    if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+        return HOTPLUG_HANDLER(machine);
+    }
+
+    return NULL;
+}
+
 static void machvirt_init(MachineState *machine)
 {
     VirtMachineState *vms = VIRT_MACHINE(machine);
@@ -641,10 +778,12 @@ static void machvirt_init(MachineState *machine)
     VirtBoardInfo *vbi;
     VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
     VirtGuestInfo *guest_info = &guest_info_state->info;
+    DeviceState *virt_hotplug;
 
     if (!cpu_model) {
         cpu_model = "cortex-a15";
     }
+    current_cpu_model = cpu_model;
 
     vbi = find_machine_info(cpu_model);
 
@@ -710,6 +849,16 @@ static void machvirt_init(MachineState *machine)
 
     create_gpio(vbi, pic);
 
+    virt_hotplug_init(&virt_hotplug);
+
+    object_property_add_link(OBJECT(machine), VIRT_MACHINE_ACPI_DEVICE_PROP,
+                             TYPE_HOTPLUG_HANDLER,
+                             (Object **)&vms->acpi_dev,
+                             object_property_allow_set_link,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+    object_property_set_link(OBJECT(machine), OBJECT(virt_hotplug),
+                            VIRT_MACHINE_ACPI_DEVICE_PROP, &error_abort);
+
     /* Create mmio transports, so the user can create virtio backends
      * (which will be automatically plugged in to the transports). If
      * no backend is created the transport will just sit harmlessly idle.
@@ -772,11 +921,15 @@ static void virt_instance_init(Object *obj)
 static void virt_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
 
     mc->name = TYPE_VIRT_MACHINE;
     mc->desc = "ARM Virtual Machine",
     mc->init = machvirt_init;
+    mc->hot_add_cpu = virt_hot_add_cpu,
     mc->max_cpus = 8;
+    mc->get_hotplug_handler = virt_get_hotpug_handler;
+    hc->plug = virt_machine_device_plug_cb;
 }
 
 static const TypeInfo machvirt_info = {
@@ -786,6 +939,10 @@ static const TypeInfo machvirt_info = {
     .instance_init = virt_instance_init,
     .class_size = sizeof(VirtMachineClass),
     .class_init = virt_class_init,
+    .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
+         { }
+    },
 };
 
 static void machvirt_machine_init(void)
diff --git a/include/hw/acpi/virt-hotplug.h b/include/hw/acpi/virt-hotplug.h
index a668d16..8f94235 100644
--- a/include/hw/acpi/virt-hotplug.h
+++ b/include/hw/acpi/virt-hotplug.h
@@ -3,6 +3,7 @@
 
 #include "qemu/typedefs.h"
 
+#define VIRT_ACPI_CPU_HOTPLUG_ID_LIMIT 256
 #define VIRT_CPU_HOTPLUG_MMIO_BASE 0x09600000
 
 void virt_hotplug_init(DeviceState **virt_hotplug);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [RFC PATCH 7/7] hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
                   ` (5 preceding siblings ...)
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 6/7] hw/arm/virt: Add cpu hotplug support Shannon Zhao
@ 2015-02-17 10:10 ` Shannon Zhao
  2015-02-18 17:19 ` [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Wei Huang
  7 siblings, 0 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-17 10:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

Add cpu hotplug support in ACPI.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 hw/acpi/aml-build.c              |  135 ++++++++++++++++++++++++++++
 hw/acpi/virt-hotplug.c           |   11 +++
 hw/arm/virt-acpi-build.c         |  179 +++++++++++++++++++++++++++++++++++++-
 hw/arm/virt.c                    |    1 +
 include/hw/acpi/aml-build.h      |   13 +++
 include/hw/acpi/virt-hotplug.h   |    2 +-
 include/hw/arm/virt-acpi-build.h |    1 +
 7 files changed, 337 insertions(+), 5 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 5e0c40b..023e055 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -468,6 +468,21 @@ Aml *aml_arg(int pos)
     return var;
 }
 
+Aml *aml_index(Aml *val, Aml *index)
+{
+    Aml *var = aml_opcode(0x88 /* IndexOp */);
+    aml_append(var, val);
+    aml_append(var, index);
+    return var;
+}
+
+Aml *aml_derefof(Aml *val)
+{
+    Aml *var = aml_opcode(0x83 /* DerefofOp */);
+    aml_append(var, val);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
 Aml *aml_store(Aml *val, Aml *target)
 {
@@ -496,6 +511,14 @@ Aml *aml_notify(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* helper to call method with none argument */
+Aml *aml_call0(const char *method)
+{
+    Aml *var = aml_alloc();
+    build_append_namestring(var->buf, "%s", method);
+    return var;
+}
+
 /* helper to call method with 1 argument */
 Aml *aml_call1(const char *method, Aml *arg1)
 {
@@ -539,6 +562,48 @@ Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
 }
 
 /*
+ * ACPI 5.0 19.5.53 GpioInt (GPIO Interrupt Connection Resource Descriptor Macro)
+ */
+Aml *aml_gpio_int(uint8_t edge, uint8_t polarity, uint8_t share, uint8_t wake,
+                  int8_t pin_cfg, int32_t pin_num, const char *name)
+{
+    Aml *var = aml_alloc();
+    uint8_t flags = edge & (polarity >> 1) & (share >> 3) & (wake >> 4) & 0x1F;
+    uint16_t length = 0x18 + sizeof(name);
+
+    build_append_byte(var->buf, 0x8C); /* GpioInt Resource Descriptor */
+    build_append_byte(var->buf, length & 0xff); /* Length, bits[7:0] */
+    build_append_byte(var->buf, (length >> 8) & 0xff); /* Length, bits[15:8] */
+    build_append_byte(var->buf, 1); /* Revision ID */
+    build_append_byte(var->buf, 0); /* GPIO Connection Type 0x00 = Interrupt Connection */
+    build_append_byte(var->buf, 0); /* General Flags, bits[7:0] */
+    build_append_byte(var->buf, 0); /* General Flags, bits[15:8] */
+    build_append_byte(var->buf, flags); /* Interrupt and IO Flags, bits[7:0] */
+    build_append_byte(var->buf, 0); /* Interrupt and IO Flags, bits[15:8] */
+    build_append_byte(var->buf, pin_cfg); /* Pin Configuration 0 = Default 1 = Pull-up
+                                           * 2 = Pull-down 3 = No Pull */
+    build_append_byte(var->buf, 0); /* Output Drive Strength, bits[7:0] */
+    build_append_byte(var->buf, 0); /* Output Drive Strength, bits[15:8] */
+    build_append_byte(var->buf, 0); /* Debounce timeout, bits[7:0] */
+    build_append_byte(var->buf, 0); /* Debounce timeout, bits[15:8] */
+
+    build_append_byte(var->buf, 0x16); /* Pin Table Offset, bits[7:0] */
+    build_append_byte(var->buf, 0); /* Pin Table Offset, bits[15:8] */
+    build_append_byte(var->buf, 0); /* Resource Source Index */
+    build_append_byte(var->buf, 0x18); /* Resource Source Name, bits[7:0] */
+    build_append_byte(var->buf, 0); /* Resource Source Name, bits[15:8] */
+    build_append_byte(var->buf, length & 0xff); /* Vendor Data Offset, bits[7:0] */
+    build_append_byte(var->buf, (length >> 8) & 0xff); /* Vendor Data Offset, bits[15:8] */
+    build_append_byte(var->buf, 0); /* Vendor Data Length, bits[7:0] */
+    build_append_byte(var->buf, 0); /* Vendor Data Length, bits[15:8] */
+    build_append_byte(var->buf, pin_num & 0xff); /* Pin Number, bits[7:0] */
+    build_append_byte(var->buf, (pin_num >> 8) & 0xff); /* Pin Number, bits[15:8] */
+    build_append_namestring(var->buf, "%s", name); /* Resource Source */
+
+    return var;
+}
+
+/*
  * ACPI 1.0: 6.4.3.4 Memory32Fixed (Memory Resource Descriptor Macro)
  */
 Aml *aml_memory32_fixed(uint64_t addr, uint64_t size, uint8_t rw_flag)
@@ -615,6 +680,43 @@ Aml *aml_irq_no_flags(uint8_t irq)
     return var;
 }
 
+/* ACPI 1.0: 16.2.3 Operators: DefIncrement */
+Aml *aml_increment(Aml *arg)
+{
+    Aml *var = aml_opcode(0x75 /* IncrementOp */);
+    aml_append(var, arg);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
+/* ACPI 1.0: 16.2.3 Operators: DefShiftRight */
+Aml *aml_shiftright(Aml *arg1, Aml *arg2, Aml *arg3)
+{
+    Aml *var = aml_opcode(0x7A /* ShiftRightOp */);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    aml_append(var, arg3);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
+/* ACPI 1.0: 16.2.3 Operators: DefSizeof */
+Aml *aml_sizeof(Aml *arg)
+{
+    Aml *var = aml_opcode(0x87 /* SizeofOp */);
+    aml_append(var, arg);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
+/* ACPI 1.0: 16.2.3 Operators: DefLNot */
+Aml *aml_not(Aml *arg)
+{
+    Aml *var = aml_opcode(0x92 /* LNotOp */);
+    aml_append(var, arg);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
 Aml *aml_equal(Aml *arg1, Aml *arg2)
 {
@@ -625,6 +727,16 @@ Aml *aml_equal(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0: 16.2.3 Operators: DefLLess */
+Aml *aml_less(Aml *arg1, Aml *arg2)
+{
+    Aml *var = aml_opcode(0x95 /* LLessOp */);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 Aml *aml_if(Aml *predicate)
 {
@@ -633,6 +745,29 @@ Aml *aml_if(Aml *predicate)
     return var;
 }
 
+/* ACPI 1.0: 16.2.3 Operators: DefElse */
+Aml *aml_else(void)
+{
+    Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
+    return var;
+}
+
+/* ACPI 1.0: 16.2.3 Operators: DefWhile */
+Aml *aml_while(Aml *predicate)
+{
+    Aml *var = aml_bundle(0xA2 /* DefWhile */, AML_PACKAGE);
+    aml_append(var, predicate);
+    return var;
+}
+
+/* ACPI 1.0: 16.2.3 Operators: DefSleep */
+Aml *aml_sleep(const uint64_t msectime)
+{
+    Aml *var = aml_bundle(0x22 /* SleepOp */, AML_EXT_PACKAGE);
+    build_append_int(var->buf, msectime);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
 Aml *aml_method(const char *name, int arg_count)
 {
diff --git a/hw/acpi/virt-hotplug.c b/hw/acpi/virt-hotplug.c
index 47da078..c9a837d 100644
--- a/hw/acpi/virt-hotplug.c
+++ b/hw/acpi/virt-hotplug.c
@@ -85,6 +85,17 @@ static int virt_hotplug_initfn(SysBusDevice *sbd)
     return 0;
 }
 
+Object *virt_hotplug_find(void)
+{
+    bool ambig;
+    Object *o = object_resolve_path_type("", TYPE_VIRT_HOTPLUG, &ambig);
+
+    if (ambig || !o) {
+        return NULL;
+    }
+    return o;
+}
+
 void virt_hotplug_init(DeviceState **virt_hotplug)
 {
     DeviceState *dev;
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 4f26551..a719487 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -38,6 +38,7 @@
 #include "target-arm/cpu.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/virt-hotplug.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/loader.h"
@@ -179,7 +180,7 @@ static void acpi_dsdt_add_virtio(Aml *scope, const hwaddr *mmio_addrs,
 static void acpi_dsdt_add_gpio(Aml *scope, const hwaddr *gpio_addrs,
                                            const int *gpio_irq)
 {
-    Aml *dev, *crs;
+    Aml *dev, *crs, *aei, *method;
 
     dev = aml_device("GPO0");
     aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0009")));
@@ -193,9 +194,172 @@ static void acpi_dsdt_add_gpio(Aml *scope, const hwaddr *gpio_addrs,
                aml_interrupt(0x01, *gpio_irq + 32));
     aml_append(dev, aml_name_decl("_CRS", crs));
 
+    aei = aml_resource_template();
+    aml_append(aei, aml_gpio_int(1, 2, 0, 0, 1, 2, "\\_SB.GPO0"));
+    aml_append(dev, aml_name_decl("_AEI", aei));
+    /* _E02 for cpu hotplug */
+    method = aml_method("_E02", 0);
+    aml_append(method, aml_call0("\\_SB.PRSC"));
+    aml_append(dev, method);
+
     aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_cpu_hotplug(Aml *scope, int max_cpus,
+                const hwaddr *cpu_hotplug_addr, VirtAcpiCpuInfo *cpuinfo)
+{
+    Aml *dev, *crs, *field, *method, *ifctx, *elsectx, *ifctx1, *whilectx;
+    Aml *local0, *local1, *local2, *local3, *local4, *pkg, *buffer;
+    int i;
+
+    /* create PRES device and its _CRS to reserve CPU hotplug MMIO */
+    dev = aml_device("PRES");
+    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
+    aml_append(dev, aml_name_decl("_UID", aml_string("CPU Hotplug Resources")));
+    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+    crs = aml_resource_template();
+    aml_append(crs,
+               aml_memory32_fixed(cpu_hotplug_addr[0], cpu_hotplug_addr[1], 0x01));
+    aml_append(dev, aml_name_decl("_CRS", crs));
+    aml_append(scope, dev);
+
+    /* declare CPU hotplug MMIO region and PRS field to access it */
+    aml_append(scope, aml_operation_region(
+        "PRST", aml_system_memory, cpu_hotplug_addr[0], cpu_hotplug_addr[1]));
+    field = aml_field("PRST", aml_byte_acc);
+    aml_append(field, aml_named_field("PRS", 256));
+    aml_append(scope, field);
+
+    /* build Processor object for each processor */
+    for (i = 0; i < max_cpus; i++) {
+        dev = aml_processor(i, 0, 0, "CP%.02X", i);
+
+        method = aml_method("_MAT", 0);
+        aml_append(method, aml_return(aml_call1("CPMA", aml_int(i))));
+        aml_append(dev, method);
+
+        method = aml_method("_STA", 0);
+        aml_append(method, aml_return(aml_call1("CPST", aml_int(i))));
+        aml_append(dev, method);
+
+        method = aml_method("_EJ0", 1);
+        aml_append(method,
+            aml_return(aml_call2("CPEJ", aml_int(i), aml_arg(0))));
+        aml_append(dev, method);
+
+        aml_append(scope, dev);
+    }
+
+    /* build this code:
+     *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
+     */
+    /* Arg0 = Processor ID = APIC ID */
+    method = aml_method("NTFY", 2);
+    for (i = 0; i < max_cpus; i++) {
+        ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));
+        aml_append(ifctx,
+            aml_notify(aml_name("CP%.02X", i), aml_arg(1))
+        );
+        aml_append(method, ifctx);
+    }
+    aml_append(scope, method);
+
+    /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
+     *
+     * Note: The ability to create variable-sized packages was first
+     * ntroduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
+     * ith up to 255 elements. Windows guests up to win2k8 fail when
+     * VarPackageOp is used.
+     */
+    pkg = max_cpus <= 255 ? aml_package(max_cpus) :
+                             aml_varpackage(max_cpus);
+
+    for (i = 0; i < max_cpus; i++) {
+        uint8_t b = test_bit(i, cpuinfo->found_cpus) ? 0x01 : 0x00;
+        aml_append(pkg, aml_int(b));
+    }
+    aml_append(scope, aml_name_decl("CPON", pkg));
+
+    /* Add CPMA method  */
+    method = aml_method("CPMA", 1);
+    local0 = aml_local(0);
+    aml_append(method,
+        aml_store(aml_derefof(aml_index(pkg, aml_arg(0))), local0));
+    buffer = aml_buffer();
+    aml_append(buffer, aml_int(0x0));
+    aml_append(buffer, aml_int(0x08));
+    aml_append(buffer, aml_int(0x0));
+    aml_append(buffer, aml_int(0x0));
+    aml_append(buffer, aml_int(0x0));
+    aml_append(buffer, aml_int(0x0));
+    aml_append(buffer, aml_int(0x0));
+    aml_append(buffer, aml_int(0x0));
+    local1 = aml_local(1);
+    aml_append(method, aml_store(buffer, local1));
+    aml_append(method, aml_store(aml_arg(0), aml_index(local1, aml_int(2))));
+    aml_append(method, aml_store(aml_arg(0), aml_index(local1, aml_int(3))));
+    aml_append(method, aml_store(local0, aml_index(local1, aml_int(4))));
+    aml_append(method, aml_return(local1));
+    aml_append(scope, method);
+
+    /* Add CPST method  */
+    method = aml_method("CPST", 1);
+    local0 = aml_local(0);
+    aml_append(method,
+        aml_store(aml_derefof(aml_index(pkg, aml_arg(0))), local0));
+    ifctx = aml_if(local0);
+    aml_append(ifctx, aml_return(aml_int(0xF)));
+    aml_append(method, ifctx);
+    elsectx = aml_else();
+    aml_append(elsectx, aml_return(aml_int(0x0)));
+    aml_append(method, elsectx);
+    aml_append(scope, method);
+
+    /* Add CPEJ method  */
+    method = aml_method("CPEJ", 2);
+    aml_append(method, aml_sleep(200));
+    aml_append(scope, method);
+
+    /* Add PRSC method  */
+    method = aml_method("PRSC", 0);
+    local4 = aml_local(4);
+    aml_append(method, aml_store(field, local4));
+    local2 = aml_local(2);
+    aml_append(method, aml_store(aml_int(0), local2));
+    local0 = aml_local(0);
+    aml_append(method, aml_store(aml_int(0), local0));
+
+    whilectx = aml_while(aml_less(local0, aml_sizeof(pkg)));
+    local1 = aml_local(1);
+    aml_append(whilectx,
+        aml_store(aml_derefof(aml_index(pkg, local0)), local1));
+    ifctx = aml_if(aml_and(local0, aml_int(0x07)));
+    aml_append(ifctx, aml_shiftright(local2, aml_int(0x1), local2));
+    aml_append(whilectx, ifctx);
+    elsectx = aml_else();
+    aml_append(elsectx,
+        aml_store(aml_derefof(aml_index(local4,
+                  aml_shiftright(local0, aml_int(0x3), local0))), local0)
+    );
+    aml_append(whilectx, elsectx);
+    local3 = aml_local(3);
+    aml_append(whilectx, aml_store(aml_and(local2, aml_int(0x1)), local3));
+    ifctx = aml_if(aml_not(aml_equal(local1, local3)));
+    aml_append(ifctx, aml_store(local3, aml_index(pkg, local0)));
+    ifctx1 = aml_if(aml_equal(local3, aml_int(0x1)));
+    aml_append(ifctx1, aml_call2("NTFY", local0, aml_int(0x1)));
+    aml_append(ifctx, ifctx1);
+    elsectx = aml_else();
+    aml_append(elsectx, aml_call2("NTFY", local0, aml_int(0x3)));
+    aml_append(ifctx, elsectx);
+    aml_append(whilectx, ifctx);
+
+    aml_append(whilectx, aml_increment(local0));
+
+    aml_append(method, whilectx);
+    aml_append(scope, method);
+}
+
 /* RSDP */
 static GArray *
 build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
@@ -348,22 +512,29 @@ build_fadt(GArray *table_data, GArray *linker, uint64_t dsdt)
 
 /* DSDT */
 static void
-build_dsdt(Aml *table_data, GArray *linker, VirtGuestInfo *guest_info)
+build_dsdt(Aml *table_data, GArray *linker, VirtGuestInfo *guest_info,
+           VirtAcpiCpuInfo *cpuinfo)
 {
     Aml *scope, *dsdt;
     const struct acpi_dsdt_info *info = guest_info->dsdt_info;
+    Object *virt_hotplug = virt_hotplug_find();
 
     dsdt = aml_def_block("DSDT", 1, ACPI_BUILD_APPNAME6,
                           ACPI_BUILD_APPNAME4, 1,
                           ACPI_BUILD_APPNAME4_HEX, 1);
     scope = aml_scope("\\_SB");
-    acpi_dsdt_add_cpus(scope, guest_info->max_cpus);
     acpi_dsdt_add_uart(scope, info->uart_addr, info->uart_irq);
     acpi_dsdt_add_rtc(scope, info->rtc_addr, info->rtc_irq);
     acpi_dsdt_add_flash(scope, info->flash_addr);
     acpi_dsdt_add_virtio(scope, info->virtio_mmio_addr,
              info->virtio_mmio_irq, info->virtio_mmio_num);
     acpi_dsdt_add_gpio(scope, info->gpio_addr, info->gpio_irq);
+    if (virt_hotplug) {
+        acpi_dsdt_add_cpu_hotplug(scope, guest_info->max_cpus,
+                                  info->cpu_hotplug_addr, cpuinfo);
+    } else {
+        acpi_dsdt_add_cpus(scope, guest_info->max_cpus);
+    }
 
     aml_append(dsdt, scope);
     aml_append(table_data, dsdt);
@@ -410,7 +581,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 
     /* DSDT is pointed to by FADT */
     dsdt = tables_blob->len;
-    build_dsdt(tables->table_data, tables->linker, guest_info);
+    build_dsdt(tables->table_data, tables->linker, guest_info, &cpuinfo);
 
     /* FADT MADT GTDT pointed to by XSDT */
     acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 760afbb..4add9f5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -168,6 +168,7 @@ static const struct acpi_dsdt_info dsdt_info = {
     .virtio_mmio_num = NUM_VIRTIO_TRANSPORTS,
     .gpio_addr = &a15memmap[VIRT_GPIO].base,
     .gpio_irq = &a15irqmap[VIRT_GPIO],
+    .cpu_hotplug_addr = &a15memmap[VIRT_CPU_HOTPLUG].base,
     .rtc_addr = &a15memmap[VIRT_RTC].base,
     .rtc_irq = &a15irqmap[VIRT_RTC],
     .flash_addr = &a15memmap[VIRT_FLASH].base,
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index eb9ba0d..5e43557 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -155,17 +155,27 @@ Aml *aml_name_decl(const char *name, Aml *val);
 Aml *aml_return(Aml *val);
 Aml *aml_int(const uint64_t val);
 Aml *aml_arg(int pos);
+Aml *aml_index(Aml *val, Aml *index);
+Aml *aml_derefof(Aml *val);
 Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
+Aml *aml_call0(const char *method);
 Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
 Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3);
 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4);
+Aml *aml_gpio_int(uint8_t edge, uint8_t polarity, uint8_t share, uint8_t wake,
+                  int8_t pin_cfg, int32_t pin_num, const char *name);
 Aml *aml_memory32_fixed(uint64_t addr, uint64_t size, uint8_t rw_flag);
 Aml *aml_interrupt(uint8_t irq_flags, int irq);
 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
             uint8_t aln, uint8_t len);
+Aml *aml_increment(Aml *arg);
+Aml *aml_shiftright(Aml *arg1, Aml *arg2, Aml *arg3);
+Aml *aml_sizeof(Aml *arg);
+Aml *aml_not(Aml *arg);
+Aml *aml_less(Aml *arg1, Aml *arg2);
 Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
                           uint32_t offset, uint32_t len);
 Aml *aml_irq_no_flags(uint8_t irq);
@@ -208,6 +218,9 @@ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_method(const char *name, int arg_count);
 Aml *aml_if(Aml *predicate);
+Aml *aml_else(void);
+Aml *aml_while(Aml *predicate);
+Aml *aml_sleep(const uint64_t msectime);
 Aml *aml_package(uint8_t num_elements);
 Aml *aml_buffer(void);
 Aml *aml_resource_template(void);
diff --git a/include/hw/acpi/virt-hotplug.h b/include/hw/acpi/virt-hotplug.h
index 8f94235..aad3381 100644
--- a/include/hw/acpi/virt-hotplug.h
+++ b/include/hw/acpi/virt-hotplug.h
@@ -7,5 +7,5 @@
 #define VIRT_CPU_HOTPLUG_MMIO_BASE 0x09600000
 
 void virt_hotplug_init(DeviceState **virt_hotplug);
-
+Object *virt_hotplug_find(void);
 #endif
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index de8d4c6..b183b42 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -49,6 +49,7 @@ struct acpi_dsdt_info {
     int virtio_mmio_num;
     const hwaddr *gpio_addr;
     const int *gpio_irq;
+    const hwaddr *cpu_hotplug_addr;
     const hwaddr *rtc_addr;
     const int *rtc_irq;
     const hwaddr *flash_addr;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support
  2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
                   ` (6 preceding siblings ...)
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 7/7] hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI Shannon Zhao
@ 2015-02-18 17:19 ` Wei Huang
  2015-02-18 17:22   ` Wei Huang
  2015-02-26  7:32   ` Shannon Zhao
  7 siblings, 2 replies; 18+ messages in thread
From: Wei Huang @ 2015-02-18 17:19 UTC (permalink / raw)
  To: Shannon Zhao, qemu-devel, peter.maydell, pbonzini,
	christoffer.dall, a.spyridakis, claudio.fontana, imammedo,
	hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

[-- Attachment #1: Type: text/plain, Size: 3169 bytes --]

Nice work. I will help review the patches.

Other than the CPU hotplug support, we are also seeking the guest VM
powerdown support via ACPI. This feature is important for management
tool to control guest VMs. In fact I had a similar GPIO patch for
powerdown recently. Given that you already posted a more complete
version, I wonder if you can add this feature to your patchset? FYI, I
attached my powerdown patch in this email. Here is a brief list of items:

* DSDT description of power button (to-be-done)
* Hook up with qemu_qemu_register_powerdown_notifier() with the GPIO IRQ

Feel free to add my name as signed-off-by in this feature if you decide
to add it.

Thanks,
-Wei

On 02/17/2015 04:09 AM, Shannon Zhao wrote:
> Add cpu-add hotplug support in machine virt. As there are some properties
> which are set out of arm_cpu_initfn, so the way of device_add is not
> supported now. This will add at next version. Some good suggestion?
> 
> This patchset is based on below patch:
> [RFC PATCH v3 00/11] Generate ACPI v5.1 tables and	expose it to guest over fw_cfg on ARM
> http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg03290.html
> 
> Have done compile test and start a Linux guest, execute cpu-add in monitor, use info cpu
> to check a new cpu created. But as the guest kernel driver is not ready, so it can't be
> used by guest now.
> 
> Any comments are welcome.
> Thanks,
> Shannon
> 
> Shannon Zhao (7):
>   hw/arm/virt: Add a GPIO controller
>   hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table
>   hw/acpi/virt-hotplug: Add a hotplug device for machine virt
>   topology: Move topology.h to an arch-independent location
>   target-arm/cpu: Add apic_id property for ARMCPU
>   hw/arm/virt: Add cpu hotplug support
>   hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI
> 
>  default-configs/arm-softmmu.mak  |    2 +
>  hw/acpi/Makefile.objs            |    1 +
>  hw/acpi/aml-build.c              |  135 ++++++++++++++++++++++++++
>  hw/acpi/cpu_hotplug.c            |   16 +---
>  hw/acpi/ich9.c                   |   12 +++
>  hw/acpi/piix4.c                  |   12 +++
>  hw/acpi/virt-hotplug.c           |  141 +++++++++++++++++++++++++++
>  hw/arm/virt-acpi-build.c         |  198 +++++++++++++++++++++++++++++++++++++-
>  hw/arm/virt.c                    |  190 ++++++++++++++++++++++++++++++++++++-
>  include/hw/acpi/aml-build.h      |   13 +++
>  include/hw/acpi/cpu_hotplug.h    |    6 +-
>  include/hw/acpi/topology.h       |  134 +++++++++++++++++++++++++
>  include/hw/acpi/virt-hotplug.h   |   11 ++
>  include/hw/arm/virt-acpi-build.h |    3 +
>  target-arm/cpu-qom.h             |    1 +
>  target-arm/cpu.c                 |   77 +++++++++++++++
>  target-arm/cpu.h                 |    2 +
>  target-i386/cpu.c                |    4 +-
>  target-i386/topology.h           |  134 -------------------------
>  tests/test-x86-cpuid.c           |   10 +-
>  20 files changed, 940 insertions(+), 162 deletions(-)
>  create mode 100644 hw/acpi/virt-hotplug.c
>  create mode 100644 include/hw/acpi/topology.h
>  create mode 100644 include/hw/acpi/virt-hotplug.h
>  delete mode 100644 target-i386/topology.h
> 
> 
> 

[-- Attachment #2: 0002-arm-Hook-up-QEMU-powerdown-notifier-to-GPIO-interrup.patch --]
[-- Type: text/x-patch, Size: 1684 bytes --]

>From 17e5319419d845fc5a5e95b1577c38bc2958d633 Mon Sep 17 00:00:00 2001
From: Wei Huang <wei@redhat.com>
Date: Mon, 16 Feb 2015 16:56:12 -0500
Subject: [mach-virt GPIO RFC 2/2] arm: Hook up QEMU powerdown notifier to GPIO
 interrupt line

Currently mach-virt model doesn't support powerdown request. Guest VM
doesn't react to system_powerdown from monitor console (or QMP) because
there is no communication mechanism for such requests. This patch registers
GPIO IRQ with powerdown notification. So guest VM can receive notification
when such powerdown request is triggered.

Signed-off-by: Wei Huang <wei@redhat.com>
---
 hw/arm/virt.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1e5d792..7234044 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -440,6 +440,16 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
     g_free(nodename);
 }
 
+static qemu_irq virt_system_powerdown;
+static void virt_powerdown_req(Notifier *n, void *opaque)
+{
+    qemu_irq_raise(virt_system_powerdown);
+}
+
+static Notifier virt_system_powerdown_notifier = {
+    .notify = virt_powerdown_req
+};
+
 static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
 {
     char *nodename;
@@ -461,6 +471,10 @@ static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
     qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
     qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
 
+    /* connect powerdown request */
+    virt_system_powerdown = pic[irq];
+    qemu_register_powerdown_notifier(&virt_system_powerdown_notifier);
+
     g_free(nodename);
 }
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support
  2015-02-18 17:19 ` [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Wei Huang
@ 2015-02-18 17:22   ` Wei Huang
  2015-02-26  7:32   ` Shannon Zhao
  1 sibling, 0 replies; 18+ messages in thread
From: Wei Huang @ 2015-02-18 17:22 UTC (permalink / raw)
  To: Shannon Zhao, qemu-devel, peter.maydell, pbonzini,
	christoffer.dall, a.spyridakis, claudio.fontana, imammedo,
	hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng



On 02/18/2015 11:19 AM, Wei Huang wrote:
> Nice work. I will help review the patches.
> 
> Other than the CPU hotplug support, we are also seeking the guest VM
> powerdown support via ACPI. This feature is important for management
> tool to control guest VMs. In fact I had a similar GPIO patch for
> powerdown recently. Given that you already posted a more complete
> version, I wonder if you can add this feature to your patchset? FYI, I
> attached my powerdown patch in this email. Here is a brief list of items:
> 
> * DSDT description of power button (to-be-done)
This is the fix (or something similar) to be added to DSDT table:
http://lists.linaro.org/pipermail/linaro-acpi/2014-July/002357.html

> * Hook up with qemu_qemu_register_powerdown_notifier() with the GPIO IRQ
> 
> Feel free to add my name as signed-off-by in this feature if you decide
> to add it.
> 
> Thanks,
> -Wei
> 
> On 02/17/2015 04:09 AM, Shannon Zhao wrote:
>> Add cpu-add hotplug support in machine virt. As there are some properties
>> which are set out of arm_cpu_initfn, so the way of device_add is not
>> supported now. This will add at next version. Some good suggestion?
>>
>> This patchset is based on below patch:
>> [RFC PATCH v3 00/11] Generate ACPI v5.1 tables and	expose it to guest over fw_cfg on ARM
>> http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg03290.html
>>
>> Have done compile test and start a Linux guest, execute cpu-add in monitor, use info cpu
>> to check a new cpu created. But as the guest kernel driver is not ready, so it can't be
>> used by guest now.
>>
>> Any comments are welcome.
>> Thanks,
>> Shannon
>>
>> Shannon Zhao (7):
>>   hw/arm/virt: Add a GPIO controller
>>   hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table
>>   hw/acpi/virt-hotplug: Add a hotplug device for machine virt
>>   topology: Move topology.h to an arch-independent location
>>   target-arm/cpu: Add apic_id property for ARMCPU
>>   hw/arm/virt: Add cpu hotplug support
>>   hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI
>>
>>  default-configs/arm-softmmu.mak  |    2 +
>>  hw/acpi/Makefile.objs            |    1 +
>>  hw/acpi/aml-build.c              |  135 ++++++++++++++++++++++++++
>>  hw/acpi/cpu_hotplug.c            |   16 +---
>>  hw/acpi/ich9.c                   |   12 +++
>>  hw/acpi/piix4.c                  |   12 +++
>>  hw/acpi/virt-hotplug.c           |  141 +++++++++++++++++++++++++++
>>  hw/arm/virt-acpi-build.c         |  198 +++++++++++++++++++++++++++++++++++++-
>>  hw/arm/virt.c                    |  190 ++++++++++++++++++++++++++++++++++++-
>>  include/hw/acpi/aml-build.h      |   13 +++
>>  include/hw/acpi/cpu_hotplug.h    |    6 +-
>>  include/hw/acpi/topology.h       |  134 +++++++++++++++++++++++++
>>  include/hw/acpi/virt-hotplug.h   |   11 ++
>>  include/hw/arm/virt-acpi-build.h |    3 +
>>  target-arm/cpu-qom.h             |    1 +
>>  target-arm/cpu.c                 |   77 +++++++++++++++
>>  target-arm/cpu.h                 |    2 +
>>  target-i386/cpu.c                |    4 +-
>>  target-i386/topology.h           |  134 -------------------------
>>  tests/test-x86-cpuid.c           |   10 +-
>>  20 files changed, 940 insertions(+), 162 deletions(-)
>>  create mode 100644 hw/acpi/virt-hotplug.c
>>  create mode 100644 include/hw/acpi/topology.h
>>  create mode 100644 include/hw/acpi/virt-hotplug.h
>>  delete mode 100644 target-i386/topology.h
>>
>>
>>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU Shannon Zhao
@ 2015-02-18 17:45   ` Andreas Färber
  2015-02-18 19:51     ` Igor Mammedov
  0 siblings, 1 reply; 18+ messages in thread
From: Andreas Färber @ 2015-02-18 17:45 UTC (permalink / raw)
  To: Shannon Zhao
  Cc: peter.maydell, hangaohuai, mst, a.spyridakis, claudio.fontana,
	qemu-devel, wanghaibin.wang, peter.huangpeng, hanjun.guo,
	imammedo, pbonzini, lersek, christoffer.dall

Hi,

Am 17.02.2015 um 11:10 schrieb Shannon Zhao:
> Add apic_id property for ARMCPU. It can be used for cpu hotplug.
> 
> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
> ---
>  target-arm/cpu-qom.h |    1 +
>  target-arm/cpu.c     |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  target-arm/cpu.h     |    2 +
>  3 files changed, 80 insertions(+), 0 deletions(-)
> 
> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
> index ed5a644..d4560e2 100644
> --- a/target-arm/cpu-qom.h
> +++ b/target-arm/cpu-qom.h
> @@ -59,6 +59,7 @@ typedef struct ARMCPU {
>      /*< public >*/
>  
>      CPUARMState env;
> +    uint32_t apic_id;

Can you add a matching @apic_id: documentation entry above the struct?

>  
>      /* Coprocessor information */
>      GHashTable *cp_regs;
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index 285947f..9202b07 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
[...]
> @@ -343,6 +407,11 @@ static void arm_cpu_initfn(Object *obj)
>      cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
>                                           g_free, g_free);
>  
> +    object_property_add(obj, "apic-id", "int",
> +                    arm_cpuid_get_apic_id,
> +                    arm_cpuid_set_apic_id, NULL, NULL, NULL);

The property is correctly called apic-id. Please update the commit
message, which has it as apic_id (2x).

Regards,
Andreas

> +
> +     cpu->apic_id = arm_cpu_apic_id_from_index(cs->cpu_index);
>  #ifndef CONFIG_USER_ONLY
>      /* Our inbound IRQ and FIQ lines */
>      if (kvm_enabled()) {
[snip]

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller
  2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller Shannon Zhao
@ 2015-02-18 17:52   ` Wei Huang
  2015-02-26  7:43     ` Shannon Zhao
  0 siblings, 1 reply; 18+ messages in thread
From: Wei Huang @ 2015-02-18 17:52 UTC (permalink / raw)
  To: Shannon Zhao, qemu-devel, peter.maydell, pbonzini,
	christoffer.dall, a.spyridakis, claudio.fontana, imammedo,
	hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng



On 02/17/2015 04:10 AM, Shannon Zhao wrote:
> Add a GPIO controller in machine virt, in order to support cpu hotplug.
> Here we use pl061.
> 
> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
> ---
>  hw/arm/virt.c |   28 ++++++++++++++++++++++++++++
>  1 files changed, 28 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 8a00574..43c0260 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -75,6 +75,7 @@ enum {
>      VIRT_MMIO,
>      VIRT_RTC,
>      VIRT_FW_CFG,
> +    VIRT_GPIO,
>  };
>  
>  typedef struct MemMapEntry {
> @@ -133,6 +134,7 @@ static const MemMapEntry a15memmap[] = {
>      [VIRT_UART] =       { 0x09000000, 0x00001000 },
>      [VIRT_RTC] =        { 0x09010000, 0x00001000 },
>      [VIRT_FW_CFG] =     { 0x09020000, 0x0000000a },
> +    [VIRT_GPIO] =       { 0x09500000, 0x00001000 },
Base address can start with 0x09030000 to save some space?

>      [VIRT_MMIO] =       { 0x0a000000, 0x00000200 },
>      /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
>      /* 0x10000000 .. 0x40000000 reserved for PCI */
> @@ -142,6 +144,7 @@ static const MemMapEntry a15memmap[] = {
>  static const int a15irqmap[] = {
>      [VIRT_UART] = 1,
>      [VIRT_RTC] = 2,
> +    [VIRT_GPIO] = 3,
>      [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
>  };
>  
> @@ -465,6 +468,29 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
>      g_free(nodename);
>  }
>  
> +static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
> +{
> +    char *nodename;
> +    hwaddr base = vbi->memmap[VIRT_GPIO].base;
> +    hwaddr size = vbi->memmap[VIRT_GPIO].size;
> +    int irq = vbi->irqmap[VIRT_GPIO];
> +    const char compat[] = "arm,pl061\0arm,primecell";
> +
> +    sysbus_create_simple("pl061", base, pic[irq]);
> +
> +    nodename = g_strdup_printf("/pl061@%" PRIx64, base);
> +    qemu_fdt_add_subnode(vbi->fdt, nodename);
> +    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
> +                                 2, base, 2, size);
> +    qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#gpio-cells", 2);
> +    qemu_fdt_setprop(vbi->fdt, nodename, "gpio-controller", NULL, 0);
> +    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
> +                           GIC_FDT_IRQ_TYPE_SPI, irq,
> +                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);
Maybe also add clocks related properties (see below)? They might be
optional, assuming that you already tested your patches.

qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");


> +    g_free(nodename);
> +}
> +
>  static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
>  {
>      int i;
> @@ -680,6 +706,8 @@ static void machvirt_init(MachineState *machine)
>  
>      create_rtc(vbi, pic);
>  
> +    create_gpio(vbi, pic);
> +
>      /* Create mmio transports, so the user can create virtio backends
>       * (which will be automatically plugged in to the transports). If
>       * no backend is created the transport will just sit harmlessly idle.
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU
  2015-02-18 17:45   ` Andreas Färber
@ 2015-02-18 19:51     ` Igor Mammedov
  2015-02-18 19:57       ` Andreas Färber
  2015-02-19  8:22       ` Hanjun Guo
  0 siblings, 2 replies; 18+ messages in thread
From: Igor Mammedov @ 2015-02-18 19:51 UTC (permalink / raw)
  To: Andreas Färber
  Cc: peter.maydell, hangaohuai, mst, a.spyridakis, claudio.fontana,
	qemu-devel, wanghaibin.wang, peter.huangpeng, hanjun.guo,
	Shannon Zhao, pbonzini, lersek, christoffer.dall

On Wed, 18 Feb 2015 18:45:51 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Hi,
> 
> Am 17.02.2015 um 11:10 schrieb Shannon Zhao:
> > Add apic_id property for ARMCPU. It can be used for cpu hotplug.
> > 
> > Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
> > ---
> >  target-arm/cpu-qom.h |    1 +
> >  target-arm/cpu.c     |   77
> > ++++++++++++++++++++++++++++++++++++++++++++++++++
> > target-arm/cpu.h     |    2 + 3 files changed, 80 insertions(+), 0
> > deletions(-)
> > 
> > diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
> > index ed5a644..d4560e2 100644
> > --- a/target-arm/cpu-qom.h
> > +++ b/target-arm/cpu-qom.h
> > @@ -59,6 +59,7 @@ typedef struct ARMCPU {
> >      /*< public >*/
> >  
> >      CPUARMState env;
> > +    uint32_t apic_id;
> 
> Can you add a matching @apic_id: documentation entry above the struct?
> 
> >  
> >      /* Coprocessor information */
> >      GHashTable *cp_regs;
> > diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> > index 285947f..9202b07 100644
> > --- a/target-arm/cpu.c
> > +++ b/target-arm/cpu.c
> [...]
> > @@ -343,6 +407,11 @@ static void arm_cpu_initfn(Object *obj)
> >      cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
> >                                           g_free, g_free);
> >  
> > +    object_property_add(obj, "apic-id", "int",
> > +                    arm_cpuid_get_apic_id,
> > +                    arm_cpuid_set_apic_id, NULL, NULL, NULL);
> 
> The property is correctly called apic-id. Please update the commit
> message, which has it as apic_id (2x).
Is there such thing as apic-id on ARM?


> 
> Regards,
> Andreas
> 
> > +
> > +     cpu->apic_id = arm_cpu_apic_id_from_index(cs->cpu_index);
> >  #ifndef CONFIG_USER_ONLY
> >      /* Our inbound IRQ and FIQ lines */
> >      if (kvm_enabled()) {
> [snip]
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU
  2015-02-18 19:51     ` Igor Mammedov
@ 2015-02-18 19:57       ` Andreas Färber
  2015-02-19  8:22       ` Hanjun Guo
  1 sibling, 0 replies; 18+ messages in thread
From: Andreas Färber @ 2015-02-18 19:57 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, hangaohuai, mst, a.spyridakis, claudio.fontana,
	qemu-devel, wanghaibin.wang, peter.huangpeng, hanjun.guo,
	Shannon Zhao, pbonzini, lersek, christoffer.dall

Am 18.02.2015 um 20:51 schrieb Igor Mammedov:
> On Wed, 18 Feb 2015 18:45:51 +0100
> Andreas Färber <afaerber@suse.de> wrote:
> 
>> Hi,
>>
>> Am 17.02.2015 um 11:10 schrieb Shannon Zhao:
>>> Add apic_id property for ARMCPU. It can be used for cpu hotplug.
>>>
>>> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
>>> ---
>>>  target-arm/cpu-qom.h |    1 +
>>>  target-arm/cpu.c     |   77
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>> target-arm/cpu.h     |    2 + 3 files changed, 80 insertions(+), 0
>>> deletions(-)
>>>
>>> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
>>> index ed5a644..d4560e2 100644
>>> --- a/target-arm/cpu-qom.h
>>> +++ b/target-arm/cpu-qom.h
>>> @@ -59,6 +59,7 @@ typedef struct ARMCPU {
>>>      /*< public >*/
>>>  
>>>      CPUARMState env;
>>> +    uint32_t apic_id;
>>
>> Can you add a matching @apic_id: documentation entry above the struct?
>>
>>>  
>>>      /* Coprocessor information */
>>>      GHashTable *cp_regs;
>>> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
>>> index 285947f..9202b07 100644
>>> --- a/target-arm/cpu.c
>>> +++ b/target-arm/cpu.c
>> [...]
>>> @@ -343,6 +407,11 @@ static void arm_cpu_initfn(Object *obj)
>>>      cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
>>>                                           g_free, g_free);
>>>  
>>> +    object_property_add(obj, "apic-id", "int",
>>> +                    arm_cpuid_get_apic_id,
>>> +                    arm_cpuid_set_apic_id, NULL, NULL, NULL);
>>
>> The property is correctly called apic-id. Please update the commit
>> message, which has it as apic_id (2x).
> Is there such thing as apic-id on ARM?

Oops, confused it with ACPI... On ARM there's the GIC (or NVIC). There
are some IDs that are being represented in the device trees, with jumps
between clusters, i.e. 0..3 and 100..103 or so.

Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU
  2015-02-18 19:51     ` Igor Mammedov
  2015-02-18 19:57       ` Andreas Färber
@ 2015-02-19  8:22       ` Hanjun Guo
  1 sibling, 0 replies; 18+ messages in thread
From: Hanjun Guo @ 2015-02-19  8:22 UTC (permalink / raw)
  To: Igor Mammedov, Shannon Zhao
  Cc: peter.maydell, hangaohuai, mst, a.spyridakis, claudio.fontana,
	qemu-devel, peter.huangpeng, wanghaibin.wang, pbonzini, lersek,
	Andreas Färber, christoffer.dall

On 2015年02月19日 03:51, Igor Mammedov wrote:
> On Wed, 18 Feb 2015 18:45:51 +0100
> Andreas Färber <afaerber@suse.de> wrote:
>
>> Hi,
>>
>> Am 17.02.2015 um 11:10 schrieb Shannon Zhao:
>>> Add apic_id property for ARMCPU. It can be used for cpu hotplug.
>>>
>>> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
>>> ---
>>>   target-arm/cpu-qom.h |    1 +
>>>   target-arm/cpu.c     |   77
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>> target-arm/cpu.h     |    2 + 3 files changed, 80 insertions(+), 0
>>> deletions(-)
>>>
>>> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
>>> index ed5a644..d4560e2 100644
>>> --- a/target-arm/cpu-qom.h
>>> +++ b/target-arm/cpu-qom.h
>>> @@ -59,6 +59,7 @@ typedef struct ARMCPU {
>>>       /*< public >*/
>>>
>>>       CPUARMState env;
>>> +    uint32_t apic_id;
>>
>> Can you add a matching @apic_id: documentation entry above the struct?
>>
>>>
>>>       /* Coprocessor information */
>>>       GHashTable *cp_regs;
>>> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
>>> index 285947f..9202b07 100644
>>> --- a/target-arm/cpu.c
>>> +++ b/target-arm/cpu.c
>> [...]
>>> @@ -343,6 +407,11 @@ static void arm_cpu_initfn(Object *obj)
>>>       cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
>>>                                            g_free, g_free);
>>>
>>> +    object_property_add(obj, "apic-id", "int",
>>> +                    arm_cpuid_get_apic_id,
>>> +                    arm_cpuid_set_apic_id, NULL, NULL, NULL);
>>
>> The property is correctly called apic-id. Please update the commit
>> message, which has it as apic_id (2x).
> Is there such thing as apic-id on ARM?

Not apic-id, apic-id is x86 and ia64 dependent. On ARM, mpidr is
similar as apic-id to represent the CPU hardware ID, so I think
mpidr will be the one used in this patch, and another thing need
to consider that mpidr on ARM64 is 64 bits, not uint32_t.
Thanks
Hanjun

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support
  2015-02-18 17:19 ` [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Wei Huang
  2015-02-18 17:22   ` Wei Huang
@ 2015-02-26  7:32   ` Shannon Zhao
  2015-02-28  4:46     ` Wei Huang
  1 sibling, 1 reply; 18+ messages in thread
From: Shannon Zhao @ 2015-02-26  7:32 UTC (permalink / raw)
  To: Wei Huang, qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

On 2015/2/19 1:19, Wei Huang wrote:
> Nice work. I will help review the patches.
> 
Thanks for your help :-)

> Other than the CPU hotplug support, we are also seeking the guest VM
> powerdown support via ACPI. This feature is important for management
> tool to control guest VMs. In fact I had a similar GPIO patch for
> powerdown recently. Given that you already posted a more complete
> version, I wonder if you can add this feature to your patchset? FYI, I
> attached my powerdown patch in this email. Here is a brief list of items:
> 
> * DSDT description of power button (to-be-done)
> * Hook up with qemu_qemu_register_powerdown_notifier() with the GPIO IRQ
> 
> Feel free to add my name as signed-off-by in this feature if you decide
> to add it.

Yes, I think the powerdown support is very useful, but maybe this feature can be
added by a new patchset as this patchset cares about CPU hotplug.

We can add powerdown, memory hotplug, cpu remove and memory remove support step
by step if the approach of this patchset is accepted. I can make a patch to add
powerdown support based on this patchset and your attached patch if you want to
test this feature. How do you think about this?

-- 
Thanks,
Shannon

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller
  2015-02-18 17:52   ` Wei Huang
@ 2015-02-26  7:43     ` Shannon Zhao
  0 siblings, 0 replies; 18+ messages in thread
From: Shannon Zhao @ 2015-02-26  7:43 UTC (permalink / raw)
  To: Wei Huang, qemu-devel, peter.maydell, pbonzini, christoffer.dall,
	a.spyridakis, claudio.fontana, imammedo, hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng

On 2015/2/19 1:52, Wei Huang wrote:
> 
> 
> On 02/17/2015 04:10 AM, Shannon Zhao wrote:
>> Add a GPIO controller in machine virt, in order to support cpu hotplug.
>> Here we use pl061.
>>
>> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
>> ---
>>  hw/arm/virt.c |   28 ++++++++++++++++++++++++++++
>>  1 files changed, 28 insertions(+), 0 deletions(-)
>>
>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>> index 8a00574..43c0260 100644
>> --- a/hw/arm/virt.c
>> +++ b/hw/arm/virt.c
>> @@ -75,6 +75,7 @@ enum {
>>      VIRT_MMIO,
>>      VIRT_RTC,
>>      VIRT_FW_CFG,
>> +    VIRT_GPIO,
>>  };
>>  
>>  typedef struct MemMapEntry {
>> @@ -133,6 +134,7 @@ static const MemMapEntry a15memmap[] = {
>>      [VIRT_UART] =       { 0x09000000, 0x00001000 },
>>      [VIRT_RTC] =        { 0x09010000, 0x00001000 },
>>      [VIRT_FW_CFG] =     { 0x09020000, 0x0000000a },
>> +    [VIRT_GPIO] =       { 0x09500000, 0x00001000 },
> Base address can start with 0x09030000 to save some space?
> 
Ok
>>      [VIRT_MMIO] =       { 0x0a000000, 0x00000200 },
>>      /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
>>      /* 0x10000000 .. 0x40000000 reserved for PCI */
>> @@ -142,6 +144,7 @@ static const MemMapEntry a15memmap[] = {
>>  static const int a15irqmap[] = {
>>      [VIRT_UART] = 1,
>>      [VIRT_RTC] = 2,
>> +    [VIRT_GPIO] = 3,
>>      [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
>>  };
>>  
>> @@ -465,6 +468,29 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
>>      g_free(nodename);
>>  }
>>  
>> +static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
>> +{
>> +    char *nodename;
>> +    hwaddr base = vbi->memmap[VIRT_GPIO].base;
>> +    hwaddr size = vbi->memmap[VIRT_GPIO].size;
>> +    int irq = vbi->irqmap[VIRT_GPIO];
>> +    const char compat[] = "arm,pl061\0arm,primecell";
>> +
>> +    sysbus_create_simple("pl061", base, pic[irq]);
>> +
>> +    nodename = g_strdup_printf("/pl061@%" PRIx64, base);
>> +    qemu_fdt_add_subnode(vbi->fdt, nodename);
>> +    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
>> +                                 2, base, 2, size);
>> +    qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
>> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#gpio-cells", 2);
>> +    qemu_fdt_setprop(vbi->fdt, nodename, "gpio-controller", NULL, 0);
>> +    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
>> +                           GIC_FDT_IRQ_TYPE_SPI, irq,
>> +                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);
> Maybe also add clocks related properties (see below)? They might be
> optional, assuming that you already tested your patches.
> 

As mentioned in cover letter I haven't tested these patches very well.
I will test them seriously latter. Thanks for pointing this out.

> qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
> qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
> 
> 
>> +    g_free(nodename);
>> +}
>> +
>>  static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
>>  {
>>      int i;
>> @@ -680,6 +706,8 @@ static void machvirt_init(MachineState *machine)
>>  
>>      create_rtc(vbi, pic);
>>  
>> +    create_gpio(vbi, pic);
>> +
>>      /* Create mmio transports, so the user can create virtio backends
>>       * (which will be automatically plugged in to the transports). If
>>       * no backend is created the transport will just sit harmlessly idle.
>>
> 
> 
> .
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support
  2015-02-26  7:32   ` Shannon Zhao
@ 2015-02-28  4:46     ` Wei Huang
  0 siblings, 0 replies; 18+ messages in thread
From: Wei Huang @ 2015-02-28  4:46 UTC (permalink / raw)
  To: Shannon Zhao, qemu-devel, peter.maydell, pbonzini,
	christoffer.dall, a.spyridakis, claudio.fontana, imammedo,
	hanjun.guo, mst, lersek
  Cc: wanghaibin.wang, hangaohuai, peter.huangpeng



On 02/26/2015 01:32 AM, Shannon Zhao wrote:
> On 2015/2/19 1:19, Wei Huang wrote:
>> Nice work. I will help review the patches.
>>
> Thanks for your help :-)
> 
>> Other than the CPU hotplug support, we are also seeking the guest VM
>> powerdown support via ACPI. This feature is important for management
>> tool to control guest VMs. In fact I had a similar GPIO patch for
>> powerdown recently. Given that you already posted a more complete
>> version, I wonder if you can add this feature to your patchset? FYI, I
>> attached my powerdown patch in this email. Here is a brief list of items:
>>
>> * DSDT description of power button (to-be-done)
>> * Hook up with qemu_qemu_register_powerdown_notifier() with the GPIO IRQ
>>
>> Feel free to add my name as signed-off-by in this feature if you decide
>> to add it.
> 
> Yes, I think the powerdown support is very useful, but maybe this feature can be
> added by a new patchset as this patchset cares about CPU hotplug.
> 
> We can add powerdown, memory hotplug, cpu remove and memory remove support step
> by step if the approach of this patchset is accepted. I can make a patch to add
> powerdown support based on this patchset and your attached patch if you want to
> test this feature. How do you think about this?
That sounds good to me. It does make sense to separate them. Keep me in
loop.

Thanks,
-Wei
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-02-28  4:47 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-17 10:09 [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Shannon Zhao
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 1/7] hw/arm/virt: Add a GPIO controller Shannon Zhao
2015-02-18 17:52   ` Wei Huang
2015-02-26  7:43     ` Shannon Zhao
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 2/7] hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table Shannon Zhao
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 3/7] hw/acpi/virt-hotplug: Add a hotplug device for machine virt Shannon Zhao
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 4/7] topology: Move topology.h to an arch-independent location Shannon Zhao
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 5/7] target-arm/cpu: Add apic_id property for ARMCPU Shannon Zhao
2015-02-18 17:45   ` Andreas Färber
2015-02-18 19:51     ` Igor Mammedov
2015-02-18 19:57       ` Andreas Färber
2015-02-19  8:22       ` Hanjun Guo
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 6/7] hw/arm/virt: Add cpu hotplug support Shannon Zhao
2015-02-17 10:10 ` [Qemu-devel] [RFC PATCH 7/7] hw/arm/virt-acpi-build: Add cpu hotplug support in ACPI Shannon Zhao
2015-02-18 17:19 ` [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support Wei Huang
2015-02-18 17:22   ` Wei Huang
2015-02-26  7:32   ` Shannon Zhao
2015-02-28  4:46     ` Wei Huang

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.