From patchwork Mon Jun 20 08:04:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887117 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 6EED1C43334 for ; Mon, 20 Jun 2022 08:21:11 +0000 (UTC) Received: from localhost ([::1]:50672 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3Cek-0004KV-9t for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:21:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60748) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPU-0006f4-0F for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47762 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPI-0007Jl-OU for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:18 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S3; Mon, 20 Jun 2022 16:04:51 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 1/8] hw/loongarch: Add default bios startup support Date: Mon, 20 Jun 2022 16:04:44 +0800 Message-Id: <20220620080451.3711049-2-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S3 X-Coremail-Antispam: 1UD129KBjvJXoW3Gr1kJr17XFy7tr1xWr18uFg_yoWxuFWkpF y3AF4kGr4kJr43Grs7G34UWr15Jw4vkFy7W3W7Cr4FkFy7Jr1UZw4v939IyFyUA3yDZa4Y qFn5trWF9Fn5J3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- hw/loongarch/fw_cfg.c | 33 +++++++++++++++ hw/loongarch/fw_cfg.h | 15 +++++++ hw/loongarch/loongson3.c | 81 ++++++++++++++++++++++++++++++++++++- include/hw/loongarch/virt.h | 7 ++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 hw/loongarch/fw_cfg.c create mode 100644 hw/loongarch/fw_cfg.h diff --git a/hw/loongarch/fw_cfg.c b/hw/loongarch/fw_cfg.c new file mode 100644 index 0000000000..a641f603b6 --- /dev/null +++ b/hw/loongarch/fw_cfg.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU fw_cfg helpers (LoongArch specific) + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "hw/loongarch/fw_cfg.h" +#include "hw/loongarch/virt.h" +#include "hw/nvram/fw_cfg.h" +#include "sysemu/sysemu.h" + +static void fw_cfg_boot_set(void *opaque, const char *boot_device, + Error **errp) +{ + fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); +} + +FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms) +{ + FWCfgState *fw_cfg; + int max_cpus = ms->smp.max_cpus; + int smp_cpus = ms->smp.cpus; + + fw_cfg = fw_cfg_init_mem_wide(FW_CFG_ADDR + 8, FW_CFG_ADDR, 8, 0, NULL); + fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); + fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); + + qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); + return fw_cfg; +} diff --git a/hw/loongarch/fw_cfg.h b/hw/loongarch/fw_cfg.h new file mode 100644 index 0000000000..7c0de4db4a --- /dev/null +++ b/hw/loongarch/fw_cfg.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU fw_cfg helpers (LoongArch specific) + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#ifndef HW_LOONGARCH_FW_CFG_H +#define HW_LOONGARCH_FW_CFG_H + +#include "hw/boards.h" +#include "hw/nvram/fw_cfg.h" + +FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms); +#endif diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index bd20ebbb78..1e2c69dd8e 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -28,13 +28,46 @@ #include "hw/pci-host/ls7a.h" #include "hw/pci-host/gpex.h" #include "hw/misc/unimp.h" - +#include "hw/loongarch/fw_cfg.h" #include "target/loongarch/cpu.h" #define PM_BASE 0x10080000 #define PM_SIZE 0x100 #define PM_CTRL 0x10 +struct la_memmap_entry { + uint64_t address; + uint64_t length; + uint32_t type; + uint32_t reserved; +}; + +static struct la_memmap_entry *la_memmap_table; +static unsigned la_memmap_entries; + +static int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) +{ + int i; + + for (i = 0; i < la_memmap_entries; i++) { + if (la_memmap_table[i].address == address) { + fprintf(stderr, "%s address:0x%lx length:0x%lx already exists\n", + __func__, address, length); + return 0; + } + } + + la_memmap_table = g_renew(struct la_memmap_entry, la_memmap_table, + la_memmap_entries + 1); + la_memmap_table[la_memmap_entries].address = cpu_to_le64(address); + la_memmap_table[la_memmap_entries].length = cpu_to_le64(length); + la_memmap_table[la_memmap_entries].type = cpu_to_le32(type); + la_memmap_entries++; + + return la_memmap_entries; +} + + /* * This is a placeholder for missing ACPI, * and will eventually be replaced. @@ -279,6 +312,38 @@ static void loongarch_irq_init(LoongArchMachineState *lams) loongarch_devices_init(pch_pic); } +static bool loongarch_firmware_init(LoongArchMachineState *lams) +{ + char *filename = MACHINE(lams)->firmware; + char *bios_name = NULL; + bool loaded = false; + int bios_size; + + if (filename) { + bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename); + if (!bios_name) { + error_report("Could not find ROM image '%s'", filename); + exit(1); + } + + bios_size = load_image_targphys(bios_name, LA_BIOS_BASE, LA_BIOS_SIZE); + if (bios_size < 0) { + error_report("Could not load ROM image '%s'", bios_name); + exit(1); + } + + g_free(bios_name); + + memory_region_init_ram(&lams->bios, NULL, "loongarch.bios", + LA_BIOS_SIZE, &error_fatal); + memory_region_set_readonly(&lams->bios, true); + memory_region_add_subregion(get_system_memory(), LA_BIOS_BASE, &lams->bios); + loaded = true; + } + + return loaded; +} + static void reset_load_elf(void *opaque) { LoongArchCPU *cpu = opaque; @@ -301,6 +366,7 @@ static void loongarch_init(MachineState *machine) LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); LoongArchCPU *lacpu; int i; + bool firmware_loaded; int64_t kernel_addr = 0; if (!cpu_model) { @@ -327,15 +393,28 @@ static void loongarch_init(MachineState *machine) machine->ram, 0, 256 * MiB); memory_region_add_subregion(address_space_mem, offset, &lams->lowmem); offset += 256 * MiB; + la_memmap_add_entry(0, 256 * MiB, 1); highram_size = ram_size - 256 * MiB; memory_region_init_alias(&lams->highmem, NULL, "loongarch.highmem", machine->ram, offset, highram_size); memory_region_add_subregion(address_space_mem, 0x90000000, &lams->highmem); + la_memmap_add_entry(0x90000000, highram_size, 1); /* Add isa io region */ memory_region_init_alias(&lams->isa_io, NULL, "isa-io", get_system_io(), 0, LOONGARCH_ISA_IO_SIZE); memory_region_add_subregion(address_space_mem, LOONGARCH_ISA_IO_BASE, &lams->isa_io); + /* load the BIOS image. */ + firmware_loaded = loongarch_firmware_init(lams); + lams->fw_cfg = loongarch_fw_cfg_init(ram_size, machine); + rom_set_fw(lams->fw_cfg); + + if (lams->fw_cfg != NULL) { + fw_cfg_add_file(lams->fw_cfg, "etc/memmap", + la_memmap_table, + sizeof(struct la_memmap_entry) * (la_memmap_entries)); + } + if (kernel_filename) { loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 09a816191c..448f46fc6b 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -17,6 +17,9 @@ #define LOONGARCH_ISA_IO_BASE 0x18000000UL #define LOONGARCH_ISA_IO_SIZE 0x0004000 +#define FW_CFG_ADDR 0x1e020000 +#define LA_BIOS_BASE 0x1c000000 +#define LA_BIOS_SIZE (4 * MiB) struct LoongArchMachineState { /*< private >*/ @@ -26,6 +29,10 @@ struct LoongArchMachineState { MemoryRegion lowmem; MemoryRegion highmem; MemoryRegion isa_io; + MemoryRegion bios; + + /* State for other subsystems/APIs: */ + FWCfgState *fw_cfg; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") From patchwork Mon Jun 20 08:04:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887116 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 896BDC433EF for ; Mon, 20 Jun 2022 08:20:33 +0000 (UTC) Received: from localhost ([::1]:49744 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3Ce6-0003Ye-Jc for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:20:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60740) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPT-0006f3-V8 for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47774 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPI-0007Jq-OL for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:16 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S4; Mon, 20 Jun 2022 16:04:52 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 2/8] hw/loongarch: Add -kernel and -initrd options support Date: Mon, 20 Jun 2022 16:04:45 +0800 Message-Id: <20220620080451.3711049-3-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S4 X-Coremail-Antispam: 1UD129KBjvJXoW3JryUAF13Jr4kWFyDWry5CFg_yoW7Wr4xpF ZxWF1rtrs5AFySyw13try5ury3urWkGay3W3W7Cr4Syan8Wr1Dur18Ww4avFyj9a95W3WY qFZ0qryag3WDJrJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- hw/loongarch/loongson3.c | 125 ++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 15 deletions(-) diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index 1e2c69dd8e..638280c4e7 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -109,6 +109,8 @@ static const MemoryRegionOps loongarch_virt_pm_ops = { static struct _loaderparams { uint64_t ram_size; const char *kernel_filename; + const char *kernel_cmdline; + const char *initrd_filename; } loaderparams; static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) @@ -355,19 +357,114 @@ static void reset_load_elf(void *opaque) } } +/** + * load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified + * by key. + * @fw_cfg: The firmware config instance to store the data in. + * @size_key: The firmware config key to store the size of the loaded + * data under, with fw_cfg_add_i32(). + * @data_key: The firmware config key to store the loaded data under, + * with fw_cfg_add_bytes(). + * @image_name: The name of the image file to load. If it is NULL, the + * function returns without doing anything. + * @try_decompress: Whether the image should be decompressed (gunzipped) before + * adding it to fw_cfg. If decompression fails, the image is + * loaded as-is. + * + * In case of failure, the function prints an error message to stderr and the + * process exits with status 1. + */ +static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key, + uint16_t data_key, const char *image_name, + bool try_decompress) +{ + size_t size = -1; + uint8_t *data; + + if (image_name == NULL) { + return; + } + + if (try_decompress) { + size = load_image_gzipped_buffer(image_name, + LOAD_IMAGE_MAX_GUNZIP_BYTES, &data); + } + + if (size == (size_t)-1) { + gchar *contents; + gsize length; + + if (!g_file_get_contents(image_name, &contents, &length, NULL)) { + error_report("failed to load \"%s\"", image_name); + exit(1); + } + size = length; + data = (uint8_t *)contents; + } + + fw_cfg_add_i32(fw_cfg, size_key, size); + fw_cfg_add_bytes(fw_cfg, data_key, data, size); +} + +static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg) +{ + /* + * Expose the kernel, the command line, and the initrd in fw_cfg. + * We don't process them here at all, it's all left to the + * firmware. + */ + load_image_to_fw_cfg(fw_cfg, + FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA, + loaderparams.kernel_filename, + false); + + if (loaderparams.initrd_filename) { + load_image_to_fw_cfg(fw_cfg, + FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA, + loaderparams.initrd_filename, false); + } + + if (loaderparams.kernel_cmdline) { + fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, + strlen(loaderparams.kernel_cmdline) + 1); + fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, + loaderparams.kernel_cmdline); + } +} + +static void loongarch_firmware_boot(LoongArchMachineState *lams, bool firmware_loaded) +{ + fw_cfg_add_kernel_info(lams->fw_cfg); +} + +static void loongarch_direct_kernel_boot(LoongArchMachineState *lams) +{ + MachineState *machine = MACHINE(lams); + int64_t kernel_addr = 0; + LoongArchCPU *lacpu; + int i; + + kernel_addr = load_kernel_info(); + if (!machine->firmware) { + for (i = 0; i < machine->smp.cpus; i++) { + lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); + lacpu->env.load_elf = true; + lacpu->env.elf_address = kernel_addr; + qemu_register_reset(reset_load_elf, lacpu); + } + } +} + static void loongarch_init(MachineState *machine) { const char *cpu_model = machine->cpu_type; - const char *kernel_filename = machine->kernel_filename; ram_addr_t offset = 0; ram_addr_t ram_size = machine->ram_size; uint64_t highram_size = 0; MemoryRegion *address_space_mem = get_system_memory(); LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); - LoongArchCPU *lacpu; int i; bool firmware_loaded; - int64_t kernel_addr = 0; if (!cpu_model) { cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); @@ -414,18 +511,16 @@ static void loongarch_init(MachineState *machine) la_memmap_table, sizeof(struct la_memmap_entry) * (la_memmap_entries)); } - - if (kernel_filename) { - loaderparams.ram_size = ram_size; - loaderparams.kernel_filename = kernel_filename; - kernel_addr = load_kernel_info(); - if (!machine->firmware) { - for (i = 0; i < machine->smp.cpus; i++) { - lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); - lacpu->env.load_elf = true; - lacpu->env.elf_address = kernel_addr; - qemu_register_reset(reset_load_elf, lacpu); - } + loaderparams.ram_size = ram_size; + loaderparams.kernel_filename = machine->kernel_filename; + loaderparams.kernel_cmdline = machine->kernel_cmdline; + loaderparams.initrd_filename = machine->initrd_filename; + /* Load the kernel. */ + if (loaderparams.kernel_filename) { + if (firmware_loaded) { + loongarch_firmware_boot(lams, firmware_loaded); + } else { + loongarch_direct_kernel_boot(lams); } } /* Initialize the IO interrupt subsystem */ From patchwork Mon Jun 20 08:04:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887088 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 9DFE9C433EF for ; Mon, 20 Jun 2022 08:10:00 +0000 (UTC) Received: from localhost ([::1]:33940 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CTv-00018l-FL for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:09:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60730) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPT-0006ey-Um for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:23 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47766 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPI-0007Jo-S1 for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:17 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S5; Mon, 20 Jun 2022 16:04:52 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 3/8] hw/loongarch: Add LoongArch smbios support Date: Mon, 20 Jun 2022 16:04:46 +0800 Message-Id: <20220620080451.3711049-4-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S5 X-Coremail-Antispam: 1UD129KBjvJXoWxGry8GFy7ZF4kXr15Jw1rtFb_yoW5Ww48pF y3CFn5Cr4rXrn3KrZxt343uF15Xrs3Kr12qF4Ivw40kFZxAr1UXF48C34qyFyDJ3ykGa4U XFn5K3W3Wa1UX3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- hw/loongarch/Kconfig | 1 + hw/loongarch/loongson3.c | 38 +++++++++++++++++++++++++++++++++++++ include/hw/loongarch/virt.h | 1 + 3 files changed, 40 insertions(+) diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 35b6680772..610552e522 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -14,3 +14,4 @@ config LOONGARCH_VIRT select LOONGARCH_PCH_MSI select LOONGARCH_EXTIOI select LS7A_RTC + select SMBIOS diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index 638280c4e7..b638d02eb5 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -30,11 +30,47 @@ #include "hw/misc/unimp.h" #include "hw/loongarch/fw_cfg.h" #include "target/loongarch/cpu.h" +#include "hw/misc/unimp.h" +#include "hw/loongarch/fw_cfg.h" +#include "hw/firmware/smbios.h" #define PM_BASE 0x10080000 #define PM_SIZE 0x100 #define PM_CTRL 0x10 +static void virt_build_smbios(LoongArchMachineState *lams) +{ + MachineState *ms = MACHINE(lams); + MachineClass *mc = MACHINE_GET_CLASS(lams); + uint8_t *smbios_tables, *smbios_anchor; + size_t smbios_tables_len, smbios_anchor_len; + const char *product = "QEMU Virtual Machine"; + + if (!lams->fw_cfg) { + return; + } + + smbios_set_defaults("QEMU", product, mc->name, false, + true, SMBIOS_ENTRY_POINT_TYPE_64); + + smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, + &smbios_anchor, &smbios_anchor_len, &error_fatal); + + if (smbios_anchor) { + fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-tables", + smbios_tables, smbios_tables_len); + fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-anchor", + smbios_anchor, smbios_anchor_len); + } +} + +static void virt_machine_done(Notifier *notifier, void *data) +{ + LoongArchMachineState *lams = container_of(notifier, + LoongArchMachineState, machine_done); + virt_build_smbios(lams); +} + struct la_memmap_entry { uint64_t address; uint64_t length; @@ -525,6 +561,8 @@ static void loongarch_init(MachineState *machine) } /* Initialize the IO interrupt subsystem */ loongarch_irq_init(lams); + lams->machine_done.notify = virt_machine_done; + qemu_add_machine_init_done_notifier(&lams->machine_done); } static void loongarch_class_init(ObjectClass *oc, void *data) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 448f46fc6b..55bc2fe4e9 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -33,6 +33,7 @@ struct LoongArchMachineState { /* State for other subsystems/APIs: */ FWCfgState *fw_cfg; + Notifier machine_done; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") From patchwork Mon Jun 20 08:04:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887094 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 BB38AC433EF for ; Mon, 20 Jun 2022 08:15:51 +0000 (UTC) Received: from localhost ([::1]:45288 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CZa-0000Qj-MM for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:15:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60766) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPU-0006fE-KR for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47772 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPK-0007Jp-DD for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:23 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S6; Mon, 20 Jun 2022 16:04:53 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 4/8] hw/loongarch: Add LoongArch acpi support Date: Mon, 20 Jun 2022 16:04:47 +0800 Message-Id: <20220620080451.3711049-5-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S6 X-Coremail-Antispam: 1UD129KBjvAXoWfCw1xAw4UArW7Ww1DGFW5trb_yoW5WFy3to Z3JFWrW3W8Xryj9rZYkrn0q3y7Wr18KF4Dtr93GF4kKa1fAw4UGryfKws5uw12y3Z0k347 XrWrKwn3ArZ7CF18n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- hw/loongarch/Kconfig | 2 + hw/loongarch/acpi-build.c | 620 ++++++++++++++++++++++++++++++++++++ hw/loongarch/loongson3.c | 78 ++++- hw/loongarch/meson.build | 4 + include/hw/loongarch/virt.h | 13 + include/hw/pci-host/ls7a.h | 5 + 6 files changed, 719 insertions(+), 3 deletions(-) create mode 100644 hw/loongarch/acpi-build.c diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 610552e522..a99aa387c3 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -15,3 +15,5 @@ config LOONGARCH_VIRT select LOONGARCH_EXTIOI select LS7A_RTC select SMBIOS + select ACPI_PCI + select ACPI_HW_REDUCED diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c new file mode 100644 index 0000000000..008f661d7b --- /dev/null +++ b/hw/loongarch/acpi-build.c @@ -0,0 +1,620 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Support for generating ACPI tables and passing them to Guests + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/bitmap.h" +#include "hw/pci/pci.h" +#include "hw/core/cpu.h" +#include "target/loongarch/cpu.h" +#include "hw/acpi/acpi-defs.h" +#include "hw/acpi/acpi.h" +#include "hw/nvram/fw_cfg.h" +#include "hw/acpi/bios-linker-loader.h" +#include "migration/vmstate.h" +#include "hw/mem/memory-device.h" +#include "sysemu/reset.h" + +/* Supported chipsets: */ +#include "hw/pci-host/ls7a.h" +#include "hw/loongarch/virt.h" +#include "hw/acpi/aml-build.h" + +#include "hw/acpi/utils.h" +#include "hw/acpi/pci.h" + +#include "qom/qom-qobject.h" + +#include "hw/acpi/generic_event_device.h" + +#define ACPI_BUILD_ALIGN_SIZE 0x1000 +#define ACPI_BUILD_TABLE_SIZE 0x20000 + +#ifdef DEBUG_ACPI_BUILD +#define ACPI_BUILD_DPRINTF(fmt, ...) \ + do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0) +#else +#define ACPI_BUILD_DPRINTF(fmt, ...) +#endif + +static void init_common_fadt_data(AcpiFadtData *data) +{ + AcpiFadtData fadt = { + /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */ + .rev = 5, + .flags = ((1 << ACPI_FADT_F_HW_REDUCED_ACPI) | + (1 << ACPI_FADT_F_RESET_REG_SUP)), + + /* ACPI 5.0: 4.8.3.7 Sleep Control and Status Registers */ + .sleep_ctl = { + .space_id = AML_AS_SYSTEM_MEMORY, + .bit_width = 8, + .address = GED_REG_ADDR + ACPI_GED_REG_SLEEP_CTL, + }, + .sleep_sts = { + .space_id = AML_AS_SYSTEM_MEMORY, + .bit_width = 8, + .address = GED_REG_ADDR + ACPI_GED_REG_SLEEP_STS, + }, + + /* ACPI 5.0: 4.8.3.6 Reset Register */ + .reset_reg = { + .space_id = AML_AS_SYSTEM_MEMORY, + .bit_width = 8, + .address = GED_REG_ADDR + ACPI_GED_REG_RESET, + }, + .reset_val = ACPI_GED_RESET_VALUE, + }; + *data = fadt; +} + +static void acpi_align_size(GArray *blob, unsigned align) +{ + /* + * Align size to multiple of given size. This reduces the chance + * we need to change size in the future (breaking cross version migration). + */ + g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); +} + +/* + * Loongson CPU firmware and kernel interface specification V3.1. + * chapter 8.7 Firmware ACPI Control Structure + */ +static void +build_facs(GArray *table_data) +{ + const char *sig = "FACS"; + const uint8_t reserved[40] = {}; + + g_array_append_vals(table_data, sig, 4); /* Signature */ + build_append_int_noprefix(table_data, 64, 4); /* Length */ + build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */ + build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */ + build_append_int_noprefix(table_data, 0, 4); /* Global Lock */ + build_append_int_noprefix(table_data, 0, 4); /* Flags */ + g_array_append_vals(table_data, reserved, 40); /* Reserved */ +} + +/* + * Loongson CPU firmware and kernel interface specification V3.1. + * chapter 8.3 Multiple APIC Description Table + */ +static void +build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) +{ + MachineState *ms = MACHINE(lams); + int i; + AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id, + .oem_table_id = lams->oem_table_id }; + + acpi_table_begin(&table, table_data); + + /* Local APIC Address */ + build_append_int_noprefix(table_data, 0, 4); + build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ + + for (i = 0; i < ms->smp.cpus; i++) { + /* Processor Core Interrupt Controller Structure */ + 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 + 1, 4); /* ACPI Processor ID */ + build_append_int_noprefix(table_data, i, 4); /* Core ID */ + build_append_int_noprefix(table_data, 1, 4); /* Flags */ + } + + /* Extend I/O Interrupt Controller Structure */ + build_append_int_noprefix(table_data, 20, 1); /* Type */ + build_append_int_noprefix(table_data, 13, 1); /* Length */ + build_append_int_noprefix(table_data, 1, 1); /* Version */ + build_append_int_noprefix(table_data, 3, 1); /* Cascade */ + build_append_int_noprefix(table_data, 0, 1); /* Node */ + build_append_int_noprefix(table_data, 0xffff, 8); /* Node map */ + + /* MSI Interrupt Controller Structure */ + build_append_int_noprefix(table_data, 21, 1); /* Type */ + build_append_int_noprefix(table_data, 19, 1); /* Length */ + build_append_int_noprefix(table_data, 1, 1); /* Version */ + build_append_int_noprefix(table_data, LS7A_PCH_MSI_ADDR_LOW, 8);/* Address */ + build_append_int_noprefix(table_data, 0x40, 4); /* Start */ + build_append_int_noprefix(table_data, 0xc0, 4); /* Count */ + + /* Bridge I/O Interrupt Controller Structure */ + build_append_int_noprefix(table_data, 22, 1); /* Type */ + build_append_int_noprefix(table_data, 17, 1); /* Length */ + build_append_int_noprefix(table_data, 1, 1); /* Version */ + build_append_int_noprefix(table_data, LS7A_PCH_REG_BASE, 8);/* Address */ + build_append_int_noprefix(table_data, 0x1000, 2); /* Size */ + build_append_int_noprefix(table_data, 0, 2); /* Id */ + build_append_int_noprefix(table_data, 0x40, 2); /* Base */ + + acpi_table_end(linker, &table); +} + +/* + * Loongson CPU firmware and kernel interface specification V3.1. + * chapter 8.4 System Resource Affinity Table + */ +static void +build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) +{ + uint64_t i; + LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + MachineState *ms = MACHINE(lams); + AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id, + .oem_table_id = lams->oem_table_id }; + + acpi_table_begin(&table, table_data); + build_append_int_noprefix(table_data, 1, 4); /* Reserved */ + build_append_int_noprefix(table_data, 0, 8); /* Reserved */ + + for (i = 0; i < ms->smp.cpus; ++i) { + /* Processor Local APIC/SAPIC Affinity Structure */ + build_append_int_noprefix(table_data, 0, 1); /* Type */ + build_append_int_noprefix(table_data, 16, 1); /* Length */ + /* Proximity Domain [7:0] */ + build_append_int_noprefix(table_data, 0, 1); + build_append_int_noprefix(table_data, i, 1); /* APIC ID */ + /* Flags, Table 5-36 */ + build_append_int_noprefix(table_data, 1, 4); + build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */ + /* Proximity Domain [31:8] */ + build_append_int_noprefix(table_data, 0, 3); + build_append_int_noprefix(table_data, 0, 4); /* Reserved */ + } + + build_srat_memory(table_data, LOW_MEM_BASE, LOW_MEM_SIZE, + 0, MEM_AFFINITY_ENABLED); + + build_srat_memory(table_data, HIGH_MEM_BASE, machine->ram_size - LOW_MEM_SIZE, + 0, MEM_AFFINITY_ENABLED); + + acpi_table_end(linker, &table); +} + +typedef +struct AcpiBuildState { + /* Copy of table in RAM (for patching). */ + MemoryRegion *table_mr; + /* Is table patched? */ + uint8_t patched; + void *rsdp; + MemoryRegion *rsdp_mr; + MemoryRegion *linker_mr; +} AcpiBuildState; + +static void build_gpex_pci0_int(Aml *table) +{ + Aml *sb_scope = aml_scope("_SB"); + Aml *pci0_scope = aml_scope("PCI0"); + Aml *prt_pkg = aml_varpackage(128); + int slot, pin; + + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + for (pin = 0; pin < PCI_NUM_PINS; pin++) { + Aml *pkg = aml_package(4); + aml_append(pkg, aml_int((slot << 16) | 0xFFFF)); + aml_append(pkg, aml_int(pin)); + aml_append(pkg, aml_int(0)); + aml_append(pkg, aml_int(80 + (slot + pin) % 4)); + aml_append(prt_pkg, pkg); + } + } + aml_append(pci0_scope, aml_name_decl("_PRT", prt_pkg)); + aml_append(sb_scope, pci0_scope); + aml_append(table, sb_scope); +} + +static void build_dbg_aml(Aml *table) +{ + Aml *field; + Aml *method; + Aml *while_ctx; + Aml *scope = aml_scope("\\"); + Aml *buf = aml_local(0); + Aml *len = aml_local(1); + Aml *idx = aml_local(2); + + aml_append(scope, + aml_operation_region("DBG", AML_SYSTEM_IO, aml_int(0x0402), 0x01)); + field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); + aml_append(field, aml_named_field("DBGB", 8)); + aml_append(scope, field); + + method = aml_method("DBUG", 1, AML_NOTSERIALIZED); + + aml_append(method, aml_to_hexstring(aml_arg(0), buf)); + aml_append(method, aml_to_buffer(buf, buf)); + aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len)); + aml_append(method, aml_store(aml_int(0), idx)); + + while_ctx = aml_while(aml_lless(idx, len)); + aml_append(while_ctx, + aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB"))); + aml_append(while_ctx, aml_increment(idx)); + aml_append(method, while_ctx); + aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB"))); + aml_append(scope, method); + aml_append(table, scope); +} + +static Aml *build_ls7a_osc_method(void) +{ + Aml *if_ctx; + Aml *if_ctx2; + Aml *else_ctx; + Aml *method; + Aml *a_cwd1 = aml_name("CDW1"); + Aml *a_ctrl = aml_local(0); + + method = aml_method("_OSC", 4, AML_NOTSERIALIZED); + aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); + + if_ctx = aml_if(aml_equal( + aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"))); + aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); + aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); + aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl)); + + /* + * Always allow native PME, AER (no dependencies) + * Allow SHPC (PCI bridges can have SHPC controller) + */ + aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); + + if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); + /* Unknown revision */ + aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1)); + aml_append(if_ctx, if_ctx2); + + if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); + /* Capabilities bits were masked */ + aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1)); + aml_append(if_ctx, if_ctx2); + + /* Update DWORD3 in the buffer */ + aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3"))); + aml_append(method, if_ctx); + + else_ctx = aml_else(); + /* Unrecognized UUID */ + aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1)); + aml_append(method, else_ctx); + + aml_append(method, aml_return(aml_arg(3))); + return method; +} + +static void build_ls7a_uart_device_aml(Aml *table) +{ + Aml *dev; + Aml *crs; + Aml *pkg0, *pkg1, *pkg2; + uint32_t uart_irq = LS7A_UART_IRQ; + + Aml *scope = aml_scope("_SB"); + dev = aml_device("COMA"); + aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); + crs = aml_resource_template(); + aml_append(crs, + aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, + AML_NON_CACHEABLE, AML_READ_WRITE, + 0, 0x1FE001E0, 0x1FE001E7, 0, 0x8)); + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_SHARED, &uart_irq, 1)); + aml_append(dev, aml_name_decl("_CRS", crs)); + pkg0 = aml_package(0x2); + aml_append(pkg0, aml_int(0x05F5E100)); + aml_append(pkg0, aml_string("clock-frenquency")); + pkg1 = aml_package(0x1); + aml_append(pkg1, pkg0); + pkg2 = aml_package(0x2); + aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); + aml_append(pkg2, pkg1); + aml_append(dev, aml_name_decl("_DSD", pkg2)); + aml_append(scope, dev); + aml_append(table, scope); +} + +/* + * Loongson CPU firmware and kernel interface specification V3.1. + * chapter 8.6 Differentiated System Description Table + */ +static void +build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) +{ + Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg; + int root_bus_limit = 0x7F; + LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id, + .oem_table_id = lams->oem_table_id }; + + acpi_table_begin(&table, table_data); + + dsdt = init_aml_allocator(); + + build_dbg_aml(dsdt); + + sb_scope = aml_scope("_SB"); + dev = aml_device("PCI0"); + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); + aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); + aml_append(dev, aml_name_decl("_ADR", aml_int(0))); + aml_append(dev, aml_name_decl("_BBN", aml_int(0))); + aml_append(dev, aml_name_decl("_UID", aml_int(1))); + aml_append(dev, build_ls7a_osc_method()); + aml_append(sb_scope, dev); + aml_append(dsdt, sb_scope); + + build_gpex_pci0_int(dsdt); + build_ls7a_uart_device_aml(dsdt); + if (lams->acpi_ged) { + build_ged_aml(dsdt, "\\_SB."GED_DEVICE, + HOTPLUG_HANDLER(lams->acpi_ged), + LS7A_SCI_IRQ - PCH_PIC_IRQ_OFFSET, AML_SYSTEM_MEMORY, + GED_EVT_ADDR); + } + + scope = aml_scope("\\_SB.PCI0"); + /* Build PCI0._CRS */ + crs = aml_resource_template(); + aml_append(crs, + aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, + 0x0000, 0x0, root_bus_limit, + 0x0000, root_bus_limit + 1)); + aml_append(crs, + aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, + AML_POS_DECODE, AML_ENTIRE_RANGE, + 0x0000, 0x0000, 0xFFFF, 0x18000000, 0x10000)); + aml_append(crs, + aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, + AML_CACHEABLE, AML_READ_WRITE, + 0, LS7A_PCI_MEM_BASE, + LS7A_PCI_MEM_BASE + LS7A_PCI_MEM_SIZE - 1, + 0, LS7A_PCI_MEM_BASE)); + aml_append(scope, aml_name_decl("_CRS", crs)); + aml_append(dsdt, scope); + + /* System State Package */ + scope = aml_scope("\\"); + pkg = aml_package(4); + aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5)); + aml_append(pkg, aml_int(0)); /* ignored */ + aml_append(pkg, aml_int(0)); /* reserved */ + aml_append(pkg, aml_int(0)); /* reserved */ + aml_append(scope, aml_name_decl("_S5", pkg)); + aml_append(dsdt, scope); + /* Copy AML table into ACPI tables blob and patch header there */ + g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); + acpi_table_end(linker, &table); + free_aml_allocator(); +} + +static void acpi_build(AcpiBuildTables *tables, MachineState *machine) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + GArray *table_offsets; + AcpiFadtData fadt_data; + unsigned facs, rsdt, fadt, dsdt; + uint8_t *u; + size_t aml_len = 0; + GArray *tables_blob = tables->table_data; + + init_common_fadt_data(&fadt_data); + + table_offsets = g_array_new(false, true, sizeof(uint32_t)); + ACPI_BUILD_DPRINTF("init ACPI tables\n"); + + bios_linker_loader_alloc(tables->linker, + ACPI_BUILD_TABLE_FILE, tables_blob, + 64, false); + + /* + * FACS is pointed to by FADT. + * We place it first since it's the only table that has alignment + * requirements. + */ + facs = tables_blob->len; + build_facs(tables_blob); + + /* DSDT is pointed to by FADT */ + dsdt = tables_blob->len; + build_dsdt(tables_blob, tables->linker, machine); + + /* + * Count the size of the DSDT, we will need it for + * legacy sizing of ACPI tables. + */ + aml_len += tables_blob->len - dsdt; + + /* ACPI tables pointed to by RSDT */ + fadt = tables_blob->len; + acpi_add_table(table_offsets, tables_blob); + fadt_data.facs_tbl_offset = &facs; + fadt_data.dsdt_tbl_offset = &dsdt; + fadt_data.xdsdt_tbl_offset = &dsdt; + build_fadt(tables_blob, tables->linker, &fadt_data, + lams->oem_id, lams->oem_table_id); + aml_len += tables_blob->len - fadt; + + acpi_add_table(table_offsets, tables_blob); + build_madt(tables_blob, tables->linker, lams); + + acpi_add_table(table_offsets, tables_blob); + build_srat(tables_blob, tables->linker, machine); + + acpi_add_table(table_offsets, tables_blob); + { + AcpiMcfgInfo mcfg = { + .base = cpu_to_le64(LS_PCIECFG_BASE), + .size = cpu_to_le64(LS_PCIECFG_SIZE), + }; + build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id, + lams->oem_table_id); + } + + /* Add tables supplied by user (if any) */ + for (u = acpi_table_first(); u; u = acpi_table_next(u)) { + unsigned len = acpi_table_len(u); + + acpi_add_table(table_offsets, tables_blob); + g_array_append_vals(tables_blob, u, len); + } + + /* RSDT is pointed to by RSDP */ + rsdt = tables_blob->len; + build_rsdt(tables_blob, tables->linker, table_offsets, + lams->oem_id, lams->oem_table_id); + + /* RSDP is in FSEG memory, so allocate it separately */ + { + AcpiRsdpData rsdp_data = { + .revision = 0, + .oem_id = lams->oem_id, + .xsdt_tbl_offset = NULL, + .rsdt_tbl_offset = &rsdt, + }; + build_rsdp(tables->rsdp, tables->linker, &rsdp_data); + } + + /* + * The align size is 128, warn if 64k is not enough therefore + * the align size could be resized. + */ + if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) { + warn_report("ACPI table size %u exceeds %d bytes," + " migration may not work", + tables_blob->len, ACPI_BUILD_TABLE_SIZE / 2); + error_printf("Try removing CPUs, NUMA nodes, memory slots" + " or PCI bridges."); + } + + acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); + + /* Cleanup memory that's no longer used. */ + g_array_free(table_offsets, true); +} + +static void acpi_ram_update(MemoryRegion *mr, GArray *data) +{ + uint32_t size = acpi_data_len(data); + + /* + * Make sure RAM size is correct - in case it got changed + * e.g. by migration + */ + memory_region_ram_resize(mr, size, &error_abort); + + memcpy(memory_region_get_ram_ptr(mr), data->data, size); + memory_region_set_dirty(mr, 0, size); +} + +static void acpi_build_update(void *build_opaque) +{ + AcpiBuildState *build_state = build_opaque; + AcpiBuildTables tables; + + /* No state to update or already patched? Nothing to do. */ + if (!build_state || build_state->patched) { + return; + } + build_state->patched = 1; + + acpi_build_tables_init(&tables); + + acpi_build(&tables, MACHINE(qdev_get_machine())); + + acpi_ram_update(build_state->table_mr, tables.table_data); + acpi_ram_update(build_state->rsdp_mr, tables.rsdp); + acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); + + acpi_build_tables_cleanup(&tables, true); +} + +static void acpi_build_reset(void *build_opaque) +{ + AcpiBuildState *build_state = build_opaque; + build_state->patched = 0; +} + +static const VMStateDescription vmstate_acpi_build = { + .name = "acpi_build", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(patched, AcpiBuildState), + VMSTATE_END_OF_LIST() + }, +}; + +void loongarch_acpi_setup(LoongArchMachineState *lams) +{ + AcpiBuildTables tables; + AcpiBuildState *build_state; + + if (!lams->fw_cfg) { + ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); + return; + } + + if (!loongarch_is_acpi_enabled(lams)) { + ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); + return; + } + + build_state = g_malloc0(sizeof *build_state); + + acpi_build_tables_init(&tables); + acpi_build(&tables, MACHINE(lams)); + + /* Now expose it all to Guest */ + build_state->table_mr = acpi_add_rom_blob(acpi_build_update, + build_state, tables.table_data, + ACPI_BUILD_TABLE_FILE); + assert(build_state->table_mr != NULL); + + build_state->linker_mr = + acpi_add_rom_blob(acpi_build_update, build_state, + tables.linker->cmd_blob, ACPI_BUILD_LOADER_FILE); + + build_state->rsdp_mr = acpi_add_rom_blob(acpi_build_update, + build_state, tables.rsdp, + ACPI_BUILD_RSDP_FILE); + + qemu_register_reset(acpi_build_reset, build_state); + acpi_build_reset(build_state); + vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); + + /* + * Cleanup tables but don't free the memory: we track it + * in build_state. + */ + acpi_build_tables_cleanup(&tables, false); +} diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index b638d02eb5..cc449a12ae 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -33,6 +33,10 @@ #include "hw/misc/unimp.h" #include "hw/loongarch/fw_cfg.h" #include "hw/firmware/smbios.h" +#include "hw/acpi/aml-build.h" +#include "qapi/qapi-visit-common.h" +#include "hw/acpi/generic_event_device.h" +#include "hw/mem/nvdimm.h" #define PM_BASE 0x10080000 #define PM_SIZE 0x100 @@ -69,6 +73,7 @@ static void virt_machine_done(Notifier *notifier, void *data) LoongArchMachineState *lams = container_of(notifier, LoongArchMachineState, machine_done); virt_build_smbios(lams); + loongarch_acpi_setup(lams); } struct la_memmap_entry { @@ -103,7 +108,6 @@ static int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) return la_memmap_entries; } - /* * This is a placeholder for missing ACPI, * and will eventually be replaced. @@ -174,7 +178,32 @@ static int64_t load_kernel_info(void) return kernel_entry; } -static void loongarch_devices_init(DeviceState *pch_pic) +static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState *lams) +{ + DeviceState *dev; + MachineState *ms = MACHINE(lams); + uint32_t event = ACPI_GED_PWR_DOWN_EVT; + + if (ms->ram_slots) { + event |= ACPI_GED_MEM_HOTPLUG_EVT; + } + dev = qdev_new(TYPE_ACPI_GED); + qdev_prop_set_uint32(dev, "ged-event", event); + + /* ged event */ + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_EVT_ADDR); + /* memory hotplug */ + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, GED_MEM_ADDR); + /* ged regs used for reset and power down */ + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, GED_REG_ADDR); + + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, + qdev_get_gpio_in(pch_pic, LS7A_SCI_IRQ - PCH_PIC_IRQ_OFFSET)); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + return dev; +} + +static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams) { DeviceState *gpex_dev; SysBusDevice *d; @@ -250,6 +279,8 @@ static void loongarch_devices_init(DeviceState *pch_pic) memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops, NULL, "loongarch_virt_pm", PM_SIZE); memory_region_add_subregion(get_system_memory(), PM_BASE, pm_mem); + /* acpi ged */ + lams->acpi_ged = create_acpi_ged(pch_pic, lams); } static void loongarch_irq_init(LoongArchMachineState *lams) @@ -347,7 +378,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START)); } - loongarch_devices_init(pch_pic); + loongarch_devices_init(pch_pic, lams); } static bool loongarch_firmware_init(LoongArchMachineState *lams) @@ -565,6 +596,40 @@ static void loongarch_init(MachineState *machine) qemu_add_machine_init_done_notifier(&lams->machine_done); } +bool loongarch_is_acpi_enabled(LoongArchMachineState *lams) +{ + if (lams->acpi == ON_OFF_AUTO_OFF) { + return false; + } + return true; +} + +static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); + OnOffAuto acpi = lams->acpi; + + visit_type_OnOffAuto(v, name, &acpi, errp); +} + +static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); + + visit_type_OnOffAuto(v, name, &lams->acpi, errp); +} + +static void loongarch_machine_initfn(Object *obj) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); + + lams->acpi = ON_OFF_AUTO_AUTO; + lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); + lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); +} + static void loongarch_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -580,6 +645,12 @@ static void loongarch_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_VIRTIO; mc->default_boot_order = "c"; mc->no_cdrom = 1; + + object_class_property_add(oc, "acpi", "OnOffAuto", + loongarch_get_acpi, loongarch_set_acpi, + NULL, NULL); + object_class_property_set_description(oc, "acpi", + "Enable ACPI"); } static const TypeInfo loongarch_machine_types[] = { @@ -588,6 +659,7 @@ static const TypeInfo loongarch_machine_types[] = { .parent = TYPE_MACHINE, .instance_size = sizeof(LoongArchMachineState), .class_init = loongarch_class_init, + .instance_init = loongarch_machine_initfn, } }; diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build index cecb1a5d65..3e7cbcfc05 100644 --- a/hw/loongarch/meson.build +++ b/hw/loongarch/meson.build @@ -1,4 +1,8 @@ loongarch_ss = ss.source_set() +loongarch_ss.add(files( + 'fw_cfg.c', +)) loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: files('loongson3.c')) +loongarch_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-build.c')) hw_arch += {'loongarch': loongarch_ss} diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 55bc2fe4e9..63b6917c15 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -21,6 +21,13 @@ #define LA_BIOS_BASE 0x1c000000 #define LA_BIOS_SIZE (4 * MiB) +#define LOW_MEM_BASE 0 +#define LOW_MEM_SIZE 0x10000000 +#define HIGH_MEM_BASE 0x90000000 +#define GED_EVT_ADDR 0x100e0000 +#define GED_MEM_ADDR (GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) +#define GED_REG_ADDR (GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) + struct LoongArchMachineState { /*< private >*/ MachineState parent_obj; @@ -34,8 +41,14 @@ struct LoongArchMachineState { /* State for other subsystems/APIs: */ FWCfgState *fw_cfg; Notifier machine_done; + OnOffAuto acpi; + char *oem_id; + char *oem_table_id; + DeviceState *acpi_ged; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE) +bool loongarch_is_acpi_enabled(LoongArchMachineState *lams); +void loongarch_acpi_setup(LoongArchMachineState *lams); #endif diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h index 08c5f78be2..f93c3e3287 100644 --- a/include/hw/pci-host/ls7a.h +++ b/include/hw/pci-host/ls7a.h @@ -23,6 +23,9 @@ #define LS7A_PCI_IO_BASE 0x18004000UL #define LS7A_PCI_IO_SIZE 0xC000 +#define LS7A_PCI_MEM_BASE 0x40000000UL +#define LS7A_PCI_MEM_SIZE 0x40000000UL + #define LS7A_PCH_REG_BASE 0x10000000UL #define LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE) #define LS7A_PCH_MSI_ADDR_LOW 0x2FF00000UL @@ -41,4 +44,6 @@ #define LS7A_MISC_REG_BASE (LS7A_PCH_REG_BASE + 0x00080000) #define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + 0x00050100) #define LS7A_RTC_LEN 0x100 +#define LS7A_ACPI_REG_BASE (LS7A_MISC_REG_BASE + 0x00050000) +#define LS7A_SCI_IRQ (PCH_PIC_IRQ_OFFSET + 4) #endif From patchwork Mon Jun 20 08:04:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887090 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 809AEC433EF for ; Mon, 20 Jun 2022 08:11:00 +0000 (UTC) Received: from localhost ([::1]:35644 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CUt-0002Fe-Jz for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:10:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60732) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPT-0006ez-V7 for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47768 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPJ-0007Jn-1E for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:16 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S7; Mon, 20 Jun 2022 16:04:53 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 5/8] hw/loongarch: Add fdt support Date: Mon, 20 Jun 2022 16:04:48 +0800 Message-Id: <20220620080451.3711049-6-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S7 X-Coremail-Antispam: 1UD129KBjvJXoW3Jr4DKw45Xw48GF1kJrWxCrg_yoW3ZFW3pF W7AFWUWrW8Xrnrurs7W345uwn3Jr1xGFW7W3W7WrWFka4DWw1UZa10ka9ayF15J34jqa4Y vFZ0qrySg3WIgrJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- hw/loongarch/loongson3.c | 136 +++++++++++++++++++++++++++++++++++- include/hw/loongarch/virt.h | 4 ++ target/loongarch/cpu.c | 1 + target/loongarch/cpu.h | 3 + 4 files changed, 141 insertions(+), 3 deletions(-) diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index cc449a12ae..146f582dbe 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -37,6 +37,129 @@ #include "qapi/qapi-visit-common.h" #include "hw/acpi/generic_event_device.h" #include "hw/mem/nvdimm.h" +#include "sysemu/device_tree.h" +#include + +static void create_fdt(LoongArchMachineState *lams) +{ + MachineState *ms = MACHINE(lams); + + ms->fdt = create_device_tree(&lams->fdt_size); + if (!ms->fdt) { + error_report("create_device_tree() failed"); + exit(1); + } + + /* Header */ + qemu_fdt_setprop_string(ms->fdt, "/", "compatible", + "linux,dummy-loongson3"); + qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2); + qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2); +} + +static void fdt_add_cpu_nodes(const LoongArchMachineState *lams) +{ + int num; + const MachineState *ms = MACHINE(lams); + int smp_cpus = ms->smp.cpus; + + qemu_fdt_add_subnode(ms->fdt, "/cpus"); + qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1); + qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0); + + /* cpu nodes */ + for (num = smp_cpus - 1; num >= 0; num--) { + char *nodename = g_strdup_printf("/cpus/cpu@%d", num); + LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num)); + + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu"); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", + cpu->dtb_compatible); + qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", + qemu_fdt_alloc_phandle(ms->fdt)); + g_free(nodename); + } + + /*cpu map */ + qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map"); + + for (num = smp_cpus - 1; num >= 0; num--) { + char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num); + char *map_path; + + if (ms->smp.threads > 1) { + map_path = g_strdup_printf( + "/cpus/cpu-map/socket%d/core%d/thread%d", + num / (ms->smp.cores * ms->smp.threads), + (num / ms->smp.threads) % ms->smp.cores, + num % ms->smp.threads); + } else { + map_path = g_strdup_printf( + "/cpus/cpu-map/socket%d/core%d", + num / ms->smp.cores, + num % ms->smp.cores); + } + qemu_fdt_add_path(ms->fdt, map_path); + qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path); + + g_free(map_path); + g_free(cpu_path); + } +} + +static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams) +{ + char *nodename; + hwaddr base = FW_CFG_ADDR; + const MachineState *ms = MACHINE(lams); + + nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, + "compatible", "qemu,fw-cfg-mmio"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", + 2, base, 2, 0x8); + qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); + g_free(nodename); +} + +static void fdt_add_pcie_node(const LoongArchMachineState *lams) +{ + char *nodename; + hwaddr base_mmio = LS7A_PCI_MEM_BASE; + hwaddr size_mmio = LS7A_PCI_MEM_SIZE; + hwaddr base_pio = LS7A_PCI_IO_BASE; + hwaddr size_pio = LS7A_PCI_IO_SIZE; + hwaddr base_pcie = LS_PCIECFG_BASE; + hwaddr size_pcie = LS_PCIECFG_SIZE; + hwaddr base = base_pcie; + + const MachineState *ms = MACHINE(lams); + + nodename = g_strdup_printf("/pcie@%" PRIx64, base); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, + "compatible", "pci-host-ecam-generic"); + qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "pci"); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 3); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2); + qemu_fdt_setprop_cell(ms->fdt, nodename, "linux,pci-domain", 0); + qemu_fdt_setprop_cells(ms->fdt, nodename, "bus-range", 0, + PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1)); + qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", + 2, base_pcie, 2, size_pcie); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges", + 1, FDT_PCI_RANGE_IOPORT, 2, LS7A_PCI_IO_OFFSET, + 2, base_pio, 2, size_pio, + 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, + 2, base_mmio, 2, size_mmio); + g_free(nodename); + qemu_fdt_dumpdtb(ms->fdt, lams->fdt_size); +} + #define PM_BASE 0x10080000 #define PM_SIZE 0x100 @@ -546,12 +669,12 @@ static void loongarch_init(MachineState *machine) error_report("ram_size must be greater than 1G."); exit(1); } - + create_fdt(lams); /* Init CPUs */ for (i = 0; i < machine->smp.cpus; i++) { cpu_create(machine->cpu_type); } - + fdt_add_cpu_nodes(lams); /* Add memory region */ memory_region_init_alias(&lams->lowmem, NULL, "loongarch.lowram", machine->ram, 0, 256 * MiB); @@ -572,12 +695,12 @@ static void loongarch_init(MachineState *machine) firmware_loaded = loongarch_firmware_init(lams); lams->fw_cfg = loongarch_fw_cfg_init(ram_size, machine); rom_set_fw(lams->fw_cfg); - if (lams->fw_cfg != NULL) { fw_cfg_add_file(lams->fw_cfg, "etc/memmap", la_memmap_table, sizeof(struct la_memmap_entry) * (la_memmap_entries)); } + fdt_add_fw_cfg_node(lams); loaderparams.ram_size = ram_size; loaderparams.kernel_filename = machine->kernel_filename; loaderparams.kernel_cmdline = machine->kernel_cmdline; @@ -594,6 +717,13 @@ static void loongarch_init(MachineState *machine) loongarch_irq_init(lams); lams->machine_done.notify = virt_machine_done; qemu_add_machine_init_done_notifier(&lams->machine_done); + fdt_add_pcie_node(lams); + + /* load fdt */ + MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); + memory_region_init_rom(fdt_rom, NULL, "fdt", LA_FDT_SIZE, &error_fatal); + memory_region_add_subregion(get_system_memory(), LA_FDT_BASE, fdt_rom); + rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, LA_FDT_BASE); } bool loongarch_is_acpi_enabled(LoongArchMachineState *lams) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 63b6917c15..e31ddde045 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -28,6 +28,9 @@ #define GED_MEM_ADDR (GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define GED_REG_ADDR (GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) +#define LA_FDT_BASE 0x1c400000 +#define LA_FDT_SIZE 0x100000 + struct LoongArchMachineState { /*< private >*/ MachineState parent_obj; @@ -45,6 +48,7 @@ struct LoongArchMachineState { char *oem_id; char *oem_table_id; DeviceState *acpi_ged; + int fdt_size; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 4c8f96bc3a..401d3fd30a 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -328,6 +328,7 @@ static void loongarch_la464_initfn(Object *obj) env->cpucfg[i] = 0x0; } + cpu->dtb_compatible = "loongarch,Loongson-3A5000"; env->cpucfg[0] = 0x14c010; /* PRID */ uint32_t data = 0; diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 71a5036c3c..ce394c3287 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -326,6 +326,9 @@ struct ArchCPU { CPUNegativeOffsetState neg; CPULoongArchState env; QEMUTimer timer; + + /* 'compatible' string for this CPU for Linux device trees */ + const char *dtb_compatible; }; #define TYPE_LOONGARCH_CPU "loongarch-cpu" From patchwork Mon Jun 20 08:04:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887092 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 08E38C433EF for ; Mon, 20 Jun 2022 08:14:27 +0000 (UTC) Received: from localhost ([::1]:42218 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CYD-0006no-4R for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:14:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60750) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPU-0006f5-0y for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47786 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPI-0007Jt-VS for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:17 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S8; Mon, 20 Jun 2022 16:04:54 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 6/8] hw/loongarch: Fix loongarch ipi device Date: Mon, 20 Jun 2022 16:04:49 +0800 Message-Id: <20220620080451.3711049-7-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S8 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr1DWFyfZF1DXr4xKryrXrb_yoWxXry7pr 9rurWa9r48tFZrXa4DJasrXF1DJ3Z7Wa429a9Ikay09F4kXry29asYy34qqFyqy3s5JF1Y vr1kCr42qa1UX3JanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- hw/intc/loongarch_ipi.c | 85 ++++++++++++++++++++++----------- hw/loongarch/loongson3.c | 5 +- include/hw/intc/loongarch_ipi.h | 8 ++-- 3 files changed, 65 insertions(+), 33 deletions(-) diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 66bee93675..57d7965289 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -50,35 +50,40 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) return ret; } -static int get_ipi_data(target_ulong val) +static void send_ipi_data(CPULoongArchState *env, target_ulong val, target_ulong addr) { int i, mask, data; - data = val >> 32; - mask = (val >> 27) & 0xf; - + data = address_space_ldl(&env->address_space_iocsr, addr, + MEMTXATTRS_UNSPECIFIED, NULL); + mask = 0; for (i = 0; i < 4; i++) { - if ((mask >> i) & 1) { - data &= ~(0xff << (i * 8)); + /* bit 27 - 30 is mask for byte write */ + if (val & (0x1UL << (27 + i))) { + mask |= 0xff << (i * 8); } } - return data; + + data &= mask; + data |= (val >> 32) & ~mask; + address_space_stl(&env->address_space_iocsr, addr, + data, MEMTXATTRS_UNSPECIFIED, NULL); } static void ipi_send(uint64_t val) { int cpuid, data; CPULoongArchState *env; + CPUState *cs; + LoongArchCPU *cpu; cpuid = (val >> 16) & 0x3ff; /* IPI status vector */ data = 1 << (val & 0x1f); - qemu_mutex_lock_iothread(); - CPUState *cs = qemu_get_cpu(cpuid); - LoongArchCPU *cpu = LOONGARCH_CPU(cs); + cs = qemu_get_cpu(cpuid); + cpu = LOONGARCH_CPU(cs); env = &cpu->env; loongarch_cpu_set_irq(cpu, IRQ_IPI, 1); - qemu_mutex_unlock_iothread(); address_space_stl(&env->address_space_iocsr, 0x1008, data, MEMTXATTRS_UNSPECIFIED, NULL); @@ -86,23 +91,23 @@ static void ipi_send(uint64_t val) static void mail_send(uint64_t val) { - int cpuid, data; + int cpuid; hwaddr addr; CPULoongArchState *env; + CPUState *cs; + LoongArchCPU *cpu; cpuid = (val >> 16) & 0x3ff; addr = 0x1020 + (val & 0x1c); - CPUState *cs = qemu_get_cpu(cpuid); - LoongArchCPU *cpu = LOONGARCH_CPU(cs); + cs = qemu_get_cpu(cpuid); + cpu = LOONGARCH_CPU(cs); env = &cpu->env; - data = get_ipi_data(val); - address_space_stl(&env->address_space_iocsr, addr, - data, MEMTXATTRS_UNSPECIFIED, NULL); + send_ipi_data(env, val, addr); } static void any_send(uint64_t val) { - int cpuid, data; + int cpuid; hwaddr addr; CPULoongArchState *env; @@ -111,9 +116,7 @@ static void any_send(uint64_t val) CPUState *cs = qemu_get_cpu(cpuid); LoongArchCPU *cpu = LOONGARCH_CPU(cs); env = &cpu->env; - data = get_ipi_data(val); - address_space_stl(&env->address_space_iocsr, addr, - data, MEMTXATTRS_UNSPECIFIED, NULL); + send_ipi_data(env, val, addr); } static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, @@ -150,12 +153,6 @@ static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, case IOCSR_IPI_SEND: ipi_send(val); break; - case IOCSR_MAIL_SEND: - mail_send(val); - break; - case IOCSR_ANY_SEND: - any_send(val); - break; default: qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr); break; @@ -172,6 +169,32 @@ static const MemoryRegionOps loongarch_ipi_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +/* mail send and any send only support writeq */ +static void loongarch_ipi_writeq(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + addr &= 0xfff; + switch (addr) { + case MAIL_SEND_OFFSET: + mail_send(val); + break; + case ANY_SEND_OFFSET: + any_send(val); + break; + default: + break; + } +} + +static const MemoryRegionOps loongarch_ipi64_ops = { + .write = loongarch_ipi_writeq, + .impl.min_access_size = 8, + .impl.max_access_size = 8, + .valid.min_access_size = 4, + .valid.max_access_size = 8, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void loongarch_ipi_init(Object *obj) { int cpu; @@ -185,10 +208,16 @@ static void loongarch_ipi_init(Object *obj) return; } lams = LOONGARCH_MACHINE(machine); + for (cpu = 0; cpu < MAX_IPI_CORE_NUM; cpu++) { memory_region_init_io(&s->ipi_iocsr_mem[cpu], obj, &loongarch_ipi_ops, - &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x100); + &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x48); sysbus_init_mmio(sbd, &s->ipi_iocsr_mem[cpu]); + + memory_region_init_io(&s->ipi64_iocsr_mem[cpu], obj, &loongarch_ipi64_ops, + &lams->ipi_core[cpu], "loongarch_ipi64_iocsr", 0x118); + sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem[cpu]); + qdev_init_gpio_out(DEVICE(obj), &lams->ipi_core[cpu].irq, 1); } } diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index 146f582dbe..c8bbe384d4 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -455,7 +455,10 @@ static void loongarch_irq_init(LoongArchMachineState *lams) /* IPI iocsr memory region */ memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX, sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), - cpu)); + cpu * 2)); + memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), + cpu * 2 + 1)); /* extioi iocsr memory region */ memory_region_add_subregion(&env->system_iocsr, APIC_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h index 996ed7ea93..a98c3dd4a3 100644 --- a/include/hw/intc/loongarch_ipi.h +++ b/include/hw/intc/loongarch_ipi.h @@ -23,9 +23,9 @@ #define IOCSR_IPI_SEND 0x40 #define IOCSR_MAIL_SEND 0x48 #define IOCSR_ANY_SEND 0x158 - -/* IPI system memory address */ -#define IPI_SYSTEM_MEM 0x1fe01000 +#define MAIL_SEND_ADDR (SMP_IPI_MAILBOX + IOCSR_MAIL_SEND) +#define MAIL_SEND_OFFSET 0 +#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND) #define MAX_IPI_CORE_NUM 4 #define MAX_IPI_MBX_NUM 4 @@ -46,7 +46,7 @@ typedef struct IPICore { struct LoongArchIPI { SysBusDevice parent_obj; MemoryRegion ipi_iocsr_mem[MAX_IPI_CORE_NUM]; - MemoryRegion ipi_system_mem[MAX_IPI_CORE_NUM]; + MemoryRegion ipi64_iocsr_mem[MAX_IPI_CORE_NUM]; }; #endif From patchwork Mon Jun 20 08:04:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887089 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 305CBC43334 for ; Mon, 20 Jun 2022 08:10:02 +0000 (UTC) Received: from localhost ([::1]:34058 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CTx-0001Dt-2m for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:10:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60738) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPT-0006f2-Ux for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47778 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPI-0007Js-Ro for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:16 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S9; Mon, 20 Jun 2022 16:04:54 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 7/8] target/loongarch: Fix vector size of exception entry address Date: Mon, 20 Jun 2022 16:04:50 +0800 Message-Id: <20220620080451.3711049-8-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S9 X-Coremail-Antispam: 1UD129KBjvdXoWrKr1ftw15uFyftF4DKFyfJFb_yoWxAFX_G3 Wfua1DCFyj93ZFqr4Fk345t345Xr48Ga1q9FZ7trZ7Ca45XwsxZwsFqwn7ur129rW7WFnx AasrGryYyr4akjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUUUUUUU X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- target/loongarch/cpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 401d3fd30a..d1a87e8e1c 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -219,6 +219,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); + if (vec_size) { + vec_size = (1 << vec_size) * 4; + } + if (cs->exception_index == EXCCODE_INT) { /* Interrupt */ uint32_t vector = 0; From patchwork Mon Jun 20 08:04:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaojuan Yang X-Patchwork-Id: 12887087 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 20950C433EF for ; Mon, 20 Jun 2022 08:09:58 +0000 (UTC) Received: from localhost ([::1]:33886 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CTs-00016b-Rc for qemu-devel@archiver.kernel.org; Mon, 20 Jun 2022 04:09:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60734) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o3CPT-0006f0-Ui for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:24 -0400 Received: from mail.loongson.cn ([114.242.206.163]:47776 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o3CPJ-0007Jr-Gp for qemu-devel@nongnu.org; Mon, 20 Jun 2022 04:05:18 -0400 Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Cxr+YjKrBilqVOAA--.20331S10; Mon, 20 Jun 2022 16:04:55 +0800 (CST) From: Xiaojuan Yang To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, gaosong@loongson.cn, maobibo@loongson.cn, mark.cave-ayland@ilande.co.uk, mst@redhat.com, imammedo@redhat.com, ani@anisinha.ca, f4bug@amsat.org, peter.maydell@linaro.org, chenhuacai@loongson.cn Subject: [PATCH 8/8] target/loongarch: Fix csrwr timer clear Date: Mon, 20 Jun 2022 16:04:51 +0800 Message-Id: <20220620080451.3711049-9-yangxiaojuan@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> References: <20220620080451.3711049-1-yangxiaojuan@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Cxr+YjKrBilqVOAA--.20331S10 X-Coremail-Antispam: 1UD129KBjvdXoW5Kw1rXr1xAFW3ZF1ruryfWFg_yoWxGFg_XF 1xGa1kurW8W3ZIkw1Yvr98tw15Jw18KF1akFsrXF4xKFyUG3ZxXr4qqan3Cw1j9r15Xrn8 ZrsavrWa9F1YkjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUUUUUUU X-CM-SenderInfo: p1dqw5xldry3tdq6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangxiaojuan@loongson.cn; helo=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_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Xiaojuan Yang --- target/loongarch/csr_helper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/loongarch/csr_helper.c b/target/loongarch/csr_helper.c index 24a9389364..7e02787895 100644 --- a/target/loongarch/csr_helper.c +++ b/target/loongarch/csr_helper.c @@ -81,7 +81,9 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val) int64_t old_v = 0; if (val & 0x1) { + qemu_mutex_lock_iothread(); loongarch_cpu_set_irq(cpu, IRQ_TIMER, 0); + qemu_mutex_unlock_iothread(); } return old_v; }