From patchwork Tue Feb 17 10:10:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shannon Zhao X-Patchwork-Id: 440546 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7E2931402A0 for ; Tue, 17 Feb 2015 21:12:20 +1100 (AEDT) Received: from localhost ([::1]:44545 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNf8c-0008Mb-If for incoming@patchwork.ozlabs.org; Tue, 17 Feb 2015 05:12:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34429) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNf7s-0006z0-5w for qemu-devel@nongnu.org; Tue, 17 Feb 2015 05:11:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YNf7m-0000qF-4y for qemu-devel@nongnu.org; Tue, 17 Feb 2015 05:11:32 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:19533) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YNf7l-0000ny-9n for qemu-devel@nongnu.org; Tue, 17 Feb 2015 05:11:26 -0500 Received: from 172.24.2.119 (EHLO szxeml426-hub.china.huawei.com) ([172.24.2.119]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BCA97228; Tue, 17 Feb 2015 18:11:04 +0800 (CST) Received: from HGHY1Z002260041.china.huawei.com (10.177.16.142) by szxeml426-hub.china.huawei.com (10.82.67.181) with Microsoft SMTP Server id 14.3.158.1; Tue, 17 Feb 2015 18:10:54 +0800 From: Shannon Zhao To: , , , , , , , , , Date: Tue, 17 Feb 2015 18:10:02 +0800 Message-ID: <1424167806-8372-4-git-send-email-zhaoshenglong@huawei.com> X-Mailer: git-send-email 1.9.0.msysgit.0 In-Reply-To: <1424167806-8372-1-git-send-email-zhaoshenglong@huawei.com> References: <1424167806-8372-1-git-send-email-zhaoshenglong@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.16.142] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020202.54E313B8.0176, ss=1, re=0.001, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 775c362e7535ec3354bfb924e8af2385 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 119.145.14.66 Cc: wanghaibin.wang@huawei.com, hangaohuai@huawei.com, peter.huangpeng@huawei.com Subject: [Qemu-devel] [RFC PATCH 3/7] hw/acpi/virt-hotplug: Add a hotplug device for machine virt 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 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 --- 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 + * + * 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 . + */ + +#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