RISC-V: Mark ROM read-only after copying in code

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 <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Alistair Francis <Alistair.Francis@wdc.com>
This commit is contained in:
Michael Clark 2018-03-04 11:52:13 +13:00
parent b8643bd608
commit 5aec3247c1
No known key found for this signature in database
GPG key ID: 6BF1D7B357EF3E4F
4 changed files with 101 additions and 82 deletions

View file

@ -42,23 +42,17 @@
#include "exec/address-spaces.h"
#include "elf.h"
#include <libfdt.h>
static const struct MemmapEntry {
hwaddr base;
hwaddr size;
} spike_memmap[] = {
[SPIKE_MROM] = { 0x1000, 0x2000 },
[SPIKE_MROM] = { 0x1000, 0x11000 },
[SPIKE_CLINT] = { 0x2000000, 0x10000 },
[SPIKE_DRAM] = { 0x80000000, 0x0 },
};
static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len)
{
int i;
for (i = 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 *machine)
SpikeState *s = g_new0(SpikeState, 1);
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
int i;
/* 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 *machine)
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
/* 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);
if (machine->kernel_filename) {
load_kernel(machine->kernel_filename);
@ -221,16 +217,26 @@ static void spike_v1_10_0_board_init(MachineState *machine)
/* dtb: */
};
/* 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 = 0; i < sizeof(reset_vec) >> 2; i++) {
reset_vec[i] = 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);
/* 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);
/* 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));
/* 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 *machine)
SpikeState *s = g_new0(SpikeState, 1);
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
int i;
/* 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 *machine)
main_mem);
/* 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);
if (machine->kernel_filename) {
load_kernel(machine->kernel_filename);
@ -319,15 +327,20 @@ static void spike_v1_09_1_board_init(MachineState *machine)
g_free(isa);
size_t config_string_len = strlen(config_string);
/* 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 = 0; i < sizeof(reset_vec) >> 2; i++) {
reset_vec[i] = 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);
/* 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);
/* 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));
/* Core Local Interruptor (timer and IPI) */
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,