From nobody Wed Oct 29 11:56:37 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1525564067613658.5134802865997; Sat, 5 May 2018 16:47:47 -0700 (PDT) Received: from localhost ([::1]:40317 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fF6u2-0003i6-IX for importer@patchew.org; Sat, 05 May 2018 19:47:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54640) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fF6ke-0004eA-9e for qemu-devel@nongnu.org; Sat, 05 May 2018 19:38:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fF6kb-0004Bs-RF for qemu-devel@nongnu.org; Sat, 05 May 2018 19:38:04 -0400 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:37614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fF6kb-0004BY-Ib for qemu-devel@nongnu.org; Sat, 05 May 2018 19:38:01 -0400 Received: by mail-pf0-x242.google.com with SMTP id e9so16093526pfi.4 for ; Sat, 05 May 2018 16:38:01 -0700 (PDT) Received: from localhost.localdomain (122-58-167-38-fibre.bb.spark.co.nz. [122.58.167.38]) by smtp.gmail.com with ESMTPSA id x8sm47297094pfa.173.2018.05.05.16.37.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 05 May 2018 16:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LQ0nESzmrCz8uUEWh+shVhQ2mMNpt03Nc0jimVnEBJk=; b=d23GYsD/lbOcn5may6KjeJ4qEDtcrFRQmEybDJ8OUKAXCE3n/ExKyTBilRmnRRyS3O OcyvwRLmjXZkD+QE4qeZYunCyGILQB3ZGk2vAipO8UzGboBIpcu/IuOAZ9tHEmRijtBB 1hWMHoCHYqa/5flA6v22UubRs+XH0mMklDFEbzCjXJSp0OQY/MAwyUIX8MMu9Y7vuv1Q 2dEQ/JuZyYjkeEne3h59ZrJ6+X+tLnk0GdpBTp1P4F8uieg7/3hAx3tsWphPpCAqPokV 6UOFg3TFBBKcm3YSR4cJ7L72jUJgvd52uS1vcT7TTRCAis1fW/YtOHwZpBVskEoQZrH8 lIHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LQ0nESzmrCz8uUEWh+shVhQ2mMNpt03Nc0jimVnEBJk=; b=p46CcQLa4Uu3ITBkdAebED//si+27P8UsEqywh995P96ch2p2SOxe+xNFhKzpHzwIY N5H/tI/bD8kEI1DsyIjzoaKEav6OBbtRUAXZfA8tR0KieucP01ZZijODSZV4FkkjC2Q/ V1JUAmJWjyQb94P68fDKzvgm7E86WuRi8F/OOgzFar6SviRLEYbUWWO5b7+CG3gnqH5m U+kime5SQND+0euLgFJWoDglvW4D7Tz7SzU+QTJvadgHyGZq3rcJTxmQKPEsEOXwxVve Yt2meN8sfxiSJIAtwgNZYLC9qoIyl+SLaxePNhsZTL2e624qUG9YSlMQIzHBMhrCtox8 7AGg== X-Gm-Message-State: ALQs6tBhRb8awiK0dcffGwQwqeJhj5GZ336tXpNBnaesPkCTw08BBoOE nla7EfcaQcqXJexsls3RJTgA1pl02W0= X-Google-Smtp-Source: AB8JxZrM5JdECvyFHjbzBLRDxtJHc8sOzRw0Uu4xERnOcAgv90QkpZzOl7Qk7Ek2wPiqi2Hj7qvl8w== X-Received: by 10.98.182.16 with SMTP id j16mr31677033pff.17.1525563480597; Sat, 05 May 2018 16:38:00 -0700 (PDT) From: Michael Clark To: qemu-devel@nongnu.org Date: Sun, 6 May 2018 11:35:25 +1200 Message-Id: <1525563325-62963-21-git-send-email-mjc@sifive.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1525563325-62963-1-git-send-email-mjc@sifive.com> References: <1525563325-62963-1-git-send-email-mjc@sifive.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::242 Subject: [Qemu-devel] [PULL 20/20] RISC-V: Mark ROM read-only after copying in code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sagar Karandikar , Bastian Koppelmann , Palmer Dabbelt , Michael Clark , Alistair Francis , patches@groups.riscv.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The sifive_u machine already marks its ROM readonly however it has the wrong base address for its mask ROM. This patch fixes the sifive_u mask ROM base address. This commit makes all other boards consistently use mask_rom as the variable name for their ROMs. Boards that use device tree now check that that the device tree fits in the assigned ROM space using the new qemu_fdt_totalsize(void *fdt) interface, adding a bounds check and error message. This can detect truncation. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- hw/riscv/sifive_e.c | 20 +++++++--------- hw/riscv/sifive_u.c | 51 +++++++++++++++++++++------------------ hw/riscv/spike.c | 69 +++++++++++++++++++++++++++++++------------------= ---- hw/riscv/virt.c | 43 ++++++++++++++++++--------------- 4 files changed, 101 insertions(+), 82 deletions(-) diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 6fa223818502..e4ecb7aa4bb6 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -74,14 +74,6 @@ static const struct MemmapEntry { [SIFIVE_E_DTIM] =3D { 0x80000000, 0x4000 } }; =20 -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i =3D 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -112,6 +104,7 @@ static void riscv_sifive_e_init(MachineState *machine) MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); MemoryRegion *xip_mem =3D g_new(MemoryRegion, 1); + int i; =20 /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -131,7 +124,7 @@ static void riscv_sifive_e_init(MachineState *machine) memmap[SIFIVE_E_DTIM].base, main_mem); =20 /* Mask ROM */ - memory_region_init_ram(mask_rom, NULL, "riscv.sifive.e.mrom", + memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom", memmap[SIFIVE_E_MROM].size, &error_fatal); memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_MROM].base, mask_rom); @@ -185,9 +178,12 @@ static void riscv_sifive_e_init(MachineState *machine) 0x00028067, /* 0x1004: jr t0 */ }; =20 - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SIFIVE_E_MROM].base, reset_vec, sizeof(reset_= vec)); - memory_region_set_readonly(mask_rom, true); + /* copy in the reset vector in little_endian byte order */ + for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] =3D cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SIFIVE_E_MROM].base, &address_space_memor= y); =20 if (machine->kernel_filename) { load_kernel(machine->kernel_filename); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 84afed4c3b0e..c05dcbba955e 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -47,12 +47,14 @@ #include "exec/address-spaces.h" #include "elf.h" =20 +#include + static const struct MemmapEntry { hwaddr base; hwaddr size; } sifive_u_memmap[] =3D { [SIFIVE_U_DEBUG] =3D { 0x0, 0x100 }, - [SIFIVE_U_MROM] =3D { 0x1000, 0x2000 }, + [SIFIVE_U_MROM] =3D { 0x1000, 0x11000 }, [SIFIVE_U_CLINT] =3D { 0x2000000, 0x10000 }, [SIFIVE_U_PLIC] =3D { 0xc000000, 0x4000000 }, [SIFIVE_U_UART0] =3D { 0x10013000, 0x1000 }, @@ -60,14 +62,6 @@ static const struct MemmapEntry { [SIFIVE_U_DRAM] =3D { 0x80000000, 0x0 }, }; =20 -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i =3D 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -221,9 +215,10 @@ static void riscv_sifive_u_init(MachineState *machine) const struct MemmapEntry *memmap =3D sifive_u_memmap; =20 SiFiveUState *s =3D g_new0(SiFiveUState, 1); - MemoryRegion *sys_memory =3D get_system_memory(); + MemoryRegion *system_memory =3D get_system_memory(); MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); - MemoryRegion *boot_rom =3D g_new(MemoryRegion, 1); + MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); + int i; =20 /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -239,17 +234,17 @@ static void riscv_sifive_u_init(MachineState *machine) /* register RAM */ memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram", machine->ram_size, &error_fatal); - memory_region_add_subregion(sys_memory, memmap[SIFIVE_U_DRAM].base, + memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DRAM].base, main_mem); =20 /* create device tree */ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); =20 /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv.sifive.u.mrom", - memmap[SIFIVE_U_MROM].base, &error_fatal); - memory_region_set_readonly(boot_rom, true); - memory_region_add_subregion(sys_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv.sifive.u.mrom", + memmap[SIFIVE_U_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base, + mask_rom); =20 if (machine->kernel_filename) { load_kernel(machine->kernel_filename); @@ -272,13 +267,23 @@ static void riscv_sifive_u_init(MachineState *machine) /* dtb: */ }; =20 - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SIFIVE_U_MROM].base, reset_vec, sizeof(reset_= vec)); + /* copy in the reset vector in little_endian byte order */ + for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] =3D cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SIFIVE_U_MROM].base, &address_space_memor= y); =20 /* copy in the device tree */ - qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(memmap[SIFIVE_U_MROM].base + - sizeof(reset_vec), s->fdt, s->fdt_size); + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[SIFIVE_U_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[SIFIVE_U_MROM].base + sizeof(reset_vec), + &address_space_memory); =20 /* MMIO */ s->plic =3D sifive_plic_create(memmap[SIFIVE_U_PLIC].base, @@ -292,9 +297,9 @@ static void riscv_sifive_u_init(MachineState *machine) SIFIVE_U_PLIC_CONTEXT_BASE, SIFIVE_U_PLIC_CONTEXT_STRIDE, memmap[SIFIVE_U_PLIC].size); - sifive_uart_create(sys_memory, memmap[SIFIVE_U_UART0].base, + sifive_uart_create(system_memory, memmap[SIFIVE_U_UART0].base, serial_hd(0), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART0_IRQ]); - /* sifive_uart_create(sys_memory, memmap[SIFIVE_U_UART1].base, + /* sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base, serial_hd(1), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART1_IRQ]); */ sifive_clint_create(memmap[SIFIVE_U_CLINT].base, memmap[SIFIVE_U_CLINT].size, smp_cpus, diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 9e18c618bfbb..f94e2b670799 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -42,23 +42,17 @@ #include "exec/address-spaces.h" #include "elf.h" =20 +#include + static const struct MemmapEntry { hwaddr base; hwaddr size; } spike_memmap[] =3D { - [SPIKE_MROM] =3D { 0x1000, 0x2000 }, + [SPIKE_MROM] =3D { 0x1000, 0x11000 }, [SPIKE_CLINT] =3D { 0x2000000, 0x10000 }, [SPIKE_DRAM] =3D { 0x80000000, 0x0 }, }; =20 -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i =3D 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -173,7 +167,8 @@ static void spike_v1_10_0_board_init(MachineState *mach= ine) SpikeState *s =3D g_new0(SpikeState, 1); MemoryRegion *system_memory =3D get_system_memory(); MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); - MemoryRegion *boot_rom =3D g_new(MemoryRegion, 1); + MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); + int i; =20 /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -196,9 +191,10 @@ static void spike_v1_10_0_board_init(MachineState *mac= hine) create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); =20 /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom", - s->fdt_size + 0x2000, &error_fatal); - memory_region_add_subregion(system_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom", + memmap[SPIKE_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base, + mask_rom); =20 if (machine->kernel_filename) { load_kernel(machine->kernel_filename); @@ -221,16 +217,26 @@ static void spike_v1_10_0_board_init(MachineState *ma= chine) /* dtb: */ }; =20 - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SPIKE_MROM].base, reset_vec, sizeof(reset_vec= )); + /* copy in the reset vector in little_endian byte order */ + for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] =3D cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SPIKE_MROM].base, &address_space_memory); =20 /* copy in the device tree */ - qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(memmap[SPIKE_MROM].base + sizeof(reset_vec), - s->fdt, s->fdt_size); + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[SPIKE_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[SPIKE_MROM].base + sizeof(reset_vec), + &address_space_memory); =20 /* initialize HTIF using symbols found in load_kernel */ - htif_mm_init(system_memory, boot_rom, &s->soc.harts[0].env, serial_hd(= 0)); + htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(= 0)); =20 /* Core Local Interruptor (timer and IPI) */ sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, @@ -244,7 +250,8 @@ static void spike_v1_09_1_board_init(MachineState *mach= ine) SpikeState *s =3D g_new0(SpikeState, 1); MemoryRegion *system_memory =3D get_system_memory(); MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); - MemoryRegion *boot_rom =3D g_new(MemoryRegion, 1); + MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); + int i; =20 /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -264,9 +271,10 @@ static void spike_v1_09_1_board_init(MachineState *mac= hine) main_mem); =20 /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom", - 0x40000, &error_fatal); - memory_region_add_subregion(system_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom", + memmap[SPIKE_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base, + mask_rom); =20 if (machine->kernel_filename) { load_kernel(machine->kernel_filename); @@ -319,15 +327,20 @@ static void spike_v1_09_1_board_init(MachineState *ma= chine) g_free(isa); size_t config_string_len =3D strlen(config_string); =20 - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SPIKE_MROM].base, reset_vec, sizeof(reset_vec= )); + /* copy in the reset vector in little_endian byte order */ + for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] =3D cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SPIKE_MROM].base, &address_space_memory); =20 /* copy in the config string */ - cpu_physical_memory_write(memmap[SPIKE_MROM].base + sizeof(reset_vec), - config_string, config_string_len); + rom_add_blob_fixed_as("mrom.reset", config_string, config_string_len, + memmap[SPIKE_MROM].base + sizeof(reset_vec), + &address_space_memory); =20 /* initialize HTIF using symbols found in load_kernel */ - htif_mm_init(system_memory, boot_rom, &s->soc.harts[0].env, serial_hd(= 0)); + htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(= 0)); =20 /* Core Local Interruptor (timer and IPI) */ sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 7ef9ba26debc..ad03113e0f72 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -40,13 +40,15 @@ #include "exec/address-spaces.h" #include "elf.h" =20 +#include + static const struct MemmapEntry { hwaddr base; hwaddr size; } virt_memmap[] =3D { [VIRT_DEBUG] =3D { 0x0, 0x100 }, - [VIRT_MROM] =3D { 0x1000, 0x2000 }, - [VIRT_TEST] =3D { 0x4000, 0x1000 }, + [VIRT_MROM] =3D { 0x1000, 0x11000 }, + [VIRT_TEST] =3D { 0x100000, 0x1000 }, [VIRT_CLINT] =3D { 0x2000000, 0x10000 }, [VIRT_PLIC] =3D { 0xc000000, 0x4000000 }, [VIRT_UART0] =3D { 0x10000000, 0x100 }, @@ -54,14 +56,6 @@ static const struct MemmapEntry { [VIRT_DRAM] =3D { 0x80000000, 0x0 }, }; =20 -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i =3D 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -272,7 +266,7 @@ static void riscv_virt_board_init(MachineState *machine) RISCVVirtState *s =3D g_new0(RISCVVirtState, 1); MemoryRegion *system_memory =3D get_system_memory(); MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); - MemoryRegion *boot_rom =3D g_new(MemoryRegion, 1); + MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); char *plic_hart_config; size_t plic_hart_config_len; int i; @@ -299,9 +293,10 @@ static void riscv_virt_board_init(MachineState *machin= e) fdt =3D create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdli= ne); =20 /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv_virt_board.bootrom", - s->fdt_size + 0x2000, &error_fatal); - memory_region_add_subregion(system_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom", + memmap[VIRT_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base, + mask_rom); =20 if (machine->kernel_filename) { uint64_t kernel_entry =3D load_kernel(machine->kernel_filename); @@ -335,13 +330,23 @@ static void riscv_virt_board_init(MachineState *machi= ne) /* dtb: */ }; =20 - /* copy in the reset vector */ - copy_le32_to_phys(memmap[VIRT_MROM].base, reset_vec, sizeof(reset_vec)= ); + /* copy in the reset vector in little_endian byte order */ + for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] =3D cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[VIRT_MROM].base, &address_space_memory); =20 /* copy in the device tree */ - qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(memmap[VIRT_MROM].base + sizeof(reset_vec), - s->fdt, s->fdt_size); + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[VIRT_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[VIRT_MROM].base + sizeof(reset_vec), + &address_space_memory); =20 /* create PLIC hart topology configuration string */ plic_hart_config_len =3D (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpu= s; --=20 2.7.0