From patchwork Tue Sep 26 09:54:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398965 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 13D41E7D274 for ; Tue, 26 Sep 2023 09:55:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mH-0003YS-45; Tue, 26 Sep 2023 05:54:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mD-0003Xp-Fy for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:45 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4m9-0001bA-Pt for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:45 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8DxBfFeqhJlM6IsAA--.20146S3; Tue, 26 Sep 2023 17:54:38 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S3; Tue, 26 Sep 2023 17:54:36 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Salil Mehta" , "Salil Mehta" , "Bernhard Beschow" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 1/7] Update ACPI GED framework to support vcpu hot-(un)plug Date: Tue, 26 Sep 2023 17:54:26 +0800 Message-Id: <14ee117df13b08403032eb07843b91e1861228d9.1695697701.git.lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S3 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org ACPI GED shall be used to convey to the guest kernel about any cpu hot-(un)plug events. Therefore, existing ACPI GED framework inside QEMU needs to be enhanced to support CPU hot-(un)plug state and events. Co-authored-by: "Salil Mehta" Co-authored-by: "Salil Mehta" Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li Signed-off-by: must always be that of the developer submitting the patch. --- hw/acpi/acpi-cpu-hotplug-stub.c | 6 +++++ hw/acpi/cpu.c | 7 ------ hw/acpi/generic_event_device.c | 33 ++++++++++++++++++++++++++ include/hw/acpi/cpu_hotplug.h | 10 ++++++++ include/hw/acpi/generic_event_device.h | 5 ++++ 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c index 3fc4b14c26..2aec90d968 100644 --- a/hw/acpi/acpi-cpu-hotplug-stub.c +++ b/hw/acpi/acpi-cpu-hotplug-stub.c @@ -24,6 +24,12 @@ void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list) return; } +void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner, + CPUHotplugState *state, hwaddr base_addr) +{ + return; +} + void acpi_cpu_plug_cb(HotplugHandler *hotplug_dev, CPUHotplugState *cpu_st, DeviceState *dev, Error **errp) { diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index 011d2c6c2d..5bad983928 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -7,13 +7,6 @@ #include "trace.h" #include "sysemu/numa.h" -#define ACPI_CPU_HOTPLUG_REG_LEN 12 -#define ACPI_CPU_SELECTOR_OFFSET_WR 0 -#define ACPI_CPU_FLAGS_OFFSET_RW 4 -#define ACPI_CPU_CMD_OFFSET_WR 5 -#define ACPI_CPU_CMD_DATA_OFFSET_RW 8 -#define ACPI_CPU_CMD_DATA2_OFFSET_R 0 - #define OVMF_CPUHP_SMI_CMD 4 enum { diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c index a3d31631fe..c5a70957b4 100644 --- a/hw/acpi/generic_event_device.c +++ b/hw/acpi/generic_event_device.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "hw/acpi/acpi.h" +#include "hw/acpi/cpu.h" #include "hw/acpi/generic_event_device.h" #include "hw/irq.h" #include "hw/mem/pc-dimm.h" @@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = { ACPI_GED_MEM_HOTPLUG_EVT, ACPI_GED_PWR_DOWN_EVT, ACPI_GED_NVDIMM_HOTPLUG_EVT, + ACPI_GED_CPU_HOTPLUG_EVT, }; /* @@ -117,6 +119,10 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev, aml_notify(aml_name("\\_SB.NVDR"), aml_int(0x80))); break; + case ACPI_GED_CPU_HOTPLUG_EVT: + aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "." + ACPI_CPU_SCAN_METHOD)); + break; default: /* * Please make sure all the events in ged_supported_events[] @@ -234,6 +240,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev, } else { acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp); } + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp); } else { error_setg(errp, "virt: device plug request for unsupported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -248,6 +256,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev, if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) && !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) { acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp); } else { error_setg(errp, "acpi: device unplug request for unsupported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -261,6 +271,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev, if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { acpi_memory_unplug_cb(&s->memhp_state, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp); } else { error_setg(errp, "acpi: device unplug for unsupported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -272,6 +284,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) AcpiGedState *s = ACPI_GED(adev); acpi_memory_ospm_status(&s->memhp_state, list); + acpi_cpu_ospm_status(&s->cpuhp_state, list); } static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) @@ -286,6 +299,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) sel = ACPI_GED_PWR_DOWN_EVT; } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) { sel = ACPI_GED_NVDIMM_HOTPLUG_EVT; + } else if (ev & ACPI_CPU_HOTPLUG_STATUS) { + sel = ACPI_GED_CPU_HOTPLUG_EVT; } else { /* Unknown event. Return without generating interrupt. */ warn_report("GED: Unsupported event %d. No irq injected", ev); @@ -318,6 +333,16 @@ static const VMStateDescription vmstate_memhp_state = { } }; +static const VMStateDescription vmstate_cpuhp_state = { + .name = "acpi-ged/cpuhp", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_CPU_HOTPLUG(cpuhp_state, AcpiGedState), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_ged_state = { .name = "acpi-ged-state", .version_id = 1, @@ -366,6 +391,7 @@ static const VMStateDescription vmstate_acpi_ged = { }, .subsections = (const VMStateDescription * []) { &vmstate_memhp_state, + &vmstate_cpuhp_state, &vmstate_ghes_state, NULL } @@ -400,6 +426,13 @@ static void acpi_ged_initfn(Object *obj) memory_region_init_io(&ged_st->regs, obj, &ged_regs_ops, ged_st, TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT); sysbus_init_mmio(sbd, &ged_st->regs); + + s->cpuhp.device = OBJECT(s); + memory_region_init(&s->container_cpuhp, OBJECT(dev), "cpuhp container", + ACPI_CPU_HOTPLUG_REG_LEN); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container_cpuhp); + cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev), + &s->cpuhp_state, 0); } static void acpi_ged_class_init(ObjectClass *class, void *data) diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 3b932abbbb..afee1ab996 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -19,6 +19,16 @@ #include "hw/hotplug.h" #include "hw/acpi/cpu.h" +#define ACPI_CPU_HOTPLUG_REG_LEN 12 +#define ACPI_CPU_SELECTOR_OFFSET_WR 0 +#define ACPI_CPU_FLAGS_OFFSET_RW 4 +#define ACPI_CPU_CMD_OFFSET_WR 5 +#define ACPI_CPU_CMD_DATA_OFFSET_RW 8 +#define ACPI_CPU_CMD_DATA2_OFFSET_R 0 + +#define ACPI_CPU_SCAN_METHOD "CSCN" +#define ACPI_CPU_CONTAINER "\\_SB.CPUS" + typedef struct AcpiCpuHotplug { Object *device; MemoryRegion io; diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h index ba84ce0214..a803ea818e 100644 --- a/include/hw/acpi/generic_event_device.h +++ b/include/hw/acpi/generic_event_device.h @@ -60,6 +60,7 @@ #define HW_ACPI_GENERIC_EVENT_DEVICE_H #include "hw/sysbus.h" +#include "hw/acpi/cpu_hotplug.h" #include "hw/acpi/memory_hotplug.h" #include "hw/acpi/ghes.h" #include "qom/object.h" @@ -95,6 +96,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) #define ACPI_GED_MEM_HOTPLUG_EVT 0x1 #define ACPI_GED_PWR_DOWN_EVT 0x2 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 +#define ACPI_GED_CPU_HOTPLUG_EVT 0x8 typedef struct GEDState { MemoryRegion evt; @@ -106,6 +108,9 @@ struct AcpiGedState { SysBusDevice parent_obj; MemHotplugState memhp_state; MemoryRegion container_memhp; + CPUHotplugState cpuhp_state; + MemoryRegion container_cpuhp; + AcpiCpuHotplug cpuhp; GEDState ged_state; uint32_t ged_event_bitmap; qemu_irq irq; From patchwork Tue Sep 26 09:54:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398969 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 46D8CE7D273 for ; Tue, 26 Sep 2023 09:56:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4ma-0003ew-Pc; Tue, 26 Sep 2023 05:55:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mD-0003Y0-RK for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:45 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mA-0001b0-JM for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:45 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8AxDOteqhJlN6IsAA--.14714S3; Tue, 26 Sep 2023 17:54:38 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S4; Tue, 26 Sep 2023 17:54:37 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Bernhard Beschow" , "Salil Mehta" , "Salil Mehta" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 2/7] Update CPUs AML with cpu-(ctrl)dev change Date: Tue, 26 Sep 2023 17:54:27 +0800 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S4 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is based on PCI and is IO port based and hence existing cpus AML code assumes _CRS objects would evaluate to a system resource which describes IO Port address. But on Loongarch arch CPUs control device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should evaluate to system resource which describes memory-mapped base address. This cpus AML code change updates the existing interface of the build cpus AML function to accept both IO/MEMORY type regions and update the _CRS object correspondingly. Co-authored-by: "Bernhard Beschow" Co-authored-by: "Salil Mehta" Co-authored-by: "Salil Mehta" Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li Signed-off-by: Michael S. Tsirkin --- hw/acpi/cpu.c | 20 +++++++++++++++----- hw/i386/acpi-build.c | 3 ++- include/hw/acpi/cpu.h | 5 +++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index 5bad983928..0afa04832e 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -6,6 +6,7 @@ #include "qapi/qapi-events-acpi.h" #include "trace.h" #include "sysemu/numa.h" +#include "hw/acpi/cpu_hotplug.h" #define OVMF_CPUHP_SMI_CMD 4 @@ -332,9 +333,10 @@ const VMStateDescription vmstate_cpu_hotplug = { #define CPU_FW_EJECT_EVENT "CEJF" void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - build_madt_cpu_fn build_madt_cpu, hwaddr io_base, + build_madt_cpu_fn build_madt_cpu, hwaddr mmap_io_base, const char *res_root, - const char *event_handler_method) + const char *event_handler_method, + AmlRegionSpace rs) { Aml *ifctx; Aml *field; @@ -359,14 +361,22 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0)); crs = aml_resource_template(); - aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1, + if (rs == AML_SYSTEM_IO) { + aml_append(crs, aml_io(AML_DECODE16, mmap_io_base, mmap_io_base, 1, ACPI_CPU_HOTPLUG_REG_LEN)); + } else { + aml_append(crs, aml_memory32_fixed(mmap_io_base, + ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE)); + } + aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs)); + g_assert(rs == AML_SYSTEM_IO || rs == AML_SYSTEM_MEMORY); /* declare CPU hotplug MMIO region with related access fields */ aml_append(cpu_ctrl_dev, - aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base), - ACPI_CPU_HOTPLUG_REG_LEN)); + aml_operation_region("PRST", rs, + aml_int(mmap_io_base), + ACPI_CPU_HOTPLUG_REG_LEN)); field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 863a939210..7016205d15 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1550,7 +1550,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, .fw_unplugs_cpu = pm->smi_on_cpu_unplug, }; build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry, - pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02"); + pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02", + AML_SYSTEM_IO); } if (pcms->memhp_io_base && nr_mem) { diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h index bc901660fb..601f644e57 100644 --- a/include/hw/acpi/cpu.h +++ b/include/hw/acpi/cpu.h @@ -60,9 +60,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - build_madt_cpu_fn build_madt_cpu, hwaddr io_base, + build_madt_cpu_fn build_madt_cpu, hwaddr mmap_io_base, const char *res_root, - const char *event_handler_method); + const char *event_handler_method, + AmlRegionSpace rs); void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list); From patchwork Tue Sep 26 09:54:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398967 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F1271E7D270 for ; Tue, 26 Sep 2023 09:55:46 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mM-0003cF-R4; Tue, 26 Sep 2023 05:54:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mF-0003Z2-8A for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:47 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mB-0001b8-FS for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:47 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxtPBfqhJlPqIsAA--.20863S3; Tue, 26 Sep 2023 17:54:39 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S5; Tue, 26 Sep 2023 17:54:38 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Bernhard Beschow" , "Salil Mehta" , "Salil Mehta" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 3/7] Added CPU topology support for Loongarch Date: Tue, 26 Sep 2023 17:54:28 +0800 Message-Id: <332ee85871e83bb972d17be8f905fdd42cd1662b.1695697701.git.lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S5 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 1.Add topological relationships for Loongarch VCPU and initialize topology member variables. 2.Add a description of the calculation method of the arch_id and the topological relationship of the CPU. Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li --- docs/system/loongarch/virt.rst | 31 ++++++++++ hw/loongarch/virt.c | 101 ++++++++++++++++++++++++++------- target/loongarch/cpu.c | 13 ++++- target/loongarch/cpu.h | 12 +++- 4 files changed, 134 insertions(+), 23 deletions(-) diff --git a/docs/system/loongarch/virt.rst b/docs/system/loongarch/virt.rst index c37268b404..eaba9e2fd7 100644 --- a/docs/system/loongarch/virt.rst +++ b/docs/system/loongarch/virt.rst @@ -28,6 +28,37 @@ The ``qemu-system-loongarch64`` provides emulation for virt machine. You can specify the machine type ``virt`` and cpu type ``la464``. +CPU Topology +-------------------- + +The ``LA464`` type CPUs have the concept of Socket Core and Thread. + +For example: + +``-smp 1,maxcpus=M,sockets=S,cores=C,threads=T`` + +The above parameters indicate that the machine has a maximum of ``M`` vCPUs and +``S`` sockets, each socket has ``C`` cores, each core has ``T`` threads, +and each thread corresponds to a vCPU. + +Then ``M`` ``S`` ``C`` ``T`` has the following relationship: + +``M = S * C * T`` + +In the CPU topology relationship, When we know the ``socket_id`` ``core_id`` +and ``thread_id`` of the CPU, we can calculate its ``arch_id``: + +``arch_id = (socket_id * S) + (core_id * C) + (thread_id * T)`` + +Similarly, when we know the ``arch_id`` of the CPU, +we can also get its ``socket_id`` ``core_id`` and ``thread_id``: + +``socket_id = arch_id / (C * T)`` + +``core_id = (arch_id / T) % C`` + +``thread_id = arch_id % T`` + Boot options ------------ diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 2629128aed..b8474e7b94 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -624,11 +624,11 @@ static void loongarch_irq_init(LoongArchMachineState *lams) sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1)); /* - * extioi iocsr memory region - * only one extioi is added on loongarch virt machine - * external device interrupt can only be routed to cpu 0-3 - */ - if (cpu < EXTIOI_CPUS) + * extioi iocsr memory region + * only one extioi is added on loongarch virt machine + * external device interrupt can only be routed to cpu 0-3 + */ + if (cpu < EXTIOI_CPUS) memory_region_add_subregion(&env->system_iocsr, APIC_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), cpu)); @@ -789,9 +789,7 @@ static void loongarch_init(MachineState *machine) NodeInfo *numa_info = machine->numa_state->nodes; int i; hwaddr fdt_base; - const CPUArchIdList *possible_cpus; MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUState *cpu; char *ramName = NULL; if (!cpu_model) { @@ -803,16 +801,41 @@ static void loongarch_init(MachineState *machine) exit(1); } create_fdt(lams); - /* Init CPUs */ - possible_cpus = mc->possible_cpu_arch_ids(machine); - for (i = 0; i < possible_cpus->len; i++) { - cpu = cpu_create(machine->cpu_type); - cpu->cpu_index = i; - machine->possible_cpus->cpus[i].cpu = OBJECT(cpu); - lacpu = LOONGARCH_CPU(cpu); - lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id; + /* Init CPUs */ + mc->possible_cpu_arch_ids(machine); + for (i = 0; i < machine->smp.cpus; i++) { + Object *cpuobj; + cpuobj = object_new(machine->cpu_type); + lacpu = LOONGARCH_CPU(cpuobj); + + lacpu->arch_id = machine->possible_cpus->cpus[i].arch_id; + object_property_set_int(cpuobj, "socket-id", + machine->possible_cpus->cpus[i].props.socket_id, + NULL); + object_property_set_int(cpuobj, "core-id", + machine->possible_cpus->cpus[i].props.core_id, + NULL); + object_property_set_int(cpuobj, "thread-id", + machine->possible_cpus->cpus[i].props.thread_id, + NULL); + /* + * The CPU in place at the time of machine startup will also enter + * the CPU hot-plug process when it is created, but at this time, + * the GED device has not been created, resulting in exit in the CPU + * hot-plug process, which can avoid the incumbent CPU repeatedly + * applying for resources. + * + * The interrupt resource of the in-place CPU will be requested at + * the current function call loongarch_irq_init(). + * + * The interrupt resource of the subsequently inserted CPU will be + * requested in the CPU hot-plug process. + */ + qdev_realize(DEVICE(cpuobj), NULL, &error_fatal); + object_unref(cpuobj); } + fdt_add_cpu_nodes(lams); /* Node0 memory */ @@ -983,6 +1006,37 @@ static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp); } +static int virt_get_arch_id_from_cpu_topo(const MachineState *ms, + LoongArchCPUTopo *cpu_topo) +{ + int arch_id, sock_vcpu_num, core_vcpu_num; + + /* + * calculate total logical cpus across socket/core/thread. + * For more information on how to calculate the arch_id, + * you can refer to the CPU Topology chapter of the + * docs/system/loongarch/virt.rst document. + */ + sock_vcpu_num = cpu_topo->socket_id * (ms->smp.threads * ms->smp.cores); + core_vcpu_num = cpu_topo->core_id * ms->smp.threads; + + /* get vcpu-id(logical cpu index) for this vcpu from this topology */ + arch_id = (sock_vcpu_num + core_vcpu_num) + cpu_topo->thread_id; + + assert(arch_id >= 0 && arch_id < ms->possible_cpus->len); + + return arch_id; +} + +static void virt_get_cpu_topo_by_cpu_index(const MachineState *ms, + LoongArchCPUTopo *cpu_topo, + int cpu_index) +{ + cpu_topo->socket_id = cpu_index / (ms->smp.cores * ms->smp.threads); + cpu_topo->core_id = cpu_index / ms->smp.threads % ms->smp.cores; + cpu_topo->thread_id = cpu_index % ms->smp.threads; +} + static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1069,6 +1123,8 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) { int n; unsigned int max_cpus = ms->smp.max_cpus; + unsigned int smp_threads = ms->smp.threads; + LoongArchCPUTopo cpu_topo; if (ms->possible_cpus) { assert(ms->possible_cpus->len == max_cpus); @@ -1079,17 +1135,20 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) sizeof(CPUArchId) * max_cpus); ms->possible_cpus->len = max_cpus; for (n = 0; n < ms->possible_cpus->len; n++) { + ms->possible_cpus->cpus[n].vcpus_count = smp_threads; ms->possible_cpus->cpus[n].type = ms->cpu_type; - ms->possible_cpus->cpus[n].arch_id = n; + + virt_get_cpu_topo_by_cpu_index(ms, &cpu_topo, n); ms->possible_cpus->cpus[n].props.has_socket_id = true; - ms->possible_cpus->cpus[n].props.socket_id = - n / (ms->smp.cores * ms->smp.threads); + ms->possible_cpus->cpus[n].props.socket_id = cpu_topo.socket_id; ms->possible_cpus->cpus[n].props.has_core_id = true; - ms->possible_cpus->cpus[n].props.core_id = - n / ms->smp.threads % ms->smp.cores; + ms->possible_cpus->cpus[n].props.core_id = cpu_topo.core_id; ms->possible_cpus->cpus[n].props.has_thread_id = true; - ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads; + ms->possible_cpus->cpus[n].props.thread_id = cpu_topo.thread_id; + + ms->possible_cpus->cpus[n].arch_id = + virt_get_arch_id_from_cpu_topo(ms, &cpu_topo); } return ms->possible_cpus; } diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index fc7f70fbe5..40b856554f 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -20,6 +20,7 @@ #include "sysemu/reset.h" #include "tcg/tcg.h" #include "vec.h" +#include "hw/qdev-properties.h" const char * const regnames[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -732,10 +733,19 @@ static int64_t loongarch_cpu_get_arch_id(CPUState *cs) { LoongArchCPU *cpu = LOONGARCH_CPU(cs); - return cpu->phy_id; + return cpu->arch_id; } #endif +static Property loongarch_cpu_properties[] = { + DEFINE_PROP_INT32("socket-id", LoongArchCPU, socket_id, 0), + DEFINE_PROP_INT32("core-id", LoongArchCPU, core_id, 0), + DEFINE_PROP_INT32("thread-id", LoongArchCPU, thread_id, 0), + DEFINE_PROP_INT32("node-id", LoongArchCPU, node_id, CPU_UNSET_NUMA_NODE_ID), + + DEFINE_PROP_END_OF_LIST() +}; + static void loongarch_cpu_class_init(ObjectClass *c, void *data) { LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c); @@ -743,6 +753,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data) DeviceClass *dc = DEVICE_CLASS(c); ResettableClass *rc = RESETTABLE_CLASS(c); + device_class_set_props(dc, loongarch_cpu_properties); device_class_set_parent_realize(dc, loongarch_cpu_realizefn, &lacc->parent_realize); resettable_class_set_parent_phases(rc, NULL, loongarch_cpu_reset_hold, NULL, diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f125a8e49b..838492f014 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -364,6 +364,12 @@ typedef struct CPUArchState { #endif } CPULoongArchState; +typedef struct LoongArchCPUTopo { + int32_t socket_id; /* socket-id of this VCPU */ + int32_t core_id; /* core-id of this VCPU */ + int32_t thread_id; /* thread-id of this VCPU */ +} LoongArchCPUTopo; + /** * LoongArchCPU: * @env: #CPULoongArchState @@ -375,10 +381,14 @@ struct ArchCPU { CPUState parent_obj; /*< public >*/ + int32_t socket_id; /* socket-id of this VCPU */ + int32_t core_id; /* core-id of this VCPU */ + int32_t thread_id; /* thread-id of this VCPU */ + int32_t node_id; /* NUMA node this CPU belongs to */ CPUNegativeOffsetState neg; CPULoongArchState env; QEMUTimer timer; - uint32_t phy_id; + uint32_t arch_id; /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; From patchwork Tue Sep 26 09:54:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398964 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5EDB6E7D273 for ; Tue, 26 Sep 2023 09:55:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mK-0003bu-TI; Tue, 26 Sep 2023 05:54:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mF-0003Yz-5m for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:47 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mC-0001bC-JI for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:46 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8BxXetfqhJlSKIsAA--.14715S3; Tue, 26 Sep 2023 17:54:39 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S6; Tue, 26 Sep 2023 17:54:38 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Bernhard Beschow" , "Salil Mehta" , "Salil Mehta" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 4/7] Optimize loongarch_irq_init function implementation Date: Tue, 26 Sep 2023 17:54:29 +0800 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S6 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Optimize loongarch_irq_init function implementation and abstract the function loongarch_cpu_irq_init from it. Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li --- hw/loongarch/virt.c | 105 ++++++++++++++++++++---------------- include/hw/loongarch/virt.h | 5 +- 2 files changed, 62 insertions(+), 48 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index b8474e7b94..fb06b4ab4e 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -46,6 +46,8 @@ #include "hw/block/flash.h" #include "qemu/error-report.h" +static LoongArchCPU *loongarch_cpu_irq_init(MachineState *machine, + LoongArchCPU *cpu, Error **errp); static void virt_flash_create(LoongArchMachineState *lams) { @@ -573,16 +575,16 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * static void loongarch_irq_init(LoongArchMachineState *lams) { MachineState *ms = MACHINE(lams); - DeviceState *pch_pic, *pch_msi, *cpudev; - DeviceState *ipi, *extioi; + DeviceState *pch_pic, *pch_msi; + DeviceState *extioi; SysBusDevice *d; LoongArchCPU *lacpu; - CPULoongArchState *env; CPUState *cpu_state; - int cpu, pin, i, start, num; + int cpu, i, start, num; extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); + lams->extioi = extioi; /* * The connection of interrupts: @@ -607,44 +609,8 @@ static void loongarch_irq_init(LoongArchMachineState *lams) */ for (cpu = 0; cpu < ms->smp.cpus; cpu++) { cpu_state = qemu_get_cpu(cpu); - cpudev = DEVICE(cpu_state); lacpu = LOONGARCH_CPU(cpu_state); - env = &(lacpu->env); - - ipi = qdev_new(TYPE_LOONGARCH_IPI); - sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); - - /* connect ipi irq to cpu irq */ - qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI)); - /* IPI iocsr memory region */ - memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX, - sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), - 0)); - memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR, - sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), - 1)); - /* - * extioi iocsr memory region - * only one extioi is added on loongarch virt machine - * external device interrupt can only be routed to cpu 0-3 - */ - if (cpu < EXTIOI_CPUS) - memory_region_add_subregion(&env->system_iocsr, APIC_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), - cpu)); - env->ipistate = ipi; - } - - /* - * connect ext irq to the cpu irq - * cpu_pin[9:2] <= intc_pin[7:0] - */ - for (cpu = 0; cpu < MIN(ms->smp.cpus, EXTIOI_CPUS); cpu++) { - cpudev = DEVICE(qemu_get_cpu(cpu)); - for (pin = 0; pin < LS3A_INTC_IP; pin++) { - qdev_connect_gpio_out(extioi, (cpu * 8 + pin), - qdev_get_gpio_in(cpudev, pin + 2)); - } + loongarch_cpu_irq_init(ms, lacpu, &error_fatal); } pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC); @@ -927,11 +893,7 @@ static void loongarch_init(MachineState *machine) } } fdt_add_flash_node(lams); - /* register reset function */ - for (i = 0; i < machine->smp.cpus; i++) { - lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); - qemu_register_reset(reset_load_elf, lacpu); - } + /* Initialize the IO interrupt subsystem */ loongarch_irq_init(lams); fdt_add_irqchip_node(lams); @@ -1091,6 +1053,57 @@ static void virt_mem_plug(HotplugHandler *hotplug_dev, dev, &error_abort); } +static LoongArchCPU *loongarch_cpu_irq_init(MachineState *machine, + LoongArchCPU *cpu, Error **errp) +{ + LoongArchMachineState *lsms = LOONGARCH_MACHINE(machine); + CPUState *cs = CPU(cpu); + unsigned int cpu_index = cs->cpu_index; + DeviceState *cpudev = DEVICE(cpu); + DeviceState *extioi = lsms->extioi; + CPULoongArchState *env = &cpu->env; + DeviceState *ipi; + int pin; + + qemu_register_reset(reset_load_elf, cpu); + + ipi = qdev_new(TYPE_LOONGARCH_IPI); + sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), errp); + + /* connect ipi irq to cpu irq */ + qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI)); + /* IPI iocsr memory region */ + memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), + 0)); + memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), + 1)); + /* + * extioi iocsr memory region + * only one extioi is added on loongarch virt machine + * external device interrupt can only be routed to cpu 0-3 + */ + if (cpu_index < EXTIOI_CPUS) + memory_region_add_subregion(&env->system_iocsr, APIC_BASE, + sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), + cpu_index)); + env->ipistate = ipi; + + /* + * connect ext irq to the cpu irq + * cpu_pin[9:2] <= intc_pin[7:0] + */ + if (cpu_index < EXTIOI_CPUS) { + for (pin = 0; pin < LS3A_INTC_IP; pin++) { + qdev_connect_gpio_out(extioi, (cpu_index * 8 + pin), + qdev_get_gpio_in(cpudev, pin + 2)); + } + } + + return cpu; +} + static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index f1659655c6..176dc43a93 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -42,7 +42,7 @@ struct LoongArchMachineState { MemoryRegion bios; bool bios_loaded; /* State for other subsystems/APIs: */ - FWCfgState *fw_cfg; + FWCfgState *fw_cfg; Notifier machine_done; Notifier powerdown_notifier; OnOffAuto acpi; @@ -50,9 +50,10 @@ struct LoongArchMachineState { char *oem_table_id; DeviceState *acpi_ged; int fdt_size; - DeviceState *platform_bus_dev; + DeviceState *platform_bus_dev; PCIBus *pci_bus; PFlashCFI01 *flash; + DeviceState *extioi; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") From patchwork Tue Sep 26 09:54:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398963 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1332FE7D271 for ; Tue, 26 Sep 2023 09:55:16 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mJ-0003bq-Eg; Tue, 26 Sep 2023 05:54:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mE-0003YA-20 for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:46 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mB-0001bE-3a for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:45 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Cx7+tfqhJlT6IsAA--.18802S3; Tue, 26 Sep 2023 17:54:39 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S7; Tue, 26 Sep 2023 17:54:39 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Bernhard Beschow" , "Salil Mehta" , "Salil Mehta" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 5/7] Add basic CPU hot-(un)plug support for Loongarch Date: Tue, 26 Sep 2023 17:54:30 +0800 Message-Id: <52bbbc0b77cb103908d8d6e7cd0c959bf9afbdaa.1695697701.git.lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S7 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add CPU hot-(un)plug related hook functions and turn on the CPU hot-(un)plug custom switch. Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li --- .../devices/loongarch64-softmmu/default.mak | 1 + hw/loongarch/virt.c | 210 ++++++++++++++++++ 2 files changed, 211 insertions(+) diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak index 928bc117ef..e596706fab 100644 --- a/configs/devices/loongarch64-softmmu/default.mak +++ b/configs/devices/loongarch64-softmmu/default.mak @@ -1,3 +1,4 @@ # Default configuration for loongarch64-softmmu CONFIG_LOONGARCH_VIRT=y +CONFIG_ACPI_CPU_HOTPLUG=y diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index fb06b4ab4e..c704f3117f 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -999,11 +999,93 @@ static void virt_get_cpu_topo_by_cpu_index(const MachineState *ms, cpu_topo->thread_id = cpu_index % ms->smp.threads; } +/* find cpu slot in machine->possible_cpus by arch_id */ +static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, int arch_id) +{ + int n; + for (n = 0; n < ms->possible_cpus->len; n++) { + if (ms->possible_cpus->cpus[n].arch_id == arch_id) { + return &ms->possible_cpus->cpus[n]; + } + } + + return NULL; +} + +static void loongarch_cpu_pre_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + MachineState *ms = MACHINE(OBJECT(hotplug_dev)); + MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev); + LoongArchCPU *cpu = LOONGARCH_CPU(dev); + CPUState *cs = CPU(dev); + CPUArchId *cpu_slot; + Error *local_err = NULL; + LoongArchCPUTopo cpu_topo; + int arch_id; + + if (dev->hotplugged && !mc->has_hotpluggable_cpus) { + error_setg(&local_err, "CPU hotplug not supported for this machine"); + goto out; + } + + /* sanity check the cpu */ + if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { + error_setg(&local_err, "Invalid CPU type, expected cpu type: '%s'", + ms->cpu_type); + goto out; + } + + if ((cpu->thread_id < 0) || (cpu->thread_id >= ms->smp.threads)) { + error_setg(&local_err, + "Invalid thread-id %u specified, must be in range 1:%u", + cpu->thread_id, ms->smp.threads - 1); + goto out; + } + + if ((cpu->core_id < 0) || (cpu->core_id >= ms->smp.cores)) { + error_setg(&local_err, + "Invalid core-id %u specified, must be in range 1:%u", + cpu->core_id, ms->smp.cores); + goto out; + } + + if ((cpu->socket_id < 0) || (cpu->socket_id >= ms->smp.sockets)) { + error_setg(&local_err, + "Invalid socket-id %u specified, must be in range 1:%u", + cpu->socket_id, ms->smp.sockets - 1); + goto out; + } + + cpu_topo.socket_id = cpu->socket_id; + cpu_topo.core_id = cpu->core_id; + cpu_topo.thread_id = cpu->thread_id; + arch_id = virt_get_arch_id_from_cpu_topo(ms, &cpu_topo); + + cpu_slot = loongarch_find_cpu_slot(ms, arch_id); + if (CPU(cpu_slot->cpu)) { + error_setg(&local_err, + "cpu(id%d=%d:%d:%d) with arch-id %" PRIu64 " exists", + cs->cpu_index, cpu->socket_id, cpu->core_id, + cpu->thread_id, cpu_slot->arch_id); + goto out; + } + cpu->arch_id = arch_id; + + numa_cpu_pre_plug(cpu_slot, dev, &local_err); + + return ; +out: + error_propagate(errp, local_err); +} + static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (memhp_type_supported(dev)) { virt_mem_pre_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { + loongarch_cpu_pre_plug(hotplug_dev, dev, errp); } } @@ -1017,11 +1099,45 @@ static void virt_mem_unplug_request(HotplugHandler *hotplug_dev, errp); } +static void loongarch_cpu_unplug_request(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + MachineState *machine = MACHINE(OBJECT(hotplug_dev)); + LoongArchMachineState *lsms = LOONGARCH_MACHINE(machine); + Error *local_err = NULL; + HotplugHandlerClass *hhc; + LoongArchCPU *cpu = LOONGARCH_CPU(dev); + CPUState *cs = CPU(dev); + + if (!lsms->acpi_ged) { + error_setg(&local_err, "CPU hot unplug not supported without ACPI"); + goto out; + } + + if (cs->cpu_index == 0) { + error_setg(&local_err, + "hot-unplug of boot cpu(id%d=%d:%d:%d) not supported", + cs->cpu_index, cpu->socket_id, + cpu->core_id, cpu->thread_id); + goto out; + } + + + hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_ged); + hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_ged), dev, &local_err); + + return; + out: + error_propagate(errp, local_err); +} + static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (memhp_type_supported(dev)) { virt_mem_unplug_request(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { + loongarch_cpu_unplug_request(hotplug_dev, dev, errp); } } @@ -1035,11 +1151,74 @@ static void virt_mem_unplug(HotplugHandler *hotplug_dev, qdev_unrealize(dev); } +static void loongarch_cpu_irq_uninit(MachineState *machine, + LoongArchCPU *cpu) +{ + LoongArchMachineState *lsms = LOONGARCH_MACHINE(machine); + CPULoongArchState *env = &cpu->env; + DeviceState *ipi = env->ipistate; + CPUState *cs = CPU(cpu); + unsigned int cpu_index = cs->cpu_index; + DeviceState *extioi = lsms->extioi; + + qemu_unregister_reset(reset_load_elf, DEVICE(cpu)); + + /* del IPI iocsr memory region */ + memory_region_del_subregion(&env->system_iocsr, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), + 0)); + memory_region_del_subregion(&env->system_iocsr, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), + 1)); + + env->ipistate = NULL; + object_unparent(OBJECT(ipi)); + + /* + * del extioi iocsr memory region + * only one extioi is added on loongarch virt machine + * external device interrupt can only be routed to cpu 0-3 + */ + if (cpu_index < EXTIOI_CPUS) + memory_region_del_subregion(&env->system_iocsr, + sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), + cpu_index)); +} + +static void loongarch_cpu_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + CPUArchId *found_cpu; + HotplugHandlerClass *hhc; + Error *local_err = NULL; + LoongArchCPU *cpu = LOONGARCH_CPU(dev); + MachineState *machine = MACHINE(OBJECT(hotplug_dev)); + LoongArchMachineState *lsms = LOONGARCH_MACHINE(machine); + + hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_ged); + hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_ged), dev, &local_err); + + if (local_err) { + goto out; + } + + loongarch_cpu_irq_uninit(machine, cpu); + + found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->arch_id); + found_cpu->cpu = NULL; + + return; +out: + error_propagate(errp, local_err); +} + static void virt_machine_device_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (memhp_type_supported(dev)) { virt_mem_unplug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { + loongarch_cpu_unplug(hotplug_dev, dev, errp); } } @@ -1104,6 +1283,33 @@ static LoongArchCPU *loongarch_cpu_irq_init(MachineState *machine, return cpu; } +static void loongarch_cpu_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + CPUArchId *found_cpu; + HotplugHandlerClass *hhc; + Error *local_err = NULL; + MachineState *machine = MACHINE(OBJECT(hotplug_dev)); + LoongArchMachineState *lsms = LOONGARCH_MACHINE(machine); + LoongArchCPU *cpu = LOONGARCH_CPU(dev); + + if (lsms->acpi_ged) { + loongarch_cpu_irq_init(machine, cpu, errp); + hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_ged); + hhc->plug(HOTPLUG_HANDLER(lsms->acpi_ged), dev, &local_err); + if (local_err) { + goto out; + } + } + + found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->arch_id); + found_cpu->cpu = OBJECT(dev); + + return; +out: + error_propagate(errp, local_err); +} + static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1117,6 +1323,8 @@ static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, } } else if (memhp_type_supported(dev)) { virt_mem_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { + loongarch_cpu_plug(hotplug_dev, dev, errp); } } @@ -1126,6 +1334,7 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, MachineClass *mc = MACHINE_GET_CLASS(machine); if (device_is_dynamic_sysbus(mc, dev) || + object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) || memhp_type_supported(dev)) { return HOTPLUG_HANDLER(machine); } @@ -1194,6 +1403,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); + mc->has_hotpluggable_cpus = true; mc->desc = "Loongson-3A5000 LS7A1000 machine"; mc->init = loongarch_init; mc->default_ram_size = 1 * GiB; From patchwork Tue Sep 26 09:54:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398968 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0BD1BE7D271 for ; Tue, 26 Sep 2023 09:56:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mb-0003fA-DL; Tue, 26 Sep 2023 05:55:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mE-0003Yb-NO for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:46 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mB-0001bJ-KO for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:46 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Dx_+tgqhJlVqIsAA--.18889S3; Tue, 26 Sep 2023 17:54:40 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S8; Tue, 26 Sep 2023 17:54:39 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Bernhard Beschow" , "Salil Mehta" , "Salil Mehta" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 6/7] Add support of *unrealize* for Loongarch cpu Date: Tue, 26 Sep 2023 17:54:31 +0800 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S8 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add the unrealize function to the Loongarch CPU for cpu hot-(un)plug Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li --- target/loongarch/cpu.c | 20 ++++++++++++++++++++ target/loongarch/cpu.h | 1 + 2 files changed, 21 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 40b856554f..92fb23704f 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -576,6 +576,22 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) lacc->parent_realize(dev, errp); } +static void loongarch_cpu_unrealizefn(DeviceState *dev) +{ + LoongArchCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); + +#ifndef CONFIG_USER_ONLY + LoongArchCPU *cpu = LOONGARCH_CPU(dev); + CPULoongArchState *env = &cpu->env; + + cpu_remove_sync(CPU(dev)); + address_space_destroy(&env->address_space_iocsr); + memory_region_del_subregion(&env->system_iocsr, &env->iocsr_mem); +#endif + + mcc->parent_unrealize(dev); +} + #ifndef CONFIG_USER_ONLY static void loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) @@ -756,6 +772,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data) device_class_set_props(dc, loongarch_cpu_properties); device_class_set_parent_realize(dc, loongarch_cpu_realizefn, &lacc->parent_realize); + device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn, + &lacc->parent_unrealize); + resettable_class_set_parent_phases(rc, NULL, loongarch_cpu_reset_hold, NULL, &lacc->parent_phases); @@ -777,6 +796,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data) #ifdef CONFIG_TCG cc->tcg_ops = &loongarch_tcg_ops; #endif + dc->user_creatable = true; } static gchar *loongarch32_gdb_arch_name(CPUState *cs) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 838492f014..ec4a9ff166 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -414,6 +414,7 @@ struct LoongArchCPUClass { /*< public >*/ DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; ResettablePhases parent_phases; }; From patchwork Tue Sep 26 09:54:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xianglai Li X-Patchwork-Id: 13398966 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3F498E7D270 for ; Tue, 26 Sep 2023 09:55:17 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mS-0003dL-Bv; Tue, 26 Sep 2023 05:55:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ql4mF-0003Z7-AB for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:47 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ql4mC-0001bL-K2 for qemu-devel@nongnu.org; Tue, 26 Sep 2023 05:54:47 -0400 Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8BxNuhgqhJlXaIsAA--.31738S3; Tue, 26 Sep 2023 17:54:40 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd5YqhJlTJgSAA--.40131S9; Tue, 26 Sep 2023 17:54:39 +0800 (CST) From: xianglai li To: qemu-devel@nongnu.org Cc: "Bernhard Beschow" , "Salil Mehta" , "Salil Mehta" , Xiaojuan Yang , Song Gao , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Peter Xu , David Hildenbrand , Bibo Mao Subject: [PATCH v3 7/7] Update the ACPI table for the Loongarch CPU Date: Tue, 26 Sep 2023 17:54:32 +0800 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dxnd5YqhJlTJgSAA--.40131S9 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass client-ip=114.242.206.163; envelope-from=lixianglai@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add new types of GED devices for Loongarch machines, add CPU hot-(un)plug event response and address spaces, and update the ACPI table. Cc: "Bernhard Beschow" Cc: "Salil Mehta" Cc: "Salil Mehta" Cc: Xiaojuan Yang Cc: Song Gao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Cc: Ani Sinha Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Philippe Mathieu-Daudé" Cc: Yanan Wang Cc: "Daniel P. Berrangé" Cc: Peter Xu Cc: David Hildenbrand Cc: Bibo Mao Signed-off-by: xianglai li --- hw/acpi/acpi-cpu-hotplug-stub.c | 9 +++++++++ hw/loongarch/acpi-build.c | 34 ++++++++++++++++++++++++++++++++- hw/loongarch/virt.c | 3 ++- include/hw/loongarch/virt.h | 1 + 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c index 2aec90d968..b3ac7a1e31 100644 --- a/hw/acpi/acpi-cpu-hotplug-stub.c +++ b/hw/acpi/acpi-cpu-hotplug-stub.c @@ -19,6 +19,15 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, return; } +void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, + build_madt_cpu_fn build_madt_cpu, hwaddr mmap_io_base, + const char *res_root, + const char *event_handler_method, + AmlRegionSpace rs) +{ + return; +} + void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list) { return; diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index ae292fc543..cf89e5c1cb 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -46,6 +46,23 @@ #define ACPI_BUILD_DPRINTF(fmt, ...) #endif +static void virt_madt_cpu_entry(int uid, + const CPUArchIdList *apic_ids, + GArray *entry, bool force_enabled) +{ + uint32_t apic_id = apic_ids->cpus[uid].arch_id; + /* Flags – Local APIC Flags */ + uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ? + 1 /* Enabled */ : 0; + + /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */ + build_append_int_noprefix(entry, 0, 1); /* Type */ + build_append_int_noprefix(entry, 8, 1); /* Length */ + build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */ + build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */ + build_append_int_noprefix(entry, flags, 4); /* Flags */ +} + /* build FADT */ static void init_common_fadt_data(AcpiFadtData *data) { @@ -121,15 +138,18 @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ for (i = 0; i < arch_ids->len; i++) { + uint32_t flags; + /* Processor Core Interrupt Controller Structure */ arch_id = arch_ids->cpus[i].arch_id; + flags = arch_ids->cpus[i].cpu ? 1 : 0; build_append_int_noprefix(table_data, 17, 1); /* Type */ build_append_int_noprefix(table_data, 15, 1); /* Length */ build_append_int_noprefix(table_data, 1, 1); /* Version */ build_append_int_noprefix(table_data, i, 4); /* ACPI Processor ID */ build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */ - build_append_int_noprefix(table_data, 1, 4); /* Flags */ + build_append_int_noprefix(table_data, flags, 4); /* Flags */ } /* Extend I/O Interrupt Controller Structure */ @@ -292,6 +312,18 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine) AML_SYSTEM_MEMORY, VIRT_GED_MEM_ADDR); } + + if (event & ACPI_GED_CPU_HOTPLUG_EVT) { + CPUHotplugFeatures opts = { + .acpi_1_compatible = false, + .has_legacy_cphp = false + }; + + build_cpus_aml(dsdt, machine, opts, virt_madt_cpu_entry, + VIRT_GED_CPUHP_ADDR, "\\_SB", "\\_GPE._E01", + AML_SYSTEM_MEMORY); + + } acpi_dsdt_add_power_button(dsdt); } diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index c704f3117f..22b287eb39 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -449,7 +449,7 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState { DeviceState *dev; MachineState *ms = MACHINE(lams); - uint32_t event = ACPI_GED_PWR_DOWN_EVT; + uint32_t event = ACPI_GED_PWR_DOWN_EVT | ACPI_GED_CPU_HOTPLUG_EVT; if (ms->ram_slots) { event |= ACPI_GED_MEM_HOTPLUG_EVT; @@ -463,6 +463,7 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, VIRT_GED_MEM_ADDR); /* ged regs used for reset and power down */ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, VIRT_GED_CPUHP_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - VIRT_GSI_BASE)); diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 176dc43a93..e23a45f9bb 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -31,6 +31,7 @@ #define VIRT_GED_EVT_ADDR 0x100e0000 #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) +#define VIRT_GED_CPUHP_ADDR (VIRT_GED_REG_ADDR + ACPI_CPU_HOTPLUG_REG_LEN) struct LoongArchMachineState { /*< private >*/