From f9cc8cfdf346cadc92db8fce32c8b5d7f1095163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 3 Sep 2021 11:59:27 +0200 Subject: [PATCH 01/28] block/qcow2-bitmap: Replace g_memdup() by g_memdup2() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538 The old API took the size of the memory to duplicate as a guint, whereas most memory functions take memory sizes as a gsize. This made it easy to accidentally pass a gsize to g_memdup(). For large values, that would lead to a silent truncation of the size from 64 to 32 bits, and result in a heap area being returned which is significantly smaller than what the caller expects. This can likely be exploited in various modules to cause a heap buffer overflow. Replace g_memdup() by the safer g_memdup2() wrapper. Trivially safe because the argument was directly from sizeof. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Eric Blake Message-Id: <20210903174510.751630-6-philmd@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- block/qcow2-bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 874ea56948..256ec99878 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -1609,7 +1609,7 @@ bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, name); goto fail; } - tb = g_memdup(&bm->table, sizeof(bm->table)); + tb = g_memdup2(&bm->table, sizeof(bm->table)); bm->table.offset = 0; bm->table.size = 0; QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry); From 40fed8c1d3a2bcef81c8de3f55d7e1abe1397347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 3 Sep 2021 12:05:51 +0200 Subject: [PATCH 02/28] target/ppc: Replace g_memdup() by g_memdup2() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538 The old API took the size of the memory to duplicate as a guint, whereas most memory functions take memory sizes as a gsize. This made it easy to accidentally pass a gsize to g_memdup(). For large values, that would lead to a silent truncation of the size from 64 to 32 bits, and result in a heap area being returned which is significantly smaller than what the caller expects. This can likely be exploited in various modules to cause a heap buffer overflow. Replace g_memdup() by the safer g_memdup2() wrapper. Trivially safe because the argument was directly from sizeof. Signed-off-by: Philippe Mathieu-Daudé Acked-by: David Gibson Message-Id: <20210903174510.751630-27-philmd@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/ppc/mmu-hash64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 5a0d80feda..0966422a55 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -1188,7 +1188,7 @@ void ppc_hash64_init(PowerPCCPU *cpu) return; } - cpu->hash64_opts = g_memdup(pcc->hash64_opts, sizeof(*cpu->hash64_opts)); + cpu->hash64_opts = g_memdup2(pcc->hash64_opts, sizeof(*cpu->hash64_opts)); } void ppc_hash64_finalize(PowerPCCPU *cpu) From 0572f01117c897bef5ece0b367bc6700d4fbd161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 3 Sep 2021 12:01:20 +0200 Subject: [PATCH 03/28] hw/hppa/machine: Replace g_memdup() by g_memdup2() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538 The old API took the size of the memory to duplicate as a guint, whereas most memory functions take memory sizes as a gsize. This made it easy to accidentally pass a gsize to g_memdup(). For large values, that would lead to a silent truncation of the size from 64 to 32 bits, and result in a heap area being returned which is significantly smaller than what the caller expects. This can likely be exploited in various modules to cause a heap buffer overflow. Replace g_memdup() by the safer g_memdup2() wrapper. Trivially safe because the argument was directly from sizeof. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210903174510.751630-12-philmd@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/hppa/machine.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 37ee6387e0..5d0a8739de 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -207,37 +207,37 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus, val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION); fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version", - g_memdup(&val, sizeof(val)), sizeof(val)); + g_memdup2(&val, sizeof(val)), sizeof(val)); val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries); fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries", - g_memdup(&val, sizeof(val)), sizeof(val)); + g_memdup2(&val, sizeof(val)), sizeof(val)); val = cpu_to_le64(btlb_entries); fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries", - g_memdup(&val, sizeof(val)), sizeof(val)); + g_memdup2(&val, sizeof(val)), sizeof(val)); len = strlen(mc->name) + 1; fw_cfg_add_file(fw_cfg, "/etc/hppa/machine", - g_memdup(mc->name, len), len); + g_memdup2(mc->name, len), len); val = cpu_to_le64(soft_power_reg); fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr", - g_memdup(&val, sizeof(val)), sizeof(val)); + g_memdup2(&val, sizeof(val)), sizeof(val)); val = cpu_to_le64(CPU_HPA + 16); fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr", - g_memdup(&val, sizeof(val)), sizeof(val)); + g_memdup2(&val, sizeof(val)), sizeof(val)); val = cpu_to_le64(CPU_HPA + 24); fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort", - g_memdup(&val, sizeof(val)), sizeof(val)); + g_memdup2(&val, sizeof(val)), sizeof(val)); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); fw_cfg_add_file(fw_cfg, "/etc/qemu-version", - g_memdup(qemu_version, sizeof(qemu_version)), + g_memdup2(qemu_version, sizeof(qemu_version)), sizeof(qemu_version)); fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg); From 09d98a241caf12e0de5ab738cfa5c911af97fbd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 3 Sep 2021 12:05:50 +0200 Subject: [PATCH 04/28] hw/ppc/spapr_pci: Replace g_memdup() by g_memdup2() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538 The old API took the size of the memory to duplicate as a guint, whereas most memory functions take memory sizes as a gsize. This made it easy to accidentally pass a gsize to g_memdup(). For large values, that would lead to a silent truncation of the size from 64 to 32 bits, and result in a heap area being returned which is significantly smaller than what the caller expects. This can likely be exploited in various modules to cause a heap buffer overflow. Replace g_memdup() by the safer g_memdup2() wrapper. Trivially safe because the argument was directly from sizeof. Signed-off-by: Philippe Mathieu-Daudé Acked-by: David Gibson Message-Id: <20210903174510.751630-17-philmd@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/ppc/spapr_pci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 72cfba419a..7cf9904c35 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2188,10 +2188,9 @@ static int spapr_pci_post_load(void *opaque, int version_id) int i; for (i = 0; i < sphb->msi_devs_num; ++i) { - key = g_memdup(&sphb->msi_devs[i].key, - sizeof(sphb->msi_devs[i].key)); - value = g_memdup(&sphb->msi_devs[i].value, - sizeof(sphb->msi_devs[i].value)); + key = g_memdup2(&sphb->msi_devs[i].key, sizeof(sphb->msi_devs[i].key)); + value = g_memdup2(&sphb->msi_devs[i].value, + sizeof(sphb->msi_devs[i].value)); g_hash_table_insert(sphb->msi, key, value); } g_free(sphb->msi_devs); From e6578f1f68a0e90789a841ada532c3e494c9a04c Mon Sep 17 00:00:00 2001 From: Mattias Nissler Date: Wed, 23 Aug 2023 02:29:30 -0700 Subject: [PATCH 05/28] hw/remote/vfio-user: Fix config space access byte order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCI config space is little-endian, so on a big-endian host we need to perform byte swaps for values as they are passed to and received from the generic PCI config space access machinery. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Hajnoczi Reviewed-by: Jagannathan Raman Signed-off-by: Mattias Nissler Message-ID: <20240507094210.300566-6-mnissler@rivosinc.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/remote/vfio-user-obj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index d9b879e056..8dbafafb9e 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -281,7 +281,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf, while (bytes > 0) { len = (bytes > pci_access_width) ? pci_access_width : bytes; if (is_write) { - memcpy(&val, ptr, len); + val = ldn_le_p(ptr, len); pci_host_config_write_common(o->pci_dev, offset, pci_config_size(o->pci_dev), val, len); @@ -289,7 +289,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf, } else { val = pci_host_config_read_common(o->pci_dev, offset, pci_config_size(o->pci_dev), len); - memcpy(ptr, &val, len); + stn_le_p(ptr, len, val); trace_vfu_cfg_read(offset, val); } offset += len; From d5e268197aa2ba89bc0540717c72be2c69568b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 7 May 2024 14:12:46 +0200 Subject: [PATCH 06/28] system/physmem: Replace qemu_mutex_lock() calls with QEMU_LOCK_GUARD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify cpu_[un]register_map_client() and cpu_notify_map_clients() by replacing the pair of qemu_mutex_lock/qemu_mutex_unlock calls by the WITH_QEMU_LOCK_GUARD() macro. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Mattias Nissler Reviewed-by: Peter Xu Message-Id: <20240507123025.93391-2-philmd@linaro.org> --- system/physmem.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/system/physmem.c b/system/physmem.c index d3a3d8a45c..26f42f4a6f 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -25,6 +25,7 @@ #include "qemu/cacheflush.h" #include "qemu/hbitmap.h" #include "qemu/madvise.h" +#include "qemu/lockable.h" #ifdef CONFIG_TCG #include "hw/core/tcg-cpu-ops.h" @@ -3086,7 +3087,7 @@ void cpu_register_map_client(QEMUBH *bh) { MapClient *client = g_malloc(sizeof(*client)); - qemu_mutex_lock(&map_client_list_lock); + QEMU_LOCK_GUARD(&map_client_list_lock); client->bh = bh; QLIST_INSERT_HEAD(&map_client_list, client, link); /* Write map_client_list before reading in_use. */ @@ -3094,7 +3095,6 @@ void cpu_register_map_client(QEMUBH *bh) if (!qatomic_read(&bounce.in_use)) { cpu_notify_map_clients_locked(); } - qemu_mutex_unlock(&map_client_list_lock); } void cpu_exec_init_all(void) @@ -3117,21 +3117,19 @@ void cpu_unregister_map_client(QEMUBH *bh) { MapClient *client; - qemu_mutex_lock(&map_client_list_lock); + QEMU_LOCK_GUARD(&map_client_list_lock); QLIST_FOREACH(client, &map_client_list, link) { if (client->bh == bh) { cpu_unregister_map_client_do(client); break; } } - qemu_mutex_unlock(&map_client_list_lock); } static void cpu_notify_map_clients(void) { - qemu_mutex_lock(&map_client_list_lock); + QEMU_LOCK_GUARD(&map_client_list_lock); cpu_notify_map_clients_locked(); - qemu_mutex_unlock(&map_client_list_lock); } static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len, From 5c62719710bab66a98f68ebdba333e2240ed6668 Mon Sep 17 00:00:00 2001 From: Mattias Nissler Date: Thu, 7 Sep 2023 06:04:23 -0700 Subject: [PATCH 07/28] system/physmem: Propagate AddressSpace to MapClient helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Propagate AddressSpace handler to following helpers: - register_map_client() - unregister_map_client() - notify_map_clients[_locked]() Rename them using 'address_space_' prefix instead of 'cpu_'. The AddressSpace argument will be used in the next commit. Reviewed-by: Peter Xu Tested-by: Jonathan Cameron Signed-off-by: Mattias Nissler Message-ID: <20240507094210.300566-2-mnissler@rivosinc.com> [PMD: Split patch, part 1/2] Signed-off-by: Philippe Mathieu-Daudé --- include/exec/cpu-common.h | 2 -- include/exec/memory.h | 26 ++++++++++++++++++++++++-- system/dma-helpers.c | 4 ++-- system/physmem.c | 24 ++++++++++++------------ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 8bc397e251..815342d043 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -147,8 +147,6 @@ void *cpu_physical_memory_map(hwaddr addr, bool is_write); void cpu_physical_memory_unmap(void *buffer, hwaddr len, bool is_write, hwaddr access_len); -void cpu_register_map_client(QEMUBH *bh); -void cpu_unregister_map_client(QEMUBH *bh); bool cpu_physical_memory_is_io(hwaddr phys_addr); diff --git a/include/exec/memory.h b/include/exec/memory.h index dadb5cd65a..e1e0c5a3de 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -2946,8 +2946,8 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, hwaddr len, * May return %NULL and set *@plen to zero(0), if resources needed to perform * the mapping are exhausted. * Use only for reads OR writes - not for read-modify-write operations. - * Use cpu_register_map_client() to know when retrying the map operation is - * likely to succeed. + * Use address_space_register_map_client() to know when retrying the map + * operation is likely to succeed. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -2972,6 +2972,28 @@ void *address_space_map(AddressSpace *as, hwaddr addr, void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, bool is_write, hwaddr access_len); +/* + * address_space_register_map_client: Register a callback to invoke when + * resources for address_space_map() are available again. + * + * address_space_map may fail when there are not enough resources available, + * such as when bounce buffer memory would exceed the limit. The callback can + * be used to retry the address_space_map operation. Note that the callback + * gets automatically removed after firing. + * + * @as: #AddressSpace to be accessed + * @bh: callback to invoke when address_space_map() retry is appropriate + */ +void address_space_register_map_client(AddressSpace *as, QEMUBH *bh); + +/* + * address_space_unregister_map_client: Unregister a callback that has + * previously been registered and not fired yet. + * + * @as: #AddressSpace to be accessed + * @bh: callback to unregister + */ +void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh); /* Internal functions, part of the implementation of address_space_read. */ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, diff --git a/system/dma-helpers.c b/system/dma-helpers.c index 9b221cf94e..74013308f5 100644 --- a/system/dma-helpers.c +++ b/system/dma-helpers.c @@ -169,7 +169,7 @@ static void dma_blk_cb(void *opaque, int ret) if (dbs->iov.size == 0) { trace_dma_map_wait(dbs); dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs); - cpu_register_map_client(dbs->bh); + address_space_register_map_client(dbs->sg->as, dbs->bh); return; } @@ -197,7 +197,7 @@ static void dma_aio_cancel(BlockAIOCB *acb) } if (dbs->bh) { - cpu_unregister_map_client(dbs->bh); + address_space_unregister_map_client(dbs->sg->as, dbs->bh); qemu_bh_delete(dbs->bh); dbs->bh = NULL; } diff --git a/system/physmem.c b/system/physmem.c index 26f42f4a6f..b76b3d2184 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -3066,24 +3066,24 @@ QemuMutex map_client_list_lock; static QLIST_HEAD(, MapClient) map_client_list = QLIST_HEAD_INITIALIZER(map_client_list); -static void cpu_unregister_map_client_do(MapClient *client) +static void address_space_unregister_map_client_do(MapClient *client) { QLIST_REMOVE(client, link); g_free(client); } -static void cpu_notify_map_clients_locked(void) +static void address_space_notify_map_clients_locked(AddressSpace *as) { MapClient *client; while (!QLIST_EMPTY(&map_client_list)) { client = QLIST_FIRST(&map_client_list); qemu_bh_schedule(client->bh); - cpu_unregister_map_client_do(client); + address_space_unregister_map_client_do(client); } } -void cpu_register_map_client(QEMUBH *bh) +void address_space_register_map_client(AddressSpace *as, QEMUBH *bh) { MapClient *client = g_malloc(sizeof(*client)); @@ -3093,7 +3093,7 @@ void cpu_register_map_client(QEMUBH *bh) /* Write map_client_list before reading in_use. */ smp_mb(); if (!qatomic_read(&bounce.in_use)) { - cpu_notify_map_clients_locked(); + address_space_notify_map_clients_locked(as); } } @@ -3113,23 +3113,23 @@ void cpu_exec_init_all(void) qemu_mutex_init(&map_client_list_lock); } -void cpu_unregister_map_client(QEMUBH *bh) +void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh) { MapClient *client; QEMU_LOCK_GUARD(&map_client_list_lock); QLIST_FOREACH(client, &map_client_list, link) { if (client->bh == bh) { - cpu_unregister_map_client_do(client); + address_space_unregister_map_client_do(client); break; } } } -static void cpu_notify_map_clients(void) +static void address_space_notify_map_clients(AddressSpace *as) { QEMU_LOCK_GUARD(&map_client_list_lock); - cpu_notify_map_clients_locked(); + address_space_notify_map_clients_locked(as); } static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len, @@ -3196,8 +3196,8 @@ flatview_extend_translation(FlatView *fv, hwaddr addr, * May map a subset of the requested range, given by and returned in *plen. * May return NULL if resources needed to perform the mapping are exhausted. * Use only for reads OR writes - not for read-modify-write operations. - * Use cpu_register_map_client() to know when retrying the map operation is - * likely to succeed. + * Use address_space_register_map_client() to know when retrying the map + * operation is likely to succeed. */ void *address_space_map(AddressSpace *as, hwaddr addr, @@ -3280,7 +3280,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, memory_region_unref(bounce.mr); /* Clear in_use before reading map_client_list. */ qatomic_set_mb(&bounce.in_use, false); - cpu_notify_map_clients(); + address_space_notify_map_clients(as); } void *cpu_physical_memory_map(hwaddr addr, From 69e78f1b3484e429274352a464a94fa1d78be339 Mon Sep 17 00:00:00 2001 From: Mattias Nissler Date: Thu, 7 Sep 2023 06:04:23 -0700 Subject: [PATCH 08/28] system/physmem: Per-AddressSpace bounce buffering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using a single global bounce buffer, give each AddressSpace its own bounce buffer. The MapClient callback mechanism moves to AddressSpace accordingly. This is in preparation for generalizing bounce buffer handling further to allow multiple bounce buffers, with a total allocation limit configured per AddressSpace. Reviewed-by: Peter Xu Tested-by: Jonathan Cameron Signed-off-by: Mattias Nissler Message-ID: <20240507094210.300566-2-mnissler@rivosinc.com> Reviewed-by: Philippe Mathieu-Daudé [PMD: Split patch, part 2/2] Signed-off-by: Philippe Mathieu-Daudé --- include/exec/memory.h | 19 +++++++++++ system/memory.c | 7 +++++ system/physmem.c | 73 ++++++++++++++++--------------------------- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index e1e0c5a3de..d417d7f363 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1112,6 +1112,19 @@ struct MemoryListener { QTAILQ_ENTRY(MemoryListener) link_as; }; +typedef struct AddressSpaceMapClient { + QEMUBH *bh; + QLIST_ENTRY(AddressSpaceMapClient) link; +} AddressSpaceMapClient; + +typedef struct { + MemoryRegion *mr; + void *buffer; + hwaddr addr; + hwaddr len; + bool in_use; +} BounceBuffer; + /** * struct AddressSpace: describes a mapping of addresses to #MemoryRegion objects */ @@ -1129,6 +1142,12 @@ struct AddressSpace { struct MemoryRegionIoeventfd *ioeventfds; QTAILQ_HEAD(, MemoryListener) listeners; QTAILQ_ENTRY(AddressSpace) address_spaces_link; + + /* Bounce buffer to use for this address space. */ + BounceBuffer bounce; + /* List of callbacks to invoke when buffers free up */ + QemuMutex map_client_list_lock; + QLIST_HEAD(, AddressSpaceMapClient) map_client_list; }; typedef struct AddressSpaceDispatch AddressSpaceDispatch; diff --git a/system/memory.c b/system/memory.c index 49f1cb2c38..642a449f8c 100644 --- a/system/memory.c +++ b/system/memory.c @@ -3174,6 +3174,9 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) as->ioeventfds = NULL; QTAILQ_INIT(&as->listeners); QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link); + as->bounce.in_use = false; + qemu_mutex_init(&as->map_client_list_lock); + QLIST_INIT(&as->map_client_list); as->name = g_strdup(name ? name : "anonymous"); address_space_update_topology(as); address_space_update_ioeventfds(as); @@ -3181,6 +3184,10 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) static void do_address_space_destroy(AddressSpace *as) { + assert(!qatomic_read(&as->bounce.in_use)); + assert(QLIST_EMPTY(&as->map_client_list)); + qemu_mutex_destroy(&as->map_client_list_lock); + assert(QTAILQ_EMPTY(&as->listeners)); flatview_unref(as->current_map); diff --git a/system/physmem.c b/system/physmem.c index b76b3d2184..342b7a8fd4 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -3047,26 +3047,8 @@ void cpu_flush_icache_range(hwaddr start, hwaddr len) NULL, len, FLUSH_CACHE); } -typedef struct { - MemoryRegion *mr; - void *buffer; - hwaddr addr; - hwaddr len; - bool in_use; -} BounceBuffer; - -static BounceBuffer bounce; - -typedef struct MapClient { - QEMUBH *bh; - QLIST_ENTRY(MapClient) link; -} MapClient; - -QemuMutex map_client_list_lock; -static QLIST_HEAD(, MapClient) map_client_list - = QLIST_HEAD_INITIALIZER(map_client_list); - -static void address_space_unregister_map_client_do(MapClient *client) +static void +address_space_unregister_map_client_do(AddressSpaceMapClient *client) { QLIST_REMOVE(client, link); g_free(client); @@ -3074,10 +3056,10 @@ static void address_space_unregister_map_client_do(MapClient *client) static void address_space_notify_map_clients_locked(AddressSpace *as) { - MapClient *client; + AddressSpaceMapClient *client; - while (!QLIST_EMPTY(&map_client_list)) { - client = QLIST_FIRST(&map_client_list); + while (!QLIST_EMPTY(&as->map_client_list)) { + client = QLIST_FIRST(&as->map_client_list); qemu_bh_schedule(client->bh); address_space_unregister_map_client_do(client); } @@ -3085,14 +3067,14 @@ static void address_space_notify_map_clients_locked(AddressSpace *as) void address_space_register_map_client(AddressSpace *as, QEMUBH *bh) { - MapClient *client = g_malloc(sizeof(*client)); + AddressSpaceMapClient *client = g_malloc(sizeof(*client)); - QEMU_LOCK_GUARD(&map_client_list_lock); + QEMU_LOCK_GUARD(&as->map_client_list_lock); client->bh = bh; - QLIST_INSERT_HEAD(&map_client_list, client, link); + QLIST_INSERT_HEAD(&as->map_client_list, client, link); /* Write map_client_list before reading in_use. */ smp_mb(); - if (!qatomic_read(&bounce.in_use)) { + if (!qatomic_read(&as->bounce.in_use)) { address_space_notify_map_clients_locked(as); } } @@ -3110,15 +3092,14 @@ void cpu_exec_init_all(void) finalize_target_page_bits(); io_mem_init(); memory_map_init(); - qemu_mutex_init(&map_client_list_lock); } void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh) { - MapClient *client; + AddressSpaceMapClient *client; - QEMU_LOCK_GUARD(&map_client_list_lock); - QLIST_FOREACH(client, &map_client_list, link) { + QEMU_LOCK_GUARD(&as->map_client_list_lock); + QLIST_FOREACH(client, &as->map_client_list, link) { if (client->bh == bh) { address_space_unregister_map_client_do(client); break; @@ -3128,7 +3109,7 @@ void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh) static void address_space_notify_map_clients(AddressSpace *as) { - QEMU_LOCK_GUARD(&map_client_list_lock); + QEMU_LOCK_GUARD(&as->map_client_list_lock); address_space_notify_map_clients_locked(as); } @@ -3220,25 +3201,25 @@ void *address_space_map(AddressSpace *as, mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs); if (!memory_access_is_direct(mr, is_write)) { - if (qatomic_xchg(&bounce.in_use, true)) { + if (qatomic_xchg(&as->bounce.in_use, true)) { *plen = 0; return NULL; } /* Avoid unbounded allocations */ l = MIN(l, TARGET_PAGE_SIZE); - bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l); - bounce.addr = addr; - bounce.len = l; + as->bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l); + as->bounce.addr = addr; + as->bounce.len = l; memory_region_ref(mr); - bounce.mr = mr; + as->bounce.mr = mr; if (!is_write) { flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED, - bounce.buffer, l); + as->bounce.buffer, l); } *plen = l; - return bounce.buffer; + return as->bounce.buffer; } @@ -3256,7 +3237,7 @@ void *address_space_map(AddressSpace *as, void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, bool is_write, hwaddr access_len) { - if (buffer != bounce.buffer) { + if (buffer != as->bounce.buffer) { MemoryRegion *mr; ram_addr_t addr1; @@ -3272,14 +3253,14 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, return; } if (is_write) { - address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED, - bounce.buffer, access_len); + address_space_write(as, as->bounce.addr, MEMTXATTRS_UNSPECIFIED, + as->bounce.buffer, access_len); } - qemu_vfree(bounce.buffer); - bounce.buffer = NULL; - memory_region_unref(bounce.mr); + qemu_vfree(as->bounce.buffer); + as->bounce.buffer = NULL; + memory_region_unref(as->bounce.mr); /* Clear in_use before reading map_client_list. */ - qatomic_set_mb(&bounce.in_use, false); + qatomic_set_mb(&as->bounce.in_use, false); address_space_notify_map_clients(as); } From 64436c5c1739abf58ef3b768c20f312355c370fc Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 25 Apr 2024 20:43:13 +0200 Subject: [PATCH 09/28] hw/i386/pc: Allow to compile without CONFIG_FDC_ISA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The q35 machine can work without FDC. But to be able to also link a QEMU binary that does not include the FDC code, we have to make it possible to disable the spots that call into the FDC code. Signed-off-by: Thomas Huth Acked-by: Philippe Mathieu-Daudé Message-ID: <20240425184315.553329-2-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 46235466d7..505ea750f4 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -440,16 +440,19 @@ static void pc_boot_set(void *opaque, const char *boot_device, Error **errp) static void pc_cmos_init_floppy(MC146818RtcState *rtc_state, ISADevice *floppy) { - int val, nb, i; + int val, nb; FloppyDriveType fd_type[2] = { FLOPPY_DRIVE_TYPE_NONE, FLOPPY_DRIVE_TYPE_NONE }; +#ifdef CONFIG_FDC_ISA /* floppy type */ if (floppy) { - for (i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) { fd_type[i] = isa_fdc_get_drive_type(floppy, i); } } +#endif + val = (cmos_get_fd_drive_type(fd_type[0]) << 4) | cmos_get_fd_drive_type(fd_type[1]); mc146818rtc_set_cmos_data(rtc_state, 0x10, val); @@ -1133,7 +1136,7 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl, int i; DriveInfo *fd[MAX_FD]; qemu_irq *a20_line; - ISADevice *fdc, *i8042, *port92, *vmmouse; + ISADevice *i8042, *port92, *vmmouse; serial_hds_isa_init(isa_bus, 0, MAX_ISA_SERIAL_PORTS); parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS); @@ -1143,11 +1146,13 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl, create_fdctrl |= !!fd[i]; } if (create_fdctrl) { - fdc = isa_new(TYPE_ISA_FDC); +#ifdef CONFIG_FDC_ISA + ISADevice *fdc = isa_new(TYPE_ISA_FDC); if (fdc) { isa_realize_and_unref(fdc, isa_bus, &error_fatal); isa_fdc_init_drives(fdc, fd); } +#endif } if (!create_i8042) { From 77af05946e450a804b55b4a10b0b1fbd4f838fa4 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 25 Apr 2024 20:43:14 +0200 Subject: [PATCH 10/28] hw/i386/Kconfig: Allow to compile Q35 without FDC_ISA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The q35 machine can be used without floppy disk controller (FDC), but due to our current Kconfig setup, the FDC code is still always included in the binary. To fix this, the "PC" config option should only imply the "FDC_ISA" instead of always selecting it. The i440fx and the isa-pc machine currently always instantiate the FDC, so we have to add the select statements now there instead. Signed-off-by: Thomas Huth Acked-by: Philippe Mathieu-Daudé Message-ID: <20240425184315.553329-3-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index 4362164962..58ca8f246d 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -32,7 +32,7 @@ config PC imply VGA_PCI imply VIRTIO_VGA imply NVDIMM - select FDC_ISA + imply FDC_ISA select I8259 select I8254 select PCKBD @@ -72,6 +72,7 @@ config I440FX imply VMPORT imply VMMOUSE select ACPI_PIIX4 + select FDC_ISA select PC_PCI select PC_ACPI select PCI_I440FX @@ -87,6 +88,7 @@ config ISAPC depends on I386 imply VGA_ISA select ISA_BUS + select FDC_ISA select PC select IDE_ISA # FIXME: it is in the same file as i440fx, and does not compile From 8793d601f38b417d63820456582e1e22e51c2d34 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 25 Apr 2024 20:43:15 +0200 Subject: [PATCH 11/28] hw/i386: Add the possibility to use i440fx and isapc without FDC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i440fx and the isapc machines can be used in binaries without FDC, too. We just have to make sure that they don't try to instantiate the FDC when it is not available. Signed-off-by: Thomas Huth Acked-by: Philippe Mathieu-Daudé Message-ID: <20240425184315.553329-4-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/Kconfig | 2 -- hw/i386/pc_piix.c | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index 58ca8f246d..40b1e44580 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -72,7 +72,6 @@ config I440FX imply VMPORT imply VMMOUSE select ACPI_PIIX4 - select FDC_ISA select PC_PCI select PC_ACPI select PCI_I440FX @@ -88,7 +87,6 @@ config ISAPC depends on I386 imply VGA_ISA select ISA_BUS - select FDC_ISA select PC select IDE_ISA # FIXME: it is in the same file as i440fx, and does not compile diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 8850c49c66..99efb3c45c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -317,8 +317,8 @@ static void pc_init1(MachineState *machine, const char *pci_type) } /* init basic PC hardware */ - pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc, true, - 0x4); + pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc, + !MACHINE_CLASS(pcmc)->no_floppy, 0x4); pc_nic_init(pcmc, isa_bus, pcms->pcibus); @@ -501,6 +501,7 @@ static void pc_i440fx_machine_options(MachineClass *m) m->default_machine_opts = "firmware=bios-256k.bin"; m->default_display = "std"; m->default_nic = "e1000"; + m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC); m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL); machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE); @@ -931,6 +932,7 @@ static void isapc_machine_options(MachineClass *m) pcmc->has_reserved_memory = false; m->default_nic = "ne2k_isa"; m->default_cpu_type = X86_CPU_TYPE_NAME("486"); + m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC); m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL); } From 014dbdac8798799d081abc9dff3e4876ca54f49e Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 30 Apr 2024 17:06:38 +0200 Subject: [PATCH 12/28] hw/i386/x86: Eliminate two if statements in x86_bios_rom_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given that memory_region_set_readonly() is a no-op when the readonlyness is already as requested it is possible to simplify the pattern if (condition) { foo(true); } to foo(condition); which is shorter and allows to see the invariant of the code more easily. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240430150643.111976-2-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/x86.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 3d5b51e92d..2a4f3ee285 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -1163,9 +1163,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, load_image_size(filename, ptr, bios_size); x86_firmware_configure(ptr, bios_size); } else { - if (!isapc_ram_fw) { - memory_region_set_readonly(bios, true); - } + memory_region_set_readonly(bios, !isapc_ram_fw); ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); if (ret != 0) { goto bios_error; @@ -1182,9 +1180,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, 0x100000 - isa_bios_size, isa_bios, 1); - if (!isapc_ram_fw) { - memory_region_set_readonly(isa_bios, true); - } + memory_region_set_readonly(isa_bios, !isapc_ram_fw); /* map all the bios at the top of memory */ memory_region_add_subregion(rom_memory, From 848351840148f8c3b53ddf6210194506547d3ffd Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 30 Apr 2024 17:06:39 +0200 Subject: [PATCH 13/28] hw/i386: Have x86_bios_rom_init() take X86MachineState rather than MachineState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function creates and leaks two MemoryRegion objects regarding the BIOS which will be moved into X86MachineState in the next steps to avoid the leakage. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240430150643.111976-3-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/microvm.c | 2 +- hw/i386/pc_sysfw.c | 4 ++-- hw/i386/x86.c | 4 ++-- include/hw/i386/x86.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 61a772dfe6..fec63cacfa 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -278,7 +278,7 @@ static void microvm_devices_init(MicrovmMachineState *mms) default_firmware = x86_machine_is_acpi_enabled(x86ms) ? MICROVM_BIOS_FILENAME : MICROVM_QBOOT_FILENAME; - x86_bios_rom_init(MACHINE(mms), default_firmware, get_system_memory(), true); + x86_bios_rom_init(x86ms, default_firmware, get_system_memory(), true); } static void microvm_memory_init(MicrovmMachineState *mms) diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index 87b5bf59d6..59c7a81692 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -205,7 +205,7 @@ void pc_system_firmware_init(PCMachineState *pcms, BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)]; if (!pcmc->pci_enabled) { - x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, true); + x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, true); return; } @@ -226,7 +226,7 @@ void pc_system_firmware_init(PCMachineState *pcms, if (!pflash_blk[0]) { /* Machine property pflash0 not set, use ROM mode */ - x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, false); + x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, false); } else { if (kvm_enabled() && !kvm_readonly_mem_enabled()) { /* diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 2a4f3ee285..6d3c72f124 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -1128,7 +1128,7 @@ void x86_load_linux(X86MachineState *x86ms, nb_option_roms++; } -void x86_bios_rom_init(MachineState *ms, const char *default_firmware, +void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, MemoryRegion *rom_memory, bool isapc_ram_fw) { const char *bios_name; @@ -1138,7 +1138,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, ssize_t ret; /* BIOS load */ - bios_name = ms->firmware ?: default_firmware; + bios_name = MACHINE(x86ms)->firmware ?: default_firmware; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = get_image_size(filename); diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index 4dc30dcb4d..cb07618d19 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -116,7 +116,7 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); -void x86_bios_rom_init(MachineState *ms, const char *default_firmware, +void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, MemoryRegion *rom_memory, bool isapc_ram_fw); void x86_load_linux(X86MachineState *x86ms, From 32d3ee87a17fc91e981a23dba94855bff89f5920 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 May 2024 19:55:04 +0200 Subject: [PATCH 14/28] hw/i386/x86: Don't leak "isa-bios" memory regions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the leaking in x86_bios_rom_init() and pc_isa_bios_init() by adding an "isa_bios" attribute to X86MachineState. Suggested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Message-ID: <20240508175507.22270-4-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc_sysfw.c | 7 +++---- hw/i386/x86.c | 9 ++++----- include/hw/i386/x86.h | 7 +++++++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index 59c7a81692..82d37cb376 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -40,11 +40,10 @@ #define FLASH_SECTOR_SIZE 4096 -static void pc_isa_bios_init(MemoryRegion *rom_memory, +static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory, MemoryRegion *flash_mem) { int isa_bios_size; - MemoryRegion *isa_bios; uint64_t flash_size; void *flash_ptr, *isa_bios_ptr; @@ -52,7 +51,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory, /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = MIN(flash_size, 128 * KiB); - isa_bios = g_malloc(sizeof(*isa_bios)); memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size, &error_fatal); memory_region_add_subregion_overlap(rom_memory, @@ -136,6 +134,7 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms) static void pc_system_flash_map(PCMachineState *pcms, MemoryRegion *rom_memory) { + X86MachineState *x86ms = X86_MACHINE(pcms); hwaddr total_size = 0; int i; BlockBackend *blk; @@ -185,7 +184,7 @@ static void pc_system_flash_map(PCMachineState *pcms, if (i == 0) { flash_mem = pflash_cfi01_get_memory(system_flash); - pc_isa_bios_init(rom_memory, flash_mem); + pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem); /* Encrypt the pflash boot ROM */ if (sev_enabled()) { diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 6d3c72f124..457e8a34a5 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -1133,7 +1133,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, { const char *bios_name; char *filename; - MemoryRegion *bios, *isa_bios; + MemoryRegion *bios; int bios_size, isa_bios_size; ssize_t ret; @@ -1173,14 +1173,13 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = MIN(bios_size, 128 * KiB); - isa_bios = g_malloc(sizeof(*isa_bios)); - memory_region_init_alias(isa_bios, NULL, "isa-bios", bios, + memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", bios, bios_size - isa_bios_size, isa_bios_size); memory_region_add_subregion_overlap(rom_memory, 0x100000 - isa_bios_size, - isa_bios, + &x86ms->isa_bios, 1); - memory_region_set_readonly(isa_bios, !isapc_ram_fw); + memory_region_set_readonly(&x86ms->isa_bios, !isapc_ram_fw); /* map all the bios at the top of memory */ memory_region_add_subregion(rom_memory, diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index cb07618d19..a07de79167 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -18,6 +18,7 @@ #define HW_I386_X86_H #include "exec/hwaddr.h" +#include "exec/memory.h" #include "hw/boards.h" #include "hw/intc/ioapic.h" @@ -52,6 +53,12 @@ struct X86MachineState { GMappedFile *initrd_mapped_file; HotplugHandler *acpi_dev; + /* + * Map the upper 128 KiB of the BIOS just underneath the 1 MiB address + * boundary. + */ + MemoryRegion isa_bios; + /* RAM information (sizes, addresses, configuration): */ ram_addr_t below_4g_mem_size, above_4g_mem_size; From 865d95321ffc8d9941e33000b10140550f094556 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 May 2024 19:55:05 +0200 Subject: [PATCH 15/28] hw/i386/x86: Don't leak "pc.bios" memory region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the leaking in x86_bios_rom_init() by adding a "bios" attribute to X86MachineState. Note that it is only used in the -bios case. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Message-ID: <20240508175507.22270-5-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/x86.c | 13 ++++++------- include/hw/i386/x86.h | 6 ++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 457e8a34a5..29167de97d 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -1133,7 +1133,6 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, { const char *bios_name; char *filename; - MemoryRegion *bios; int bios_size, isa_bios_size; ssize_t ret; @@ -1149,8 +1148,8 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, (bios_size % 65536) != 0) { goto bios_error; } - bios = g_malloc(sizeof(*bios)); - memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal); + memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size, + &error_fatal); if (sev_enabled()) { /* * The concept of a "reset" simply doesn't exist for @@ -1159,11 +1158,11 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, * the firmware as rom to properly re-initialize on reset. * Just go for a straight file load instead. */ - void *ptr = memory_region_get_ram_ptr(bios); + void *ptr = memory_region_get_ram_ptr(&x86ms->bios); load_image_size(filename, ptr, bios_size); x86_firmware_configure(ptr, bios_size); } else { - memory_region_set_readonly(bios, !isapc_ram_fw); + memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw); ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); if (ret != 0) { goto bios_error; @@ -1173,7 +1172,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = MIN(bios_size, 128 * KiB); - memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", bios, + memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", &x86ms->bios, bios_size - isa_bios_size, isa_bios_size); memory_region_add_subregion_overlap(rom_memory, 0x100000 - isa_bios_size, @@ -1184,7 +1183,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, /* map all the bios at the top of memory */ memory_region_add_subregion(rom_memory, (uint32_t)(-bios_size), - bios); + &x86ms->bios); return; bios_error: diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index a07de79167..55c6809ae0 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -53,6 +53,12 @@ struct X86MachineState { GMappedFile *initrd_mapped_file; HotplugHandler *acpi_dev; + /* + * Map the whole BIOS just underneath the 4 GiB address boundary. Only used + * in the ROM (-bios) case. + */ + MemoryRegion bios; + /* * Map the upper 128 KiB of the BIOS just underneath the 1 MiB address * boundary. From 5c5ffec12c30d2017cbdee6798f54d8fad3f9656 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Wed, 8 May 2024 19:55:06 +0200 Subject: [PATCH 16/28] hw/i386/x86: Extract x86_isa_bios_init() from x86_bios_rom_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function is inspired by pc_isa_bios_init() and should eventually replace it. Using x86_isa_bios_init() rather than pc_isa_bios_init() fixes pflash commands to work in the isa-bios region. While at it convert the magic number 0x100000 (== 1MiB) to increase readability. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Bernhard Beschow Message-ID: <20240508175507.22270-6-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/x86.c | 25 ++++++++++++++++--------- include/hw/i386/x86.h | 2 ++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 29167de97d..c61f4ebfa6 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -1128,12 +1128,25 @@ void x86_load_linux(X86MachineState *x86ms, nb_option_roms++; } +void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory, + MemoryRegion *bios, bool read_only) +{ + uint64_t bios_size = memory_region_size(bios); + uint64_t isa_bios_size = MIN(bios_size, 128 * KiB); + + memory_region_init_alias(isa_bios, NULL, "isa-bios", bios, + bios_size - isa_bios_size, isa_bios_size); + memory_region_add_subregion_overlap(isa_memory, 1 * MiB - isa_bios_size, + isa_bios, 1); + memory_region_set_readonly(isa_bios, read_only); +} + void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, MemoryRegion *rom_memory, bool isapc_ram_fw) { const char *bios_name; char *filename; - int bios_size, isa_bios_size; + int bios_size; ssize_t ret; /* BIOS load */ @@ -1171,14 +1184,8 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, g_free(filename); /* map the last 128KB of the BIOS in ISA space */ - isa_bios_size = MIN(bios_size, 128 * KiB); - memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", &x86ms->bios, - bios_size - isa_bios_size, isa_bios_size); - memory_region_add_subregion_overlap(rom_memory, - 0x100000 - isa_bios_size, - &x86ms->isa_bios, - 1); - memory_region_set_readonly(&x86ms->isa_bios, !isapc_ram_fw); + x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios, + !isapc_ram_fw); /* map all the bios at the top of memory */ memory_region_add_subregion(rom_memory, diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index 55c6809ae0..d7b7d3f3ce 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -129,6 +129,8 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); +void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory, + MemoryRegion *bios, bool read_only); void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, MemoryRegion *rom_memory, bool isapc_ram_fw); From f94b1871aa6ca64114dadea877ee6518809ddb9d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 5 May 2024 18:14:41 +0100 Subject: [PATCH 17/28] hw/usb/dev-network: Remove unused struct 'rndis_config_parameter' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As far as I can tell it was never used. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240505171444.333302-5-dave@treblig.org> Signed-off-by: Philippe Mathieu-Daudé --- hw/usb/dev-network.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index 2c33e36cad..d00d68b21d 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -475,14 +475,6 @@ struct rndis_packet_msg_type { le32 Reserved; }; -struct rndis_config_parameter { - le32 ParameterNameOffset; - le32 ParameterNameLength; - le32 ParameterType; - le32 ParameterValueOffset; - le32 ParameterValueLength; -}; - /* implementation specific */ enum rndis_state { From 1f3cabd3409c4eef0174f58211c0ced196f11446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?In=C3=A8s=20Varhol?= Date: Tue, 7 May 2024 20:55:39 +0200 Subject: [PATCH 18/28] hw/gpio: Handle clock migration in STM32L4x5 gpios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STM32L4x5 GPIO wasn't migrating its clock. Signed-off-by: Inès Varhol Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240507185854.34572-3-ines.varhol@telecom-paris.fr> Signed-off-by: Philippe Mathieu-Daudé --- hw/gpio/stm32l4x5_gpio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c index 71bf5fddb2..30d8d6cba4 100644 --- a/hw/gpio/stm32l4x5_gpio.c +++ b/hw/gpio/stm32l4x5_gpio.c @@ -20,6 +20,7 @@ #include "qemu/log.h" #include "hw/gpio/stm32l4x5_gpio.h" #include "hw/irq.h" +#include "hw/clock.h" #include "hw/qdev-clock.h" #include "hw/qdev-properties.h" #include "qapi/visitor.h" @@ -426,8 +427,8 @@ static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp) static const VMStateDescription vmstate_stm32l4x5_gpio = { .name = TYPE_STM32L4X5_GPIO, - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .fields = (VMStateField[]){ VMSTATE_UINT32(moder, Stm32l4x5GpioState), VMSTATE_UINT32(otyper, Stm32l4x5GpioState), @@ -441,6 +442,7 @@ static const VMStateDescription vmstate_stm32l4x5_gpio = { VMSTATE_UINT32(ascr, Stm32l4x5GpioState), VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState), VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState), + VMSTATE_CLOCK(clk, Stm32l4x5GpioState), VMSTATE_END_OF_LIST() } }; From ed95bdd1e52a0a5f4f8e07468f6c1aa766efc4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 7 May 2024 14:33:32 +0200 Subject: [PATCH 19/28] hw/ppc: Deprecate 'ref405ep' machine and 405 CPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'ref405ep' machine and PPC 405 CPU have no known users, firmware images are not available, OpenWRT dropped support in 2019, U-Boot in 2017, Linux also is dropping support in 2024. It is time to let go of this ancient hardware and focus on newer CPUs and platforms. Signed-off-by: Cédric Le Goater Acked-by: Nicholas Piggin Message-ID: <20240507123332.641708-1-clg@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- docs/about/deprecated.rst | 8 ++++++++ hw/ppc/ppc405_boards.c | 1 + 2 files changed, 9 insertions(+) diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 03f8b1b655..e22acb17f2 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -258,6 +258,14 @@ dropping the ``cheetah`` OMAP1 board, because we don't have any test images for it and don't know of anybody who does; the ``sx1`` and ``sx1-v1`` OMAP1 machines remain supported for now. +PPC 405 ``ref405ep`` machine (since 9.1) +'''''''''''''''''''''''''''''''''''''''' + +The ``ref405ep`` machine and PPC 405 CPU have no known users, firmware +images are not available, OpenWRT dropped support in 2019, U-Boot in +2017, Linux also is dropping support in 2024. It is time to let go of +this ancient hardware and focus on newer CPUs and platforms. + Backend options --------------- diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index 4092ebc1ab..c44e7ed162 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -350,6 +350,7 @@ static void ppc405_machine_class_init(ObjectClass *oc, void *data) mc->init = ppc405_init; mc->default_ram_size = 128 * MiB; mc->default_ram_id = "ppc405.ram"; + mc->deprecation_reason = "machine is old and unmaintained"; } static const TypeInfo ppc405_machine_type = { From 72674db080bcdf2fd66b2a538379ee6000f5b113 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 7 May 2024 16:51:35 +0200 Subject: [PATCH 20/28] hw/loongarch: move memory map to boot.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that it can be used even if virt.c is not included in the build, as is the case for --without-default-devices. Signed-off-by: Paolo Bonzini Acked-by: Richard Henderson Message-ID: <20240507145135.270803-1-pbonzini@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- .gitlab-ci.d/buildtest.yml | 2 +- hw/loongarch/boot.c | 3 +++ hw/loongarch/virt.c | 3 --- include/hw/loongarch/boot.h | 10 ++++++++++ include/hw/loongarch/virt.h | 10 ---------- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index e9402a68a7..bab6194564 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -650,7 +650,7 @@ build-tci: # Check our reduced build configurations # requires libfdt: aarch64, arm, i386, loongarch64, microblaze, microblazeel, # mips64el, or1k, ppc, ppc64, riscv32, riscv64, rx, x86_64 -# does not build without boards: i386, loongarch64, s390x, sh4, sh4eb, x86_64 +# does not build without boards: i386, s390x, sh4, sh4eb, x86_64 build-without-defaults: extends: .native_build_job_template needs: diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 7d1630b2e7..03f6301a77 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -15,6 +15,9 @@ #include "sysemu/reset.h" #include "sysemu/qtest.h" +struct memmap_entry *memmap_table; +unsigned memmap_entries; + ram_addr_t initrd_offset; uint64_t initrd_size; diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index c0999878df..504e1fb349 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -516,9 +516,6 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque) acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS); } -struct memmap_entry *memmap_table; -unsigned memmap_entries; - static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) { /* Ensure there are no duplicate entries. */ diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h index 4ebcc89dcf..b3b870df1f 100644 --- a/include/hw/loongarch/boot.h +++ b/include/hw/loongarch/boot.h @@ -104,6 +104,16 @@ struct loongarch_boot_info { uint64_t a0, a1, a2; }; +extern struct memmap_entry *memmap_table; +extern unsigned memmap_entries; + +struct memmap_entry { + uint64_t address; + uint64_t length; + uint32_t type; + uint32_t reserved; +}; + void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info); #endif /* HW_LOONGARCH_BOOT_H */ diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 4e14bf6060..fdbd2b146f 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -37,16 +37,6 @@ #define FDT_BASE 0x100000 -extern struct memmap_entry *memmap_table; -extern unsigned memmap_entries; - -struct memmap_entry { - uint64_t address; - uint64_t length; - uint32_t type; - uint32_t reserved; -}; - struct LoongArchMachineState { /*< private >*/ MachineState parent_obj; From 54c52ec719fb8c83bbde54cb87b58688ab27c166 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Tue, 7 May 2024 10:22:39 +0800 Subject: [PATCH 21/28] hw/loongarch/virt: Fix memory leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The char pointer 'ramName' point to a block of memory, but never free it. Use 'g_autofree' to automatically free it. Resolves: Coverity CID 1544773 Fixes: 0cf1478d6 ("hw/loongarch: Add numa support") Signed-off-by: Song Gao Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240507022239.3113987-1-gaosong@loongson.cn> Signed-off-by: Philippe Mathieu-Daudé --- hw/loongarch/virt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 504e1fb349..69924a8734 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -884,7 +884,6 @@ static void loongarch_init(MachineState *machine) const CPUArchIdList *possible_cpus; MachineClass *mc = MACHINE_GET_CLASS(machine); CPUState *cpu; - char *ramName = NULL; if (!cpu_model) { cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); @@ -943,7 +942,7 @@ static void loongarch_init(MachineState *machine) for (i = 1; i < nb_numa_nodes; i++) { MemoryRegion *nodemem = g_new(MemoryRegion, 1); - ramName = g_strdup_printf("loongarch.node%d.ram", i); + g_autofree char *ramName = g_strdup_printf("loongarch.node%d.ram", i); memory_region_init_alias(nodemem, NULL, ramName, machine->ram, offset, numa_info[i].node_mem); memory_region_add_subregion(address_space_mem, phyAddr, nodemem); From df0d93c1e20db0c2b683a823a8e95208f5dc09ff Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Wed, 8 May 2024 11:11:06 +0800 Subject: [PATCH 22/28] hw/loongarch: Rename LOONGARCH_MACHINE with LOONGARCH_VIRT_MACHINE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On LoongArch system, there is only virt machine type now, name LOONGARCH_MACHINE is confused, rename it with LOONGARCH_VIRT_MACHINE. Machine name about Other real hw boards can be added in future. Signed-off-by: Bibo Mao Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240508031110.2507477-2-maobibo@loongson.cn> Signed-off-by: Philippe Mathieu-Daudé --- hw/loongarch/acpi-build.c | 8 ++++---- hw/loongarch/boot.c | 2 +- hw/loongarch/virt.c | 19 +++++++++---------- include/hw/loongarch/virt.h | 4 ++-- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index e5ab1080af..c7150cc0c4 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -167,7 +167,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) int i, arch_id, node_id; uint64_t mem_len, mem_base; int nb_numa_nodes = machine->numa_state->num_nodes; - LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); MachineClass *mc = MACHINE_GET_CLASS(lams); const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine); AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id, @@ -279,7 +279,7 @@ static void build_la_ged_aml(Aml *dsdt, MachineState *machine) { uint32_t event; - LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); build_ged_aml(dsdt, "\\_SB."GED_DEVICE, HOTPLUG_HANDLER(lams->acpi_ged), @@ -391,7 +391,7 @@ static void build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) { Aml *dsdt, *scope, *pkg; - LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id, .oem_table_id = lams->oem_table_id }; @@ -421,7 +421,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) static void acpi_build(AcpiBuildTables *tables, MachineState *machine) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); GArray *table_offsets; AcpiFadtData fadt_data; unsigned facs, rsdt, dsdt; diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 03f6301a77..e37512729d 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -319,7 +319,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(ms); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(ms); int i; /* register reset function */ diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 69924a8734..d7de80baf8 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -877,7 +877,7 @@ static void loongarch_init(MachineState *machine) ram_addr_t ram_size = machine->ram_size; uint64_t highram_size = 0, phyAddr = 0; MemoryRegion *address_space_mem = get_system_memory(); - LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); int nb_numa_nodes = machine->numa_state->num_nodes; NodeInfo *numa_info = machine->numa_state->nodes; int i; @@ -1028,7 +1028,7 @@ bool loongarch_is_acpi_enabled(LoongArchMachineState *lams) static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj); OnOffAuto acpi = lams->acpi; visit_type_OnOffAuto(v, name, &acpi, errp); @@ -1037,14 +1037,14 @@ static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj); visit_type_OnOffAuto(v, name, &lams->acpi, errp); } static void loongarch_machine_initfn(Object *obj) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj); lams->acpi = ON_OFF_AUTO_AUTO; lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); @@ -1076,7 +1076,7 @@ static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, static void virt_mem_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); /* the acpi ged is always exist */ hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev, @@ -1094,7 +1094,7 @@ static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev, static void virt_mem_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp); pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams)); @@ -1112,7 +1112,7 @@ static void virt_machine_device_unplug(HotplugHandler *hotplug_dev, static void virt_mem_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); pc_dimm_plug(PC_DIMM(dev), MACHINE(lams)); hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged), @@ -1122,7 +1122,7 @@ static void virt_mem_plug(HotplugHandler *hotplug_dev, static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); MachineClass *mc = MACHINE_GET_CLASS(lams); if (device_is_dynamic_sysbus(mc, dev)) { @@ -1204,7 +1204,6 @@ static void loongarch_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); - mc->desc = "Loongson-3A5000 LS7A1000 machine"; mc->init = loongarch_init; mc->default_ram_size = 1 * GiB; mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464"); @@ -1241,7 +1240,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data) static const TypeInfo loongarch_machine_types[] = { { - .name = TYPE_LOONGARCH_MACHINE, + .name = TYPE_LOONGARCH_VIRT_MACHINE, .parent = TYPE_MACHINE, .instance_size = sizeof(LoongArchMachineState), .class_init = loongarch_class_init, diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index fdbd2b146f..5b1416d7bc 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -63,8 +63,8 @@ struct LoongArchMachineState { struct loongarch_boot_info bootinfo; }; -#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") -OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE) +#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") +OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_VIRT_MACHINE) bool loongarch_is_acpi_enabled(LoongArchMachineState *lams); void loongarch_acpi_setup(LoongArchMachineState *lams); #endif From d804ad98f51cc6ae795ff9c9890db66bae513214 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Wed, 8 May 2024 11:11:07 +0800 Subject: [PATCH 23/28] hw/loongarch: Rename LoongArchMachineState with LoongArchVirtMachineState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename LoongArchMachineState with LoongArchVirtMachineState, and change variable name LoongArchMachineState *lams with LoongArchVirtMachineState *lvms. Rename function specific for virtmachine loongarch_xxx() with virt_xxx(). However some common functions keep unchanged such as loongarch_acpi_setup()/loongarch_load_kernel(), since there functions can be used for real hw boards. Signed-off-by: Bibo Mao Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240508031110.2507477-3-maobibo@loongson.cn> Signed-off-by: Philippe Mathieu-Daudé --- hw/loongarch/acpi-build.c | 89 +++++----- hw/loongarch/boot.c | 10 +- hw/loongarch/fw_cfg.c | 2 +- hw/loongarch/fw_cfg.h | 2 +- hw/loongarch/virt.c | 340 ++++++++++++++++++------------------ include/hw/loongarch/virt.h | 7 +- 6 files changed, 226 insertions(+), 224 deletions(-) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index c7150cc0c4..5ef010d4da 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -105,14 +105,15 @@ build_facs(GArray *table_data) /* build MADT */ static void -build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) +build_madt(GArray *table_data, BIOSLinker *linker, + LoongArchVirtMachineState *lvms) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); MachineClass *mc = MACHINE_GET_CLASS(ms); const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); int i, arch_id; - AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id, - .oem_table_id = lams->oem_table_id }; + AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lvms->oem_id, + .oem_table_id = lvms->oem_table_id }; acpi_table_begin(&table, table_data); @@ -167,11 +168,11 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) int i, arch_id, node_id; uint64_t mem_len, mem_base; int nb_numa_nodes = machine->numa_state->num_nodes; - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); - MachineClass *mc = MACHINE_GET_CLASS(lams); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); + MachineClass *mc = MACHINE_GET_CLASS(lvms); const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine); - AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id, - .oem_table_id = lams->oem_table_id }; + AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lvms->oem_id, + .oem_table_id = lvms->oem_table_id }; acpi_table_begin(&table, table_data); build_append_int_noprefix(table_data, 1, 4); /* Reserved */ @@ -279,13 +280,13 @@ static void build_la_ged_aml(Aml *dsdt, MachineState *machine) { uint32_t event; - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); build_ged_aml(dsdt, "\\_SB."GED_DEVICE, - HOTPLUG_HANDLER(lams->acpi_ged), + HOTPLUG_HANDLER(lvms->acpi_ged), VIRT_SCI_IRQ, AML_SYSTEM_MEMORY, VIRT_GED_EVT_ADDR); - event = object_property_get_uint(OBJECT(lams->acpi_ged), + event = object_property_get_uint(OBJECT(lvms->acpi_ged), "ged-event", &error_abort); if (event & ACPI_GED_MEM_HOTPLUG_EVT) { build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL, @@ -295,7 +296,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine) acpi_dsdt_add_power_button(dsdt); } -static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) +static void build_pci_device_aml(Aml *scope, LoongArchVirtMachineState *lvms) { struct GPEXConfig cfg = { .mmio64.base = VIRT_PCI_MEM_BASE, @@ -305,13 +306,13 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) .ecam.base = VIRT_PCI_CFG_BASE, .ecam.size = VIRT_PCI_CFG_SIZE, .irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS, - .bus = lams->pci_bus, + .bus = lvms->pci_bus, }; acpi_dsdt_add_gpex(scope, &cfg); } -static void build_flash_aml(Aml *scope, LoongArchMachineState *lams) +static void build_flash_aml(Aml *scope, LoongArchVirtMachineState *lvms) { Aml *dev, *crs; MemoryRegion *flash_mem; @@ -322,11 +323,11 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams) hwaddr flash1_base; hwaddr flash1_size; - flash_mem = pflash_cfi01_get_memory(lams->flash[0]); + flash_mem = pflash_cfi01_get_memory(lvms->flash[0]); flash0_base = flash_mem->addr; flash0_size = memory_region_size(flash_mem); - flash_mem = pflash_cfi01_get_memory(lams->flash[1]); + flash_mem = pflash_cfi01_get_memory(lvms->flash[1]); flash1_base = flash_mem->addr; flash1_size = memory_region_size(flash_mem); @@ -352,7 +353,7 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams) } #ifdef CONFIG_TPM -static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms) +static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms) { PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; @@ -391,18 +392,18 @@ static void build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) { Aml *dsdt, *scope, *pkg; - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); - AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id, - .oem_table_id = lams->oem_table_id }; + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); + AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id, + .oem_table_id = lvms->oem_table_id }; acpi_table_begin(&table, table_data); dsdt = init_aml_allocator(); build_uart_device_aml(dsdt); - build_pci_device_aml(dsdt, lams); + build_pci_device_aml(dsdt, lvms); build_la_ged_aml(dsdt, machine); - build_flash_aml(dsdt, lams); + build_flash_aml(dsdt, lvms); #ifdef CONFIG_TPM - acpi_dsdt_add_tpm(dsdt, lams); + acpi_dsdt_add_tpm(dsdt, lvms); #endif /* System State Package */ scope = aml_scope("\\"); @@ -421,7 +422,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) static void acpi_build(AcpiBuildTables *tables, MachineState *machine) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); GArray *table_offsets; AcpiFadtData fadt_data; unsigned facs, rsdt, dsdt; @@ -455,14 +456,14 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) 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); + lvms->oem_id, lvms->oem_table_id); acpi_add_table(table_offsets, tables_blob); - build_madt(tables_blob, tables->linker, lams); + build_madt(tables_blob, tables->linker, lvms); acpi_add_table(table_offsets, tables_blob); build_pptt(tables_blob, tables->linker, machine, - lams->oem_id, lams->oem_table_id); + lvms->oem_id, lvms->oem_table_id); acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, machine); @@ -470,13 +471,13 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) if (machine->numa_state->num_nodes) { if (machine->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker, machine, lams->oem_id, - lams->oem_table_id); + build_slit(tables_blob, tables->linker, machine, lvms->oem_id, + lvms->oem_table_id); } if (machine->numa_state->hmat_enabled) { acpi_add_table(table_offsets, tables_blob); build_hmat(tables_blob, tables->linker, machine->numa_state, - lams->oem_id, lams->oem_table_id); + lvms->oem_id, lvms->oem_table_id); } } @@ -486,8 +487,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) .base = cpu_to_le64(VIRT_PCI_CFG_BASE), .size = cpu_to_le64(VIRT_PCI_CFG_SIZE), }; - build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id, - lams->oem_table_id); + build_mcfg(tables_blob, tables->linker, &mcfg, lvms->oem_id, + lvms->oem_table_id); } #ifdef CONFIG_TPM @@ -495,8 +496,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { acpi_add_table(table_offsets, tables_blob); build_tpm2(tables_blob, tables->linker, - tables->tcpalog, lams->oem_id, - lams->oem_table_id); + tables->tcpalog, lvms->oem_id, + lvms->oem_table_id); } #endif /* Add tables supplied by user (if any) */ @@ -510,13 +511,13 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) /* 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); + lvms->oem_id, lvms->oem_table_id); /* RSDP is in FSEG memory, so allocate it separately */ { AcpiRsdpData rsdp_data = { .revision = 0, - .oem_id = lams->oem_id, + .oem_id = lvms->oem_id, .xsdt_tbl_offset = NULL, .rsdt_tbl_offset = &rsdt, }; @@ -593,17 +594,25 @@ static const VMStateDescription vmstate_acpi_build = { }, }; -void loongarch_acpi_setup(LoongArchMachineState *lams) +static bool loongarch_is_acpi_enabled(LoongArchVirtMachineState *lvms) +{ + if (lvms->acpi == ON_OFF_AUTO_OFF) { + return false; + } + return true; +} + +void loongarch_acpi_setup(LoongArchVirtMachineState *lvms) { AcpiBuildTables tables; AcpiBuildState *build_state; - if (!lams->fw_cfg) { + if (!lvms->fw_cfg) { ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); return; } - if (!loongarch_is_acpi_enabled(lams)) { + if (!loongarch_is_acpi_enabled(lvms)) { ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); return; } @@ -611,7 +620,7 @@ void loongarch_acpi_setup(LoongArchMachineState *lams) build_state = g_malloc0(sizeof *build_state); acpi_build_tables_init(&tables); - acpi_build(&tables, MACHINE(lams)); + acpi_build(&tables, MACHINE(lvms)); /* Now expose it all to Guest */ build_state->table_mr = acpi_add_rom_blob(acpi_build_update, diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index e37512729d..b8e1aa18d5 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -259,10 +259,10 @@ static void fw_cfg_add_kernel_info(struct loongarch_boot_info *info, } } -static void loongarch_firmware_boot(LoongArchMachineState *lams, +static void loongarch_firmware_boot(LoongArchVirtMachineState *lvms, struct loongarch_boot_info *info) { - fw_cfg_add_kernel_info(info, lams->fw_cfg); + fw_cfg_add_kernel_info(info, lvms->fw_cfg); } static void init_boot_rom(struct loongarch_boot_info *info, void *p) @@ -319,7 +319,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(ms); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms); int i; /* register reset function */ @@ -331,8 +331,8 @@ void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) info->kernel_cmdline = ms->kernel_cmdline; info->initrd_filename = ms->initrd_filename; - if (lams->bios_loaded) { - loongarch_firmware_boot(lams, info); + if (lvms->bios_loaded) { + loongarch_firmware_boot(lvms, info); } else { loongarch_direct_kernel_boot(info); } diff --git a/hw/loongarch/fw_cfg.c b/hw/loongarch/fw_cfg.c index f15a17416c..35aeb2decb 100644 --- a/hw/loongarch/fw_cfg.c +++ b/hw/loongarch/fw_cfg.c @@ -17,7 +17,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device, 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 *virt_fw_cfg_init(ram_addr_t ram_size, MachineState *ms) { FWCfgState *fw_cfg; int max_cpus = ms->smp.max_cpus; diff --git a/hw/loongarch/fw_cfg.h b/hw/loongarch/fw_cfg.h index 7c0de4db4a..27ee68286e 100644 --- a/hw/loongarch/fw_cfg.h +++ b/hw/loongarch/fw_cfg.h @@ -11,5 +11,5 @@ #include "hw/boards.h" #include "hw/nvram/fw_cfg.h" -FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms); +FWCfgState *virt_fw_cfg_init(ram_addr_t ram_size, MachineState *ms); #endif diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index d7de80baf8..51e0aca39b 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -46,7 +46,7 @@ #include "hw/block/flash.h" #include "qemu/error-report.h" -static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams, +static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms, const char *name, const char *alias_prop_name) { @@ -61,16 +61,16 @@ static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams, qdev_prop_set_uint16(dev, "id2", 0x00); qdev_prop_set_uint16(dev, "id3", 0x00); qdev_prop_set_string(dev, "name", name); - object_property_add_child(OBJECT(lams), name, OBJECT(dev)); - object_property_add_alias(OBJECT(lams), alias_prop_name, + object_property_add_child(OBJECT(lvms), name, OBJECT(dev)); + object_property_add_alias(OBJECT(lvms), alias_prop_name, OBJECT(dev), "drive"); return PFLASH_CFI01(dev); } -static void virt_flash_create(LoongArchMachineState *lams) +static void virt_flash_create(LoongArchVirtMachineState *lvms) { - lams->flash[0] = virt_flash_create1(lams, "virt.flash0", "pflash0"); - lams->flash[1] = virt_flash_create1(lams, "virt.flash1", "pflash1"); + lvms->flash[0] = virt_flash_create1(lvms, "virt.flash0", "pflash0"); + lvms->flash[1] = virt_flash_create1(lvms, "virt.flash1", "pflash1"); } static void virt_flash_map1(PFlashCFI01 *flash, @@ -96,20 +96,20 @@ static void virt_flash_map1(PFlashCFI01 *flash, sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); } -static void virt_flash_map(LoongArchMachineState *lams, +static void virt_flash_map(LoongArchVirtMachineState *lvms, MemoryRegion *sysmem) { - PFlashCFI01 *flash0 = lams->flash[0]; - PFlashCFI01 *flash1 = lams->flash[1]; + PFlashCFI01 *flash0 = lvms->flash[0]; + PFlashCFI01 *flash1 = lvms->flash[1]; virt_flash_map1(flash0, VIRT_FLASH0_BASE, VIRT_FLASH0_SIZE, sysmem); virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem); } -static void fdt_add_cpuic_node(LoongArchMachineState *lams, +static void fdt_add_cpuic_node(LoongArchVirtMachineState *lvms, uint32_t *cpuintc_phandle) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); char *nodename; *cpuintc_phandle = qemu_fdt_alloc_phandle(ms->fdt); @@ -123,11 +123,11 @@ static void fdt_add_cpuic_node(LoongArchMachineState *lams, g_free(nodename); } -static void fdt_add_eiointc_node(LoongArchMachineState *lams, +static void fdt_add_eiointc_node(LoongArchVirtMachineState *lvms, uint32_t *cpuintc_phandle, uint32_t *eiointc_phandle) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); char *nodename; hwaddr extioi_base = APIC_BASE; hwaddr extioi_size = EXTIOI_SIZE; @@ -148,11 +148,11 @@ static void fdt_add_eiointc_node(LoongArchMachineState *lams, g_free(nodename); } -static void fdt_add_pch_pic_node(LoongArchMachineState *lams, +static void fdt_add_pch_pic_node(LoongArchVirtMachineState *lvms, uint32_t *eiointc_phandle, uint32_t *pch_pic_phandle) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); char *nodename; hwaddr pch_pic_base = VIRT_PCH_REG_BASE; hwaddr pch_pic_size = VIRT_PCH_REG_SIZE; @@ -173,11 +173,11 @@ static void fdt_add_pch_pic_node(LoongArchMachineState *lams, g_free(nodename); } -static void fdt_add_pch_msi_node(LoongArchMachineState *lams, +static void fdt_add_pch_msi_node(LoongArchVirtMachineState *lvms, uint32_t *eiointc_phandle, uint32_t *pch_msi_phandle) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); char *nodename; hwaddr pch_msi_base = VIRT_PCH_MSI_ADDR_LOW; hwaddr pch_msi_size = VIRT_PCH_MSI_SIZE; @@ -201,9 +201,9 @@ static void fdt_add_pch_msi_node(LoongArchMachineState *lams, g_free(nodename); } -static void fdt_add_flash_node(LoongArchMachineState *lams) +static void fdt_add_flash_node(LoongArchVirtMachineState *lvms) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); char *nodename; MemoryRegion *flash_mem; @@ -213,11 +213,11 @@ static void fdt_add_flash_node(LoongArchMachineState *lams) hwaddr flash1_base; hwaddr flash1_size; - flash_mem = pflash_cfi01_get_memory(lams->flash[0]); + flash_mem = pflash_cfi01_get_memory(lvms->flash[0]); flash0_base = flash_mem->addr; flash0_size = memory_region_size(flash_mem); - flash_mem = pflash_cfi01_get_memory(lams->flash[1]); + flash_mem = pflash_cfi01_get_memory(lvms->flash[1]); flash1_base = flash_mem->addr; flash1_size = memory_region_size(flash_mem); @@ -231,13 +231,13 @@ static void fdt_add_flash_node(LoongArchMachineState *lams) g_free(nodename); } -static void fdt_add_rtc_node(LoongArchMachineState *lams, +static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, uint32_t *pch_pic_phandle) { char *nodename; hwaddr base = VIRT_RTC_REG_BASE; hwaddr size = VIRT_RTC_LEN; - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); nodename = g_strdup_printf("/rtc@%" PRIx64, base); qemu_fdt_add_subnode(ms->fdt, nodename); @@ -251,13 +251,13 @@ static void fdt_add_rtc_node(LoongArchMachineState *lams, g_free(nodename); } -static void fdt_add_uart_node(LoongArchMachineState *lams, +static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, uint32_t *pch_pic_phandle) { char *nodename; hwaddr base = VIRT_UART_BASE; hwaddr size = VIRT_UART_SIZE; - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); nodename = g_strdup_printf("/serial@%" PRIx64, base); qemu_fdt_add_subnode(ms->fdt, nodename); @@ -272,11 +272,11 @@ static void fdt_add_uart_node(LoongArchMachineState *lams, g_free(nodename); } -static void create_fdt(LoongArchMachineState *lams) +static void create_fdt(LoongArchVirtMachineState *lvms) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); - ms->fdt = create_device_tree(&lams->fdt_size); + ms->fdt = create_device_tree(&lvms->fdt_size); if (!ms->fdt) { error_report("create_device_tree() failed"); exit(1); @@ -290,10 +290,10 @@ static void create_fdt(LoongArchMachineState *lams) qemu_fdt_add_subnode(ms->fdt, "/chosen"); } -static void fdt_add_cpu_nodes(const LoongArchMachineState *lams) +static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms) { int num; - const MachineState *ms = MACHINE(lams); + const MachineState *ms = MACHINE(lvms); int smp_cpus = ms->smp.cpus; qemu_fdt_add_subnode(ms->fdt, "/cpus"); @@ -347,11 +347,11 @@ static void fdt_add_cpu_nodes(const LoongArchMachineState *lams) } } -static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams) +static void fdt_add_fw_cfg_node(const LoongArchVirtMachineState *lvms) { char *nodename; hwaddr base = VIRT_FWCFG_BASE; - const MachineState *ms = MACHINE(lams); + const MachineState *ms = MACHINE(lvms); nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); qemu_fdt_add_subnode(ms->fdt, nodename); @@ -363,7 +363,7 @@ static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams) g_free(nodename); } -static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams, +static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms, char *nodename, uint32_t *pch_pic_phandle) { @@ -371,7 +371,7 @@ static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams, uint32_t irq_map_stride = 0; uint32_t full_irq_map[GPEX_NUM_IRQS *GPEX_NUM_IRQS * 10] = {}; uint32_t *irq_map = full_irq_map; - const MachineState *ms = MACHINE(lams); + const MachineState *ms = MACHINE(lvms); /* This code creates a standard swizzle of interrupts such that * each device's first interrupt is based on it's PCI_SLOT number. @@ -416,7 +416,7 @@ static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams, 0x1800, 0, 0, 0x7); } -static void fdt_add_pcie_node(const LoongArchMachineState *lams, +static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, uint32_t *pch_pic_phandle, uint32_t *pch_msi_phandle) { @@ -429,7 +429,7 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams, hwaddr size_pcie = VIRT_PCI_CFG_SIZE; hwaddr base = base_pcie; - const MachineState *ms = MACHINE(lams); + const MachineState *ms = MACHINE(lvms); nodename = g_strdup_printf("/pcie@%" PRIx64, base); qemu_fdt_add_subnode(ms->fdt, nodename); @@ -452,7 +452,7 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams, qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map", 0, *pch_msi_phandle, 0, 0x10000); - fdt_add_pcie_irq_map_node(lams, nodename, pch_pic_phandle); + fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle); g_free(nodename); } @@ -473,15 +473,15 @@ static void fdt_add_memory_node(MachineState *ms, g_free(nodename); } -static void virt_build_smbios(LoongArchMachineState *lams) +static void virt_build_smbios(LoongArchVirtMachineState *lvms) { - MachineState *ms = MACHINE(lams); - MachineClass *mc = MACHINE_GET_CLASS(lams); + MachineState *ms = MACHINE(lvms); + MachineClass *mc = MACHINE_GET_CLASS(lvms); uint8_t *smbios_tables, *smbios_anchor; size_t smbios_tables_len, smbios_anchor_len; const char *product = "QEMU Virtual Machine"; - if (!lams->fw_cfg) { + if (!lvms->fw_cfg) { return; } @@ -493,26 +493,26 @@ static void virt_build_smbios(LoongArchMachineState *lams) &smbios_anchor, &smbios_anchor_len, &error_fatal); if (smbios_anchor) { - fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-tables", + fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-tables", smbios_tables, smbios_tables_len); - fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-anchor", + fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-anchor", smbios_anchor, smbios_anchor_len); } } -static void virt_machine_done(Notifier *notifier, void *data) +static void virt_done(Notifier *notifier, void *data) { - LoongArchMachineState *lams = container_of(notifier, - LoongArchMachineState, machine_done); - virt_build_smbios(lams); - loongarch_acpi_setup(lams); + LoongArchVirtMachineState *lvms = container_of(notifier, + LoongArchVirtMachineState, machine_done); + virt_build_smbios(lvms); + loongarch_acpi_setup(lvms); } static void virt_powerdown_req(Notifier *notifier, void *opaque) { - LoongArchMachineState *s = container_of(notifier, - LoongArchMachineState, powerdown_notifier); + LoongArchVirtMachineState *s; + s = container_of(notifier, LoongArchVirtMachineState, powerdown_notifier); acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS); } @@ -532,10 +532,11 @@ static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) memmap_entries++; } -static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState *lams) +static DeviceState *create_acpi_ged(DeviceState *pch_pic, + LoongArchVirtMachineState *lvms) { DeviceState *dev; - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); uint32_t event = ACPI_GED_PWR_DOWN_EVT; if (ms->ram_slots) { @@ -582,12 +583,12 @@ static DeviceState *create_platform_bus(DeviceState *pch_pic) return dev; } -static void loongarch_devices_init(DeviceState *pch_pic, - LoongArchMachineState *lams, +static void virt_devices_init(DeviceState *pch_pic, + LoongArchVirtMachineState *lvms, uint32_t *pch_pic_phandle, uint32_t *pch_msi_phandle) { - MachineClass *mc = MACHINE_GET_CLASS(lams); + MachineClass *mc = MACHINE_GET_CLASS(lvms); DeviceState *gpex_dev; SysBusDevice *d; PCIBus *pci_bus; @@ -599,7 +600,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, d = SYS_BUS_DEVICE(gpex_dev); sysbus_realize_and_unref(d, &error_fatal); pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus; - lams->pci_bus = pci_bus; + lvms->pci_bus = pci_bus; /* Map only part size_ecam bytes of ECAM space */ ecam_alias = g_new0(MemoryRegion, 1); @@ -632,13 +633,13 @@ static void loongarch_devices_init(DeviceState *pch_pic, } /* Add pcie node */ - fdt_add_pcie_node(lams, pch_pic_phandle, pch_msi_phandle); + fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle); serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0, qdev_get_gpio_in(pch_pic, VIRT_UART_IRQ - VIRT_GSI_BASE), 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); - fdt_add_uart_node(lams, pch_pic_phandle); + fdt_add_uart_node(lvms, pch_pic_phandle); /* Network init */ pci_init_nic_devices(pci_bus, mc->default_nic); @@ -651,17 +652,17 @@ static void loongarch_devices_init(DeviceState *pch_pic, sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE, qdev_get_gpio_in(pch_pic, VIRT_RTC_IRQ - VIRT_GSI_BASE)); - fdt_add_rtc_node(lams, pch_pic_phandle); + fdt_add_rtc_node(lvms, pch_pic_phandle); /* acpi ged */ - lams->acpi_ged = create_acpi_ged(pch_pic, lams); + lvms->acpi_ged = create_acpi_ged(pch_pic, lvms); /* platform bus */ - lams->platform_bus_dev = create_platform_bus(pch_pic); + lvms->platform_bus_dev = create_platform_bus(pch_pic); } -static void loongarch_irq_init(LoongArchMachineState *lams) +static void virt_irq_init(LoongArchVirtMachineState *lvms) { - MachineState *ms = MACHINE(lams); + MachineState *ms = MACHINE(lvms); DeviceState *pch_pic, *pch_msi, *cpudev; DeviceState *ipi, *extioi; SysBusDevice *d; @@ -699,20 +700,20 @@ static void loongarch_irq_init(LoongArchMachineState *lams) sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); /* IPI iocsr memory region */ - memory_region_add_subregion(&lams->system_iocsr, SMP_IPI_MAILBOX, + memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX, sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0)); - memory_region_add_subregion(&lams->system_iocsr, MAIL_SEND_ADDR, + memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR, sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1)); /* Add cpu interrupt-controller */ - fdt_add_cpuic_node(lams, &cpuintc_phandle); + fdt_add_cpuic_node(lvms, &cpuintc_phandle); 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); - env->address_space_iocsr = &lams->as_iocsr; + env->address_space_iocsr = &lvms->as_iocsr; /* connect ipi irq to cpu irq */ qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI)); @@ -723,7 +724,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus); sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); - memory_region_add_subregion(&lams->system_iocsr, APIC_BASE, + memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); /* @@ -739,7 +740,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) } /* Add Extend I/O Interrupt Controller node */ - fdt_add_eiointc_node(lams, &cpuintc_phandle, &eiointc_phandle); + fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle); pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC); num = VIRT_PCH_PIC_IRQ_NUM; @@ -761,7 +762,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) } /* Add PCH PIC node */ - fdt_add_pch_pic_node(lams, &eiointc_phandle, &pch_pic_phandle); + fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle); pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI); start = num; @@ -778,30 +779,30 @@ static void loongarch_irq_init(LoongArchMachineState *lams) } /* Add PCH MSI node */ - fdt_add_pch_msi_node(lams, &eiointc_phandle, &pch_msi_phandle); + fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle); - loongarch_devices_init(pch_pic, lams, &pch_pic_phandle, &pch_msi_phandle); + virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle); } -static void loongarch_firmware_init(LoongArchMachineState *lams) +static void virt_firmware_init(LoongArchVirtMachineState *lvms) { - char *filename = MACHINE(lams)->firmware; + char *filename = MACHINE(lvms)->firmware; char *bios_name = NULL; int bios_size, i; BlockBackend *pflash_blk0; MemoryRegion *mr; - lams->bios_loaded = false; + lvms->bios_loaded = false; /* Map legacy -drive if=pflash to machine properties */ - for (i = 0; i < ARRAY_SIZE(lams->flash); i++) { - pflash_cfi01_legacy_drive(lams->flash[i], + for (i = 0; i < ARRAY_SIZE(lvms->flash); i++) { + pflash_cfi01_legacy_drive(lvms->flash[i], drive_get(IF_PFLASH, 0, i)); } - virt_flash_map(lams, get_system_memory()); + virt_flash_map(lvms, get_system_memory()); - pflash_blk0 = pflash_cfi01_get_blk(lams->flash[0]); + pflash_blk0 = pflash_cfi01_get_blk(lvms->flash[0]); if (pflash_blk0) { if (filename) { @@ -809,7 +810,7 @@ static void loongarch_firmware_init(LoongArchMachineState *lams) "options at once"); exit(1); } - lams->bios_loaded = true; + lvms->bios_loaded = true; return; } @@ -820,24 +821,24 @@ static void loongarch_firmware_init(LoongArchMachineState *lams) exit(1); } - mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lams->flash[0]), 0); + mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lvms->flash[0]), 0); bios_size = load_image_mr(bios_name, mr); if (bios_size < 0) { error_report("Could not load ROM image '%s'", bios_name); exit(1); } g_free(bios_name); - lams->bios_loaded = true; + lvms->bios_loaded = true; } } -static void loongarch_qemu_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static void virt_iocsr_misc_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) { } -static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) +static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr addr, unsigned size) { switch (addr) { case VERSION_REG: @@ -855,9 +856,9 @@ static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) return 0ULL; } -static const MemoryRegionOps loongarch_qemu_ops = { - .read = loongarch_qemu_read, - .write = loongarch_qemu_write, +static const MemoryRegionOps virt_iocsr_misc_ops = { + .read = virt_iocsr_misc_read, + .write = virt_iocsr_misc_write, .endianness = DEVICE_LITTLE_ENDIAN, .valid = { .min_access_size = 4, @@ -869,7 +870,7 @@ static const MemoryRegionOps loongarch_qemu_ops = { }, }; -static void loongarch_init(MachineState *machine) +static void virt_init(MachineState *machine) { LoongArchCPU *lacpu; const char *cpu_model = machine->cpu_type; @@ -877,7 +878,7 @@ static void loongarch_init(MachineState *machine) ram_addr_t ram_size = machine->ram_size; uint64_t highram_size = 0, phyAddr = 0; MemoryRegion *address_space_mem = get_system_memory(); - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); int nb_numa_nodes = machine->numa_state->num_nodes; NodeInfo *numa_info = machine->numa_state->nodes; int i; @@ -893,16 +894,16 @@ static void loongarch_init(MachineState *machine) error_report("ram_size must be greater than 1G."); exit(1); } - create_fdt(lams); + create_fdt(lvms); /* Create IOCSR space */ - memory_region_init_io(&lams->system_iocsr, OBJECT(machine), NULL, + memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL, machine, "iocsr", UINT64_MAX); - address_space_init(&lams->as_iocsr, &lams->system_iocsr, "IOCSR"); - memory_region_init_io(&lams->iocsr_mem, OBJECT(machine), - &loongarch_qemu_ops, + address_space_init(&lvms->as_iocsr, &lvms->system_iocsr, "IOCSR"); + memory_region_init_io(&lvms->iocsr_mem, OBJECT(machine), + &virt_iocsr_misc_ops, machine, "iocsr_misc", 0x428); - memory_region_add_subregion(&lams->system_iocsr, 0, &lams->iocsr_mem); + memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem); /* Init CPUs */ possible_cpus = mc->possible_cpu_arch_ids(machine); @@ -913,14 +914,14 @@ static void loongarch_init(MachineState *machine) lacpu = LOONGARCH_CPU(cpu); lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id; } - fdt_add_cpu_nodes(lams); + fdt_add_cpu_nodes(lvms); /* Node0 memory */ memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1); fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0); - memory_region_init_alias(&lams->lowmem, NULL, "loongarch.node0.lowram", + memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.node0.lowram", machine->ram, offset, VIRT_LOWMEM_SIZE); - memory_region_add_subregion(address_space_mem, phyAddr, &lams->lowmem); + memory_region_add_subregion(address_space_mem, phyAddr, &lvms->lowmem); offset += VIRT_LOWMEM_SIZE; if (nb_numa_nodes > 0) { @@ -932,9 +933,9 @@ static void loongarch_init(MachineState *machine) phyAddr = VIRT_HIGHMEM_BASE; memmap_add_entry(phyAddr, highram_size, 1); fdt_add_memory_node(machine, phyAddr, highram_size, 0); - memory_region_init_alias(&lams->highmem, NULL, "loongarch.node0.highram", + memory_region_init_alias(&lvms->highmem, NULL, "loongarch.node0.highram", machine->ram, offset, highram_size); - memory_region_add_subregion(address_space_mem, phyAddr, &lams->highmem); + memory_region_add_subregion(address_space_mem, phyAddr, &lvms->highmem); /* Node1 - Nodemax memory */ offset += highram_size; @@ -975,30 +976,30 @@ static void loongarch_init(MachineState *machine) } /* load the BIOS image. */ - loongarch_firmware_init(lams); + virt_firmware_init(lvms); /* fw_cfg init */ - 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", + lvms->fw_cfg = virt_fw_cfg_init(ram_size, machine); + rom_set_fw(lvms->fw_cfg); + if (lvms->fw_cfg != NULL) { + fw_cfg_add_file(lvms->fw_cfg, "etc/memmap", memmap_table, sizeof(struct memmap_entry) * (memmap_entries)); } - fdt_add_fw_cfg_node(lams); - fdt_add_flash_node(lams); + fdt_add_fw_cfg_node(lvms); + fdt_add_flash_node(lvms); /* Initialize the IO interrupt subsystem */ - loongarch_irq_init(lams); + virt_irq_init(lvms); platform_bus_add_all_fdt_nodes(machine->fdt, "/platic", VIRT_PLATFORM_BUS_BASEADDRESS, VIRT_PLATFORM_BUS_SIZE, VIRT_PLATFORM_BUS_IRQ); - lams->machine_done.notify = virt_machine_done; - qemu_add_machine_init_done_notifier(&lams->machine_done); + lvms->machine_done.notify = virt_done; + qemu_add_machine_init_done_notifier(&lvms->machine_done); /* connect powerdown request */ - lams->powerdown_notifier.notify = virt_powerdown_req; - qemu_register_powerdown_notifier(&lams->powerdown_notifier); + lvms->powerdown_notifier.notify = virt_powerdown_req; + qemu_register_powerdown_notifier(&lvms->powerdown_notifier); /* * Since lowmem region starts from 0 and Linux kernel legacy start address @@ -1007,49 +1008,41 @@ static void loongarch_init(MachineState *machine) * Put the FDT into the memory map as a ROM image: this will ensure * the FDT is copied again upon reset, even if addr points into RAM. */ - qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size); - rom_add_blob_fixed_as("fdt", machine->fdt, lams->fdt_size, FDT_BASE, + qemu_fdt_dumpdtb(machine->fdt, lvms->fdt_size); + rom_add_blob_fixed_as("fdt", machine->fdt, lvms->fdt_size, FDT_BASE, &address_space_memory); qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, - rom_ptr_for_as(&address_space_memory, FDT_BASE, lams->fdt_size)); + rom_ptr_for_as(&address_space_memory, FDT_BASE, lvms->fdt_size)); - lams->bootinfo.ram_size = ram_size; - loongarch_load_kernel(machine, &lams->bootinfo); + lvms->bootinfo.ram_size = ram_size; + loongarch_load_kernel(machine, &lvms->bootinfo); } -bool loongarch_is_acpi_enabled(LoongArchMachineState *lams) +static void virt_get_acpi(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) { - 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_VIRT_MACHINE(obj); - OnOffAuto acpi = lams->acpi; + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + OnOffAuto acpi = lvms->acpi; visit_type_OnOffAuto(v, name, &acpi, errp); } -static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, +static void virt_set_acpi(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); - visit_type_OnOffAuto(v, name, &lams->acpi, errp); + visit_type_OnOffAuto(v, name, &lvms->acpi, errp); } -static void loongarch_machine_initfn(Object *obj) +static void virt_initfn(Object *obj) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_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); - virt_flash_create(lams); + lvms->acpi = ON_OFF_AUTO_AUTO; + lvms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); + lvms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); + virt_flash_create(lvms); } static bool memhp_type_supported(DeviceState *dev) @@ -1065,7 +1058,7 @@ static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp); } -static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, +static void virt_device_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (memhp_type_supported(dev)) { @@ -1076,14 +1069,14 @@ static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, static void virt_mem_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev); /* the acpi ged is always exist */ - hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev, + hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp); } -static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev, +static void virt_device_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (memhp_type_supported(dev)) { @@ -1094,14 +1087,14 @@ static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev, static void virt_mem_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev); - hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp); - pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams)); + hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp); + pc_dimm_unplug(PC_DIMM(dev), MACHINE(lvms)); qdev_unrealize(dev); } -static void virt_machine_device_unplug(HotplugHandler *hotplug_dev, +static void virt_device_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (memhp_type_supported(dev)) { @@ -1112,31 +1105,32 @@ static void virt_machine_device_unplug(HotplugHandler *hotplug_dev, static void virt_mem_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev); - pc_dimm_plug(PC_DIMM(dev), MACHINE(lams)); - hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged), + pc_dimm_plug(PC_DIMM(dev), MACHINE(lvms)); + hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &error_abort); } -static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, +static void virt_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev); - MachineClass *mc = MACHINE_GET_CLASS(lams); + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev); + MachineClass *mc = MACHINE_GET_CLASS(lvms); + PlatformBusDevice *pbus; if (device_is_dynamic_sysbus(mc, dev)) { - if (lams->platform_bus_dev) { - platform_bus_link_device(PLATFORM_BUS_DEVICE(lams->platform_bus_dev), - SYS_BUS_DEVICE(dev)); + if (lvms->platform_bus_dev) { + pbus = PLATFORM_BUS_DEVICE(lvms->platform_bus_dev); + platform_bus_link_device(pbus, SYS_BUS_DEVICE(dev)); } } else if (memhp_type_supported(dev)) { virt_mem_plug(hotplug_dev, dev, errp); } } -static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, - DeviceState *dev) +static HotplugHandler *virt_get_hotplug_handler(MachineState *machine, + DeviceState *dev) { MachineClass *mc = MACHINE_GET_CLASS(machine); @@ -1176,8 +1170,8 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) return ms->possible_cpus; } -static CpuInstanceProperties -virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) +static CpuInstanceProperties virt_cpu_index_to_props(MachineState *ms, + unsigned cpu_index) { MachineClass *mc = MACHINE_GET_CLASS(ms); const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); @@ -1199,12 +1193,12 @@ static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) return nidx; } -static void loongarch_class_init(ObjectClass *oc, void *data) +static void virt_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); - mc->init = loongarch_init; + mc->init = virt_init; mc->default_ram_size = 1 * GiB; mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464"); mc->default_ram_id = "loongarch.ram"; @@ -1220,15 +1214,15 @@ static void loongarch_class_init(ObjectClass *oc, void *data) mc->numa_mem_supported = true; mc->auto_enable_numa_with_memhp = true; mc->auto_enable_numa_with_memdev = true; - mc->get_hotplug_handler = virt_machine_get_hotplug_handler; + mc->get_hotplug_handler = virt_get_hotplug_handler; mc->default_nic = "virtio-net-pci"; - hc->plug = loongarch_machine_device_plug_cb; - hc->pre_plug = virt_machine_device_pre_plug; - hc->unplug_request = virt_machine_device_unplug_request; - hc->unplug = virt_machine_device_unplug; + hc->plug = virt_device_plug_cb; + hc->pre_plug = virt_device_pre_plug; + hc->unplug_request = virt_device_unplug_request; + hc->unplug = virt_device_unplug; object_class_property_add(oc, "acpi", "OnOffAuto", - loongarch_get_acpi, loongarch_set_acpi, + virt_get_acpi, virt_set_acpi, NULL, NULL); object_class_property_set_description(oc, "acpi", "Enable ACPI"); @@ -1238,13 +1232,13 @@ static void loongarch_class_init(ObjectClass *oc, void *data) #endif } -static const TypeInfo loongarch_machine_types[] = { +static const TypeInfo virt_machine_types[] = { { .name = TYPE_LOONGARCH_VIRT_MACHINE, .parent = TYPE_MACHINE, - .instance_size = sizeof(LoongArchMachineState), - .class_init = loongarch_class_init, - .instance_init = loongarch_machine_initfn, + .instance_size = sizeof(LoongArchVirtMachineState), + .class_init = virt_class_init, + .instance_init = virt_initfn, .interfaces = (InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } @@ -1252,4 +1246,4 @@ static const TypeInfo loongarch_machine_types[] = { } }; -DEFINE_TYPES(loongarch_machine_types) +DEFINE_TYPES(virt_machine_types) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 5b1416d7bc..d8a4ddb936 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -37,7 +37,7 @@ #define FDT_BASE 0x100000 -struct LoongArchMachineState { +struct LoongArchVirtMachineState { /*< private >*/ MachineState parent_obj; @@ -64,7 +64,6 @@ struct LoongArchMachineState { }; #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") -OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_VIRT_MACHINE) -bool loongarch_is_acpi_enabled(LoongArchMachineState *lams); -void loongarch_acpi_setup(LoongArchMachineState *lams); +OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE) +void loongarch_acpi_setup(LoongArchVirtMachineState *lvms); #endif From 5b1a3b9f8c0fbcd2420977678601948d7573c809 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 8 May 2024 10:31:09 +0100 Subject: [PATCH 24/28] hw/mips/loongson3_virt: Emulate suspend function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suspend function is emulated as what hardware actually do. Doorbell register fields are updates to include suspend value, suspend vector is encoded in firmware blob and fw_cfg is updated to include S3 bits as what x86 did. Signed-off-by: Jiaxun Yang Message-ID: <20240508-loongson3v-suspend-v1-1-186725524a39@flygoat.com> [PMD: Use g_memdup2(), constify suspend array] Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/loongson3_bootp.c | 1 + hw/mips/loongson3_virt.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c index f99af22932..03a10b63c1 100644 --- a/hw/mips/loongson3_bootp.c +++ b/hw/mips/loongson3_bootp.c @@ -148,4 +148,5 @@ void init_reset_system(struct efi_reset_system_t *reset) reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8); reset->ResetCold = cpu_to_le64(0xffffffffbfc00080); reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080); + reset->DoSuspend = cpu_to_le64(0xffffffffbfc000d0); } diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c index b10a611a98..440268a074 100644 --- a/hw/mips/loongson3_virt.c +++ b/hw/mips/loongson3_virt.c @@ -127,6 +127,9 @@ static void loongson3_pm_write(void *opaque, hwaddr addr, case 0x00: qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); return; + case 0x01: + qemu_system_suspend_request(); + return; case 0xff: qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); return; @@ -250,6 +253,17 @@ static void init_boot_rom(void) 0x240D00FF, /* li t1, 0xff */ 0xA18D0000, /* sb t1, (t0) */ 0x1000FFFF, /* 1: b 1b */ + 0x00000000, /* nop */ + /* Suspend */ + 0x3C0C9000, /* dli t0, 0x9000000010080010 */ + 0x358C0000, + 0x000C6438, + 0x358C1008, + 0x000C6438, + 0x358C0010, + 0x240D0001, /* li t1, 0x01 */ + 0xA18D0000, /* sb t1, (t0) */ + 0x03e00008, /* jr ra */ 0x00000000 /* nop */ }; @@ -265,6 +279,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device, static void fw_conf_init(unsigned long ram_size) { + static const uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; FWCfgState *fw_cfg; hwaddr cfg_addr = virt_memmap[VIRT_FW_CFG].base; @@ -274,6 +289,10 @@ static void fw_conf_init(unsigned long ram_size) fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz()); + + fw_cfg_add_file(fw_cfg, "etc/system-states", + g_memdup2(suspend, sizeof(suspend)), sizeof(suspend)); + qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } @@ -553,6 +572,7 @@ static void mips_loongson3_virt_init(MachineState *machine) machine->ram, 0, virt_memmap[VIRT_LOWMEM].size); memory_region_init_io(iomem, NULL, &loongson3_pm_ops, NULL, "loongson3_pm", virt_memmap[VIRT_PM].size); + qemu_register_wakeup_support(); memory_region_add_subregion(address_space_mem, virt_memmap[VIRT_LOWMEM].base, ram); From 39b3ae11b0763d8d8f4df9b03fc4b3ed5fa155ee Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 8 May 2024 14:06:46 +0100 Subject: [PATCH 25/28] hw/intc/loongarch_ipi: Remove pointless MAX_CPU check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since cpuid will be checked by ipi_getcpu anyway, there is no point to enforce MAX_CPU here. This also saved us from including loongarch board header. Signed-off-by: Jiaxun Yang Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240508-loongson3-ipi-v1-1-1a7b67704664@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/intc/loongarch_ipi.c | 19 ++----------------- hw/intc/trace-events | 2 -- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index a184112b09..44b3b9c138 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -6,6 +6,7 @@ */ #include "qemu/osdep.h" +#include "hw/boards.h" #include "hw/sysbus.h" #include "hw/intc/loongarch_ipi.h" #include "hw/irq.h" @@ -13,9 +14,8 @@ #include "qapi/error.h" #include "qemu/log.h" #include "exec/address-spaces.h" -#include "hw/loongarch/virt.h" #include "migration/vmstate.h" -#include "target/loongarch/internals.h" +#include "target/loongarch/cpu.h" #include "trace.h" static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, @@ -122,11 +122,6 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs) CPUState *cs; cpuid = extract32(val, 16, 10); - if (cpuid >= LOONGARCH_MAX_CPUS) { - trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid); - return MEMTX_DECODE_ERROR; - } - cs = ipi_getcpu(cpuid); if (cs == NULL) { return MEMTX_DECODE_ERROR; @@ -146,11 +141,6 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) CPUState *cs; cpuid = extract32(val, 16, 10); - if (cpuid >= LOONGARCH_MAX_CPUS) { - trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid); - return MEMTX_DECODE_ERROR; - } - cs = ipi_getcpu(cpuid); if (cs == NULL) { return MEMTX_DECODE_ERROR; @@ -201,11 +191,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, break; case IOCSR_IPI_SEND: cpuid = extract32(val, 16, 10); - if (cpuid >= LOONGARCH_MAX_CPUS) { - trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid); - return MEMTX_DECODE_ERROR; - } - /* IPI status vector */ vector = extract8(val, 0, 5); cs = ipi_getcpu(cpuid); diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 47340b5bc1..a979784f9b 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -294,8 +294,6 @@ sh_intc_set(int id, int enable) "setting interrupt group %d to %d" # loongarch_ipi.c loongarch_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 loongarch_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 -loongarch_ipi_unsupported_cpuid(const char *s, uint32_t cpuid) "%s unsupported cpuid 0x%" PRIx32 - # loongarch_pch_pic.c loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d" loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 From b4a12dfc2132dc22c587ee2ecbd7b8d48ec381a1 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 8 May 2024 14:06:47 +0100 Subject: [PATCH 26/28] hw/intc/loongarch_ipi: Rename as loongson_ipi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This device will be shared among LoongArch and MIPS based Loongson machine, rename it as loongson_ipi to reflect this nature. Signed-off-by: Jiaxun Yang Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240508-loongson3-ipi-v1-2-1a7b67704664@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 4 + hw/intc/Kconfig | 2 +- hw/intc/loongson_ipi.c | 347 ++++++++++++++++++ hw/intc/meson.build | 2 +- hw/intc/trace-events | 6 +- hw/loongarch/Kconfig | 2 +- hw/loongarch/virt.c | 4 +- .../intc/{loongarch_ipi.h => loongson_ipi.h} | 12 +- include/hw/loongarch/virt.h | 2 +- 9 files changed, 366 insertions(+), 15 deletions(-) create mode 100644 hw/intc/loongson_ipi.c rename include/hw/intc/{loongarch_ipi.h => loongson_ipi.h} (84%) diff --git a/MAINTAINERS b/MAINTAINERS index 84391777db..7097f31245 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1242,7 +1242,9 @@ F: configs/devices/loongarch64-softmmu/default.mak F: hw/loongarch/ F: include/hw/loongarch/virt.h F: include/hw/intc/loongarch_*.h +F: include/hw/intc/loongson_ipi.h F: hw/intc/loongarch_*.c +F: hw/intc/loongson_ipi.c F: include/hw/pci-host/ls7a.h F: hw/rtc/ls7a_rtc.c F: gdb-xml/loongarch*.xml @@ -1376,10 +1378,12 @@ Loongson-3 virtual platforms M: Huacai Chen R: Jiaxun Yang S: Maintained +F: hw/intc/loongson_ipi.c F: hw/intc/loongson_liointc.c F: hw/mips/loongson3_bootp.c F: hw/mips/loongson3_bootp.h F: hw/mips/loongson3_virt.c +F: include/hw/intc/loongson_ipi.h F: include/hw/intc/loongson_liointc.h F: tests/avocado/machine_mips_loongson3v.py diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig index ad59abebaa..58b6d3a710 100644 --- a/hw/intc/Kconfig +++ b/hw/intc/Kconfig @@ -87,7 +87,7 @@ config GOLDFISH_PIC config M68K_IRQC bool -config LOONGARCH_IPI +config LOONGSON_IPI bool config LOONGARCH_PCH_PIC diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c new file mode 100644 index 0000000000..8c888da3b2 --- /dev/null +++ b/hw/intc/loongson_ipi.c @@ -0,0 +1,347 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Loongson ipi interrupt support + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "hw/boards.h" +#include "hw/sysbus.h" +#include "hw/intc/loongson_ipi.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "exec/address-spaces.h" +#include "migration/vmstate.h" +#include "target/loongarch/cpu.h" +#include "trace.h" + +static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr, + uint64_t *data, + unsigned size, MemTxAttrs attrs) +{ + IPICore *s; + LoongsonIPI *ipi = opaque; + uint64_t ret = 0; + int index = 0; + + s = &ipi->cpu[attrs.requester_id]; + addr &= 0xff; + switch (addr) { + case CORE_STATUS_OFF: + ret = s->status; + break; + case CORE_EN_OFF: + ret = s->en; + break; + case CORE_SET_OFF: + ret = 0; + break; + case CORE_CLEAR_OFF: + ret = 0; + break; + case CORE_BUF_20 ... CORE_BUF_38 + 4: + index = (addr - CORE_BUF_20) >> 2; + ret = s->buf[index]; + break; + default: + qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr); + break; + } + + trace_loongson_ipi_read(size, (uint64_t)addr, ret); + *data = ret; + return MEMTX_OK; +} + +static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, + MemTxAttrs attrs) +{ + int i, mask = 0, data = 0; + + /* + * bit 27-30 is mask for byte writing, + * if the mask is 0, we need not to do anything. + */ + if ((val >> 27) & 0xf) { + data = address_space_ldl(env->address_space_iocsr, addr, + attrs, NULL); + for (i = 0; i < 4; i++) { + /* get mask for byte writing */ + if (val & (0x1 << (27 + i))) { + mask |= 0xff << (i * 8); + } + } + } + + data &= mask; + data |= (val >> 32) & ~mask; + address_space_stl(env->address_space_iocsr, addr, + data, attrs, NULL); +} + +static int archid_cmp(const void *a, const void *b) +{ + CPUArchId *archid_a = (CPUArchId *)a; + CPUArchId *archid_b = (CPUArchId *)b; + + return archid_a->arch_id - archid_b->arch_id; +} + +static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id) +{ + CPUArchId apic_id, *found_cpu; + + apic_id.arch_id = id; + found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, + ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), + archid_cmp); + + return found_cpu; +} + +static CPUState *ipi_getcpu(int arch_id) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + CPUArchId *archid; + + archid = find_cpu_by_archid(machine, arch_id); + if (archid) { + return CPU(archid->cpu); + } + + return NULL; +} + +static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs) +{ + uint32_t cpuid; + hwaddr addr; + CPUState *cs; + + cpuid = extract32(val, 16, 10); + cs = ipi_getcpu(cpuid); + if (cs == NULL) { + return MEMTX_DECODE_ERROR; + } + + /* override requester_id */ + addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c); + attrs.requester_id = cs->cpu_index; + send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); + return MEMTX_OK; +} + +static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) +{ + uint32_t cpuid; + hwaddr addr; + CPUState *cs; + + cpuid = extract32(val, 16, 10); + cs = ipi_getcpu(cpuid); + if (cs == NULL) { + return MEMTX_DECODE_ERROR; + } + + /* override requester_id */ + addr = val & 0xffff; + attrs.requester_id = cs->cpu_index; + send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); + return MEMTX_OK; +} + +static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs) +{ + LoongsonIPI *ipi = opaque; + IPICore *s; + int index = 0; + uint32_t cpuid; + uint8_t vector; + CPUState *cs; + + s = &ipi->cpu[attrs.requester_id]; + addr &= 0xff; + trace_loongson_ipi_write(size, (uint64_t)addr, val); + switch (addr) { + case CORE_STATUS_OFF: + qemu_log_mask(LOG_GUEST_ERROR, "can not be written"); + break; + case CORE_EN_OFF: + s->en = val; + break; + case CORE_SET_OFF: + s->status |= val; + if (s->status != 0 && (s->status & s->en) != 0) { + qemu_irq_raise(s->irq); + } + break; + case CORE_CLEAR_OFF: + s->status &= ~val; + if (s->status == 0 && s->en != 0) { + qemu_irq_lower(s->irq); + } + break; + case CORE_BUF_20 ... CORE_BUF_38 + 4: + index = (addr - CORE_BUF_20) >> 2; + s->buf[index] = val; + break; + case IOCSR_IPI_SEND: + cpuid = extract32(val, 16, 10); + /* IPI status vector */ + vector = extract8(val, 0, 5); + cs = ipi_getcpu(cpuid); + if (cs == NULL) { + return MEMTX_DECODE_ERROR; + } + + /* override requester_id */ + attrs.requester_id = cs->cpu_index; + loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs); + break; + default: + qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr); + break; + } + + return MEMTX_OK; +} + +static const MemoryRegionOps loongson_ipi_ops = { + .read_with_attrs = loongson_ipi_readl, + .write_with_attrs = loongson_ipi_writel, + .impl.min_access_size = 4, + .impl.max_access_size = 4, + .valid.min_access_size = 4, + .valid.max_access_size = 8, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +/* mail send and any send only support writeq */ +static MemTxResult loongson_ipi_writeq(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs) +{ + MemTxResult ret = MEMTX_OK; + + addr &= 0xfff; + switch (addr) { + case MAIL_SEND_OFFSET: + ret = mail_send(val, attrs); + break; + case ANY_SEND_OFFSET: + ret = any_send(val, attrs); + break; + default: + break; + } + + return ret; +} + +static const MemoryRegionOps loongson_ipi64_ops = { + .write_with_attrs = loongson_ipi_writeq, + .impl.min_access_size = 8, + .impl.max_access_size = 8, + .valid.min_access_size = 8, + .valid.max_access_size = 8, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void loongson_ipi_realize(DeviceState *dev, Error **errp) +{ + LoongsonIPI *s = LOONGSON_IPI(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + int i; + + if (s->num_cpu == 0) { + error_setg(errp, "num-cpu must be at least 1"); + return; + } + + memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), &loongson_ipi_ops, + s, "loongson_ipi_iocsr", 0x48); + + /* loongson_ipi_iocsr performs re-entrant IO through ipi_send */ + s->ipi_iocsr_mem.disable_reentrancy_guard = true; + + sysbus_init_mmio(sbd, &s->ipi_iocsr_mem); + + memory_region_init_io(&s->ipi64_iocsr_mem, OBJECT(dev), + &loongson_ipi64_ops, + s, "loongson_ipi64_iocsr", 0x118); + sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem); + + s->cpu = g_new0(IPICore, s->num_cpu); + if (s->cpu == NULL) { + error_setg(errp, "Memory allocation for ExtIOICore faile"); + return; + } + + for (i = 0; i < s->num_cpu; i++) { + qdev_init_gpio_out(dev, &s->cpu[i].irq, 1); + } +} + +static const VMStateDescription vmstate_ipi_core = { + .name = "ipi-single", + .version_id = 2, + .minimum_version_id = 2, + .fields = (const VMStateField[]) { + VMSTATE_UINT32(status, IPICore), + VMSTATE_UINT32(en, IPICore), + VMSTATE_UINT32(set, IPICore), + VMSTATE_UINT32(clear, IPICore), + VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_loongson_ipi = { + .name = TYPE_LOONGSON_IPI, + .version_id = 2, + .minimum_version_id = 2, + .fields = (const VMStateField[]) { + VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongsonIPI, num_cpu, + vmstate_ipi_core, IPICore), + VMSTATE_END_OF_LIST() + } +}; + +static Property ipi_properties[] = { + DEFINE_PROP_UINT32("num-cpu", LoongsonIPI, num_cpu, 1), + DEFINE_PROP_END_OF_LIST(), +}; + +static void loongson_ipi_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = loongson_ipi_realize; + device_class_set_props(dc, ipi_properties); + dc->vmsd = &vmstate_loongson_ipi; +} + +static void loongson_ipi_finalize(Object *obj) +{ + LoongsonIPI *s = LOONGSON_IPI(obj); + + g_free(s->cpu); +} + +static const TypeInfo loongson_ipi_info = { + .name = TYPE_LOONGSON_IPI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(LoongsonIPI), + .class_init = loongson_ipi_class_init, + .instance_finalize = loongson_ipi_finalize, +}; + +static void loongson_ipi_register_types(void) +{ + type_register_static(&loongson_ipi_info); +} + +type_init(loongson_ipi_register_types) diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 58140da5f2..f4b540e6a8 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -68,7 +68,7 @@ specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c')) specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'], if_true: files('spapr_xive_kvm.c')) specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c')) -specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c')) +specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: files('loongson_ipi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c')) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index a979784f9b..b815cea129 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -291,9 +291,9 @@ sh_intc_read(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PR sh_intc_write(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PRIx64 " <- 0x%lx" sh_intc_set(int id, int enable) "setting interrupt group %d to %d" -# loongarch_ipi.c -loongarch_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 -loongarch_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 +# loongson_ipi.c +loongson_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 +loongson_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 # loongarch_pch_pic.c loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d" loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 7864050563..ad77502445 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -10,7 +10,7 @@ config LOONGARCH_VIRT select SERIAL select VIRTIO_PCI select PLATFORM_BUS - select LOONGARCH_IPI + select LOONGSON_IPI select LOONGARCH_PCH_PIC select LOONGARCH_PCH_MSI select LOONGARCH_EXTIOI diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 51e0aca39b..852036467a 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -21,7 +21,7 @@ #include "net/net.h" #include "hw/loader.h" #include "elf.h" -#include "hw/intc/loongarch_ipi.h" +#include "hw/intc/loongson_ipi.h" #include "hw/intc/loongarch_extioi.h" #include "hw/intc/loongarch_pch_pic.h" #include "hw/intc/loongarch_pch_msi.h" @@ -695,7 +695,7 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) */ /* Create IPI device */ - ipi = qdev_new(TYPE_LOONGARCH_IPI); + ipi = qdev_new(TYPE_LOONGSON_IPI); qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus); sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongson_ipi.h similarity index 84% rename from include/hw/intc/loongarch_ipi.h rename to include/hw/intc/loongson_ipi.h index 1c1e834849..2c0e8820f5 100644 --- a/include/hw/intc/loongarch_ipi.h +++ b/include/hw/intc/loongson_ipi.h @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * LoongArch ipi interrupt header files + * Loongson ipi interrupt header files * * Copyright (C) 2021 Loongson Technology Corporation Limited */ -#ifndef HW_LOONGARCH_IPI_H -#define HW_LOONGARCH_IPI_H +#ifndef HW_LOONGSON_IPI_H +#define HW_LOONGSON_IPI_H #include "hw/sysbus.h" @@ -30,8 +30,8 @@ #define IPI_MBX_NUM 4 -#define TYPE_LOONGARCH_IPI "loongarch_ipi" -OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI) +#define TYPE_LOONGSON_IPI "loongson_ipi" +OBJECT_DECLARE_SIMPLE_TYPE(LoongsonIPI, LOONGSON_IPI) typedef struct IPICore { uint32_t status; @@ -43,7 +43,7 @@ typedef struct IPICore { qemu_irq irq; } IPICore; -struct LoongArchIPI { +struct LoongsonIPI { SysBusDevice parent_obj; MemoryRegion ipi_iocsr_mem; MemoryRegion ipi64_iocsr_mem; diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index d8a4ddb936..2c4f5cf9c8 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -11,7 +11,7 @@ #include "target/loongarch/cpu.h" #include "hw/boards.h" #include "qemu/queue.h" -#include "hw/intc/loongarch_ipi.h" +#include "hw/intc/loongson_ipi.h" #include "hw/block/flash.h" #include "hw/loongarch/boot.h" From 91d0b151de4cb433ae31b7e2678fdb19850ad772 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 8 May 2024 14:06:48 +0100 Subject: [PATCH 27/28] hw/intc/loongson_ipi: Implement IOCSR address space for MIPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement IOCSR address space get functions for MIPS/Loongson CPUs. For MIPS/Loongson without IOCSR (i.e. Loongson-3A1000), get_cpu_iocsr_as will return as null, and send_ipi_data will fail with MEMTX_DECODE_ERROR, which matches expected behavior on hardware. Signed-off-by: Jiaxun Yang Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20240508-loongson3-ipi-v1-3-1a7b67704664@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/intc/loongson_ipi.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c index 8c888da3b2..93cc50a37a 100644 --- a/hw/intc/loongson_ipi.c +++ b/hw/intc/loongson_ipi.c @@ -15,7 +15,12 @@ #include "qemu/log.h" #include "exec/address-spaces.h" #include "migration/vmstate.h" +#ifdef TARGET_LOONGARCH64 #include "target/loongarch/cpu.h" +#endif +#ifdef TARGET_MIPS +#include "target/mips/cpu.h" +#endif #include "trace.h" static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr, @@ -56,18 +61,35 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr, return MEMTX_OK; } -static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, +static AddressSpace *get_cpu_iocsr_as(CPUState *cpu) +{ +#ifdef TARGET_LOONGARCH64 + return LOONGARCH_CPU(cpu)->env.address_space_iocsr; +#endif +#ifdef TARGET_MIPS + if (ase_lcsr_available(&MIPS_CPU(cpu)->env)) { + return &MIPS_CPU(cpu)->env.iocsr.as; + } +#endif + return NULL; +} + +static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr, MemTxAttrs attrs) { int i, mask = 0, data = 0; + AddressSpace *iocsr_as = get_cpu_iocsr_as(cpu); + + if (!iocsr_as) { + return MEMTX_DECODE_ERROR; + } /* * bit 27-30 is mask for byte writing, * if the mask is 0, we need not to do anything. */ if ((val >> 27) & 0xf) { - data = address_space_ldl(env->address_space_iocsr, addr, - attrs, NULL); + data = address_space_ldl(iocsr_as, addr, attrs, NULL); for (i = 0; i < 4; i++) { /* get mask for byte writing */ if (val & (0x1 << (27 + i))) { @@ -78,8 +100,9 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, data &= mask; data |= (val >> 32) & ~mask; - address_space_stl(env->address_space_iocsr, addr, - data, attrs, NULL); + address_space_stl(iocsr_as, addr, data, attrs, NULL); + + return MEMTX_OK; } static int archid_cmp(const void *a, const void *b) @@ -130,8 +153,7 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs) /* override requester_id */ addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c); attrs.requester_id = cs->cpu_index; - send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); - return MEMTX_OK; + return send_ipi_data(cs, val, addr, attrs); } static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) @@ -149,8 +171,7 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) /* override requester_id */ addr = val & 0xffff; attrs.requester_id = cs->cpu_index; - send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); - return MEMTX_OK; + return send_ipi_data(cs, val, addr, attrs); } static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val, From 8b4d80bb53af30db5de91749216d0bb73fa93cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 7 May 2024 16:05:48 +0200 Subject: [PATCH 28/28] misc: Use QEMU header path relative to include/ directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU headers are relative to the include/ directory, not to the project root directory. Remove "include/". See also: https://www.qemu.org/docs/master/devel/style.html#include-directives Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson Message-Id: <20240507142737.95735-1-philmd@linaro.org> --- hw/audio/virtio-snd.c | 2 +- hw/rtc/ls7a_rtc.c | 2 +- target/i386/gdbstub.c | 2 +- tests/qtest/nvme-test.c | 2 +- tests/qtest/ufs-test.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c index 6a2ee085c0..7d09800d1f 100644 --- a/hw/audio/virtio-snd.c +++ b/hw/audio/virtio-snd.c @@ -19,7 +19,7 @@ #include "qemu/iov.h" #include "qemu/log.h" #include "qemu/error-report.h" -#include "include/qemu/lockable.h" +#include "qemu/lockable.h" #include "exec/tswap.h" #include "sysemu/runstate.h" #include "trace.h" diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c index ac28c1165b..052201c2cd 100644 --- a/hw/rtc/ls7a_rtc.c +++ b/hw/rtc/ls7a_rtc.c @@ -8,7 +8,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/irq.h" -#include "include/hw/register.h" +#include "hw/register.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "qemu/cutils.h" diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c index ebb000df6a..4acf485879 100644 --- a/target/i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -19,7 +19,7 @@ */ #include "qemu/osdep.h" #include "cpu.h" -#include "include/gdbstub/helpers.h" +#include "gdbstub/helpers.h" #ifdef TARGET_X86_64 static const int gpr_map[16] = { diff --git a/tests/qtest/nvme-test.c b/tests/qtest/nvme-test.c index 008d189b0f..5ad6821f7a 100644 --- a/tests/qtest/nvme-test.c +++ b/tests/qtest/nvme-test.c @@ -13,7 +13,7 @@ #include "libqtest.h" #include "libqos/qgraph.h" #include "libqos/pci.h" -#include "include/block/nvme.h" +#include "block/nvme.h" typedef struct QNvme QNvme; diff --git a/tests/qtest/ufs-test.c b/tests/qtest/ufs-test.c index 95e82f9472..82ec3f0671 100644 --- a/tests/qtest/ufs-test.c +++ b/tests/qtest/ufs-test.c @@ -13,7 +13,7 @@ #include "libqos/qgraph.h" #include "libqos/pci.h" #include "scsi/constants.h" -#include "include/block/ufs.h" +#include "block/ufs.h" /* Test images sizes in Bytes */ #define TEST_IMAGE_SIZE (64 * 1024 * 1024)