From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36822) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrVaI-0001Jt-HN for qemu-devel@nongnu.org; Fri, 13 Dec 2013 11:27:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VrVaC-000243-Cg for qemu-devel@nongnu.org; Fri, 13 Dec 2013 11:27:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:22377) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrVaC-00023o-4T for qemu-devel@nongnu.org; Fri, 13 Dec 2013 11:27:20 -0500 From: Igor Mammedov Date: Fri, 13 Dec 2013 17:22:08 +0100 Message-Id: <1386951736-929-4-git-send-email-imammedo@redhat.com> In-Reply-To: <1386951736-929-1-git-send-email-imammedo@redhat.com> References: <1386951736-929-1-git-send-email-imammedo@redhat.com> Subject: [Qemu-devel] [PATCH 03/11] acpi: factor out common cpu hotplug code for PIIX4/Q35 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: stefanha@redhat.com, mst@redhat.com, hutao@cn.fujitsu.com, jjherne@us.ibm.com, brogers@suse.com, kraxel@redhat.com, aliguori@amazon.com, kaneshige.kenji@jp.fujitsu.com, chen.fan.fnst@cn.fujitsu.com, pbonzini@redhat.com, lersek@redhat.com .. so it could be used for adding CPU hotplug to Q35 machine Signed-off-by: Igor Mammedov --- hw/acpi/Makefile.objs | 2 +- hw/acpi/hotplug.c | 65 +++++++++++++++++++++++++++++++++++++++ hw/acpi/piix4.c | 78 +++++------------------------------------------ include/hw/acpi/hotplug.h | 31 +++++++++++++++++++ 4 files changed, 104 insertions(+), 72 deletions(-) create mode 100644 hw/acpi/hotplug.c create mode 100644 include/hw/acpi/hotplug.h diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs index a0b63b5..41dec06 100644 --- a/hw/acpi/Makefile.objs +++ b/hw/acpi/Makefile.objs @@ -1,2 +1,2 @@ -common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o +common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o hotplug.o diff --git a/hw/acpi/hotplug.c b/hw/acpi/hotplug.c new file mode 100644 index 0000000..fcc0988 --- /dev/null +++ b/hw/acpi/hotplug.c @@ -0,0 +1,65 @@ +/* + * QEMU ACPI hotplug utilities + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "hw/hw.h" +#include "hw/acpi/hotplug.h" + +static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) +{ + AcpiCPUHotplug *cpus = opaque; + uint64_t val = cpus->sts[addr]; + + return val; +} + +static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) +{ + /* TODO: implement VCPU removal on guest signal that CPU can be removed */ +} + +static const MemoryRegionOps acpi_cpu_hotplug_ops = { + .read = cpu_status_read, + .write = cpu_status_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +void acpi_hotplug_cpu_add(ACPIGPE *gpe, AcpiCPUHotplug *g, CPUState *cpu) +{ + CPUClass *k = CPU_GET_CLASS(cpu); + int64_t cpu_id; + + *gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS; + cpu_id = k->get_arch_id(CPU(cpu)); + g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); +} + +void acpi_hotplug_cpu_init(MemoryRegion *parent, Object *owner, + AcpiCPUHotplug *gpe_cpu, uint16_t base) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + CPUClass *cc = CPU_GET_CLASS(cpu); + int64_t id = cc->get_arch_id(cpu); + + g_assert((id / 8) < ACPI_GPE_PROC_LEN); + gpe_cpu->sts[id / 8] |= (1 << (id % 8)); + } + gpe_cpu->io_base = base; + memory_region_init_io(&gpe_cpu->io, owner, &acpi_cpu_hotplug_ops, + gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN); + memory_region_add_subregion(parent, gpe_cpu->io_base, &gpe_cpu->io); +} diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b6b97ce..8ab85b2 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -30,6 +30,7 @@ #include "hw/nvram/fw_cfg.h" #include "exec/address-spaces.h" #include "hw/acpi/piix4.h" +#include "hw/acpi/hotplug.h" //#define DEBUG @@ -50,20 +51,14 @@ #define PCI_RMV_BASE 0xae0c #define PIIX4_PROC_BASE 0xaf00 -#define PIIX4_PROC_LEN 32 #define PIIX4_PCI_HOTPLUG_STATUS 2 -#define PIIX4_CPU_HOTPLUG_STATUS 4 struct pci_status { uint32_t up; /* deprecated, maintained for migration compatibility */ uint32_t down; }; -typedef struct CPUStatus { - uint8_t sts[PIIX4_PROC_LEN]; -} CPUStatus; - typedef struct PIIX4PMState { /*< private >*/ PCIDevice parent_obj; @@ -74,7 +69,6 @@ typedef struct PIIX4PMState { MemoryRegion io_gpe; MemoryRegion io_pci; - MemoryRegion io_cpu; ACPIREGS ar; APMState apm; @@ -97,7 +91,7 @@ typedef struct PIIX4PMState { uint8_t disable_s4; uint8_t s4_val; - CPUStatus gpe_cpu; + AcpiCPUHotplug gpe_cpu; Notifier cpu_added_notifier; } PIIX4PMState; @@ -628,61 +622,13 @@ static const MemoryRegionOps piix4_pci_ops = { }, }; -static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) -{ - PIIX4PMState *s = opaque; - CPUStatus *cpus = &s->gpe_cpu; - uint64_t val = cpus->sts[addr]; - - return val; -} - -static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data, - unsigned int size) -{ - /* TODO: implement VCPU removal on guest signal that CPU can be removed */ -} - -static const MemoryRegionOps cpu_hotplug_ops = { - .read = cpu_status_read, - .write = cpu_status_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 1, - .max_access_size = 1, - }, -}; - -typedef enum { - PLUG, - UNPLUG, -} HotplugEventType; - -static void piix4_cpu_hotplug_req(PIIX4PMState *s, CPUState *cpu, - HotplugEventType action) -{ - CPUStatus *g = &s->gpe_cpu; - ACPIGPE *gpe = &s->ar.gpe; - CPUClass *k = CPU_GET_CLASS(cpu); - int64_t cpu_id; - - assert(s != NULL); - - *gpe->sts = *gpe->sts | PIIX4_CPU_HOTPLUG_STATUS; - cpu_id = k->get_arch_id(CPU(cpu)); - if (action == PLUG) { - g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); - } else { - g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8)); - } - acpi_update_sci(&s->ar, s->irq); -} - static void piix4_cpu_added_req(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier); - piix4_cpu_hotplug_req(s, CPU(opaque), PLUG); + assert(s != NULL); + acpi_hotplug_cpu_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque)); + acpi_update_sci(&s->ar, s->irq); } static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, @@ -691,8 +637,6 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, PCIBus *bus, PIIX4PMState *s) { - CPUState *cpu; - memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s, "acpi-gpe0", GPE_LEN); memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe); @@ -703,16 +647,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, &s->io_pci); pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); - CPU_FOREACH(cpu) { - CPUClass *cc = CPU_GET_CLASS(cpu); - int64_t id = cc->get_arch_id(cpu); - - g_assert((id / 8) < PIIX4_PROC_LEN); - s->gpe_cpu.sts[id / 8] |= (1 << (id % 8)); - } - memory_region_init_io(&s->io_cpu, OBJECT(s), &cpu_hotplug_ops, s, - "acpi-cpu-hotplug", PIIX4_PROC_LEN); - memory_region_add_subregion(parent, PIIX4_PROC_BASE, &s->io_cpu); + acpi_hotplug_cpu_init(parent, OBJECT(s), &s->gpe_cpu, + PIIX4_PROC_BASE); s->cpu_added_notifier.notify = piix4_cpu_added_req; qemu_register_cpu_added_notifier(&s->cpu_added_notifier); } diff --git a/include/hw/acpi/hotplug.h b/include/hw/acpi/hotplug.h new file mode 100644 index 0000000..8bc176b --- /dev/null +++ b/include/hw/acpi/hotplug.h @@ -0,0 +1,31 @@ +/* + * QEMU ACPI hotplug utilities + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#ifndef ACPI_HOTPLUG_H +#define ACPI_HOTPLUG_H + +#include "hw/acpi/acpi.h" + +#define ACPI_CPU_HOTPLUG_STATUS 4 + +#define ACPI_GPE_PROC_LEN 32 + +typedef struct AcpiCPUHotplug { + MemoryRegion io; + uint16_t io_base; + uint8_t sts[ACPI_GPE_PROC_LEN]; +} AcpiCPUHotplug; + +void acpi_hotplug_cpu_add(ACPIGPE *gpe, AcpiCPUHotplug *g, CPUState *cpu); + +void acpi_hotplug_cpu_init(MemoryRegion *parent, Object *owner, + AcpiCPUHotplug *gpe_cpu, uint16_t base); +#endif -- 1.8.3.1