From patchwork Fri Dec 13 16:22:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Mammedov X-Patchwork-Id: 301094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D7BA32C009A for ; Sat, 14 Dec 2013 03:28:05 +1100 (EST) Received: from localhost ([::1]:43449 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrVat-0001WL-2B for incoming@patchwork.ozlabs.org; Fri, 13 Dec 2013 11:28:03 -0500 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 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rBDGRDxP031444 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Dec 2013 11:27:14 -0500 Received: from thinkpad.redhat.com (vpn-229-8.phx2.redhat.com [10.3.229.8]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rBDGMGiU029326; Fri, 13 Dec 2013 11:22:26 -0500 From: Igor Mammedov To: qemu-devel@nongnu.org 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> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 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 Subject: [Qemu-devel] [PATCH 03/11] acpi: factor out common cpu hotplug code for PIIX4/Q35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org .. 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