From e92fb01639cadbeb9c6fc5d5189e35ef3e45836f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 26 Jun 2020 06:13:40 -0700 Subject: MAINTAINERS: Add an entry for OpenSBI firmware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List me as the maintainer for OpenSBI firmware related files. Signed-off-by: Bin Meng Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1593177220-28143-1-git-send-email-bmeng.cn@gmail.com> Signed-off-by: Alistair Francis --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index fe8139f..80fa883 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2681,6 +2681,13 @@ F: hw/i386/intel_iommu.c F: hw/i386/intel_iommu_internal.h F: include/hw/i386/intel_iommu.h +OpenSBI Firmware +M: Bin Meng +S: Supported +F: pc-bios/opensbi-* +F: .gitlab-ci.d/opensbi.yml +F: .gitlab-ci.d/opensbi/ + Usermode Emulation ------------------ Overall usermode emulation -- cgit v1.1 From 2c44bbf32cda5fbf85b697e3a12127f59d2c2e80 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 2 Jul 2020 20:21:51 -0700 Subject: hw/riscv: virt: Sort the SoC memmap table entries Adjust the PCIe memory maps to follow the order. Signed-off-by: Bin Meng Reviewed-by: Alistair Francis Message-Id: <1593746511-19517-1-git-send-email-bmeng.cn@gmail.com> Signed-off-by: Alistair Francis --- hw/riscv/virt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index f7630c8..18283e2 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -60,14 +60,14 @@ static const struct MemmapEntry { [VIRT_TEST] = { 0x100000, 0x1000 }, [VIRT_RTC] = { 0x101000, 0x1000 }, [VIRT_CLINT] = { 0x2000000, 0x10000 }, + [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, [VIRT_PLIC] = { 0xc000000, 0x4000000 }, [VIRT_UART0] = { 0x10000000, 0x100 }, [VIRT_VIRTIO] = { 0x10001000, 0x1000 }, [VIRT_FLASH] = { 0x20000000, 0x4000000 }, - [VIRT_DRAM] = { 0x80000000, 0x0 }, - [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, - [VIRT_PCIE_PIO] = { 0x03000000, 0x00010000 }, [VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 }, + [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, + [VIRT_DRAM] = { 0x80000000, 0x0 }, }; #define VIRT_FLASH_SECTOR_SIZE (256 * KiB) -- cgit v1.1 From 43cf723adca9a5e188c664c3b606a585192a599c Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Wed, 1 Jul 2020 11:39:46 -0700 Subject: riscv: Unify Qemu's reset vector code path Currently, all riscv machines except sifive_u have identical reset vector code implementations with memory addresses being different for all machines. They can be easily combined into a single function in common code. Move it to common function and let all the machines use the common function. Signed-off-by: Atish Patra Reviewed-by: Alistair Francis Reviewed-by: Bin Meng Tested-by: Bin Meng Message-Id: <20200701183949.398134-2-atish.patra@wdc.com> Signed-off-by: Alistair Francis --- hw/riscv/boot.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ hw/riscv/sifive_u.c | 1 - hw/riscv/spike.c | 41 +++-------------------------------------- hw/riscv/virt.c | 40 +++------------------------------------- include/hw/riscv/boot.h | 2 ++ 5 files changed, 54 insertions(+), 76 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index adb421b..3df8023 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -26,8 +26,11 @@ #include "hw/loader.h" #include "hw/riscv/boot.h" #include "elf.h" +#include "sysemu/device_tree.h" #include "sysemu/qtest.h" +#include + #if defined(TARGET_RISCV32) # define KERNEL_BOOT_ADDRESS 0x80400000 #else @@ -155,3 +158,46 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, return *start + size; } + +void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, + hwaddr rom_size, void *fdt) +{ + int i; + + /* reset vector */ + uint32_t reset_vec[8] = { + 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ + 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ + 0xf1402573, /* csrr a0, mhartid */ +#if defined(TARGET_RISCV32) + 0x0182a283, /* lw t0, 24(t0) */ +#elif defined(TARGET_RISCV64) + 0x0182b283, /* ld t0, 24(t0) */ +#endif + 0x00028067, /* jr t0 */ + 0x00000000, + start_addr, /* start: .dword */ + 0x00000000, + /* dtb: */ + }; + + /* 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), + rom_base, &address_space_memory); + + /* copy in the device tree */ + if (fdt_pack(fdt) || fdt_totalsize(fdt) > + rom_size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); + rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt), + rom_base + sizeof(reset_vec), + &address_space_memory); + + return; +} diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 7851326..0695c93 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -56,7 +56,6 @@ #include "sysemu/device_tree.h" #include "sysemu/runstate.h" #include "sysemu/sysemu.h" -#include "exec/address-spaces.h" #include diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index c107bf3..a8a0588 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -41,9 +41,6 @@ #include "sysemu/device_tree.h" #include "sysemu/qtest.h" #include "sysemu/sysemu.h" -#include "exec/address-spaces.h" - -#include #if defined(TARGET_RISCV32) # define BIOS_FILENAME "opensbi-riscv32-spike-fw_jump.elf" @@ -165,7 +162,6 @@ static void spike_board_init(MachineState *machine) MemoryRegion *system_memory = get_system_memory(); MemoryRegion *main_mem = g_new(MemoryRegion, 1); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); - int i; unsigned int smp_cpus = machine->smp.cpus; /* Initialize SOC */ @@ -212,40 +208,9 @@ static void spike_board_init(MachineState *machine) } } - /* reset vector */ - uint32_t reset_vec[8] = { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ - 0xf1402573, /* csrr a0, mhartid */ -#if defined(TARGET_RISCV32) - 0x0182a283, /* lw t0, 24(t0) */ -#elif defined(TARGET_RISCV64) - 0x0182b283, /* ld t0, 24(t0) */ -#endif - 0x00028067, /* jr t0 */ - 0x00000000, - memmap[SPIKE_DRAM].base, /* start: .dword DRAM_BASE */ - 0x00000000, - /* dtb: */ - }; - - /* 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 */ - 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); + /* load the reset vector */ + riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base, + memmap[SPIKE_MROM].size, s->fdt); /* initialize HTIF using symbols found in load_kernel */ htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0)); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 18283e2..3463cf5 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -39,12 +39,9 @@ #include "sysemu/arch_init.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" -#include "exec/address-spaces.h" #include "hw/pci/pci.h" #include "hw/pci-host/gpex.h" -#include - #if defined(TARGET_RISCV32) # define BIOS_FILENAME "opensbi-riscv32-virt-fw_jump.bin" #else @@ -535,40 +532,9 @@ static void virt_machine_init(MachineState *machine) start_addr = virt_memmap[VIRT_FLASH].base; } - /* reset vector */ - uint32_t reset_vec[8] = { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ - 0xf1402573, /* csrr a0, mhartid */ -#if defined(TARGET_RISCV32) - 0x0182a283, /* lw t0, 24(t0) */ -#elif defined(TARGET_RISCV64) - 0x0182b283, /* ld t0, 24(t0) */ -#endif - 0x00028067, /* jr t0 */ - 0x00000000, - start_addr, /* start: .dword */ - 0x00000000, - /* dtb: */ - }; - - /* 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[VIRT_MROM].base, &address_space_memory); - - /* copy in the device tree */ - 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); + /* load the reset vector */ + riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, + virt_memmap[VIRT_MROM].size, s->fdt); /* create PLIC hart topology configuration string */ plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus; diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 9daa98d..3e9759c 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -35,5 +35,7 @@ target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb); hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, uint64_t kernel_entry, hwaddr *start); +void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base, + hwaddr rom_size, void *fdt); #endif /* RISCV_BOOT_H */ -- cgit v1.1 From 66b1205bc5ab8bb3f5e12fa4155bbeb56e6724e9 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Wed, 1 Jul 2020 11:39:47 -0700 Subject: RISC-V: Copy the fdt in dram instead of ROM Currently, the fdt is copied to the ROM after the reset vector. The firmware has to copy it to DRAM. Instead of this, directly copy the device tree to a pre-computed dram address. The device tree load address should be as far as possible from kernel and initrd images. That's why it is kept at the end of the DRAM or 4GB whichever is lesser. Signed-off-by: Atish Patra Reviewed-by: Alistair Francis Reviewed-by: Bin Meng Tested-by: Bin Meng Message-Id: <20200701183949.398134-3-atish.patra@wdc.com> Signed-off-by: Alistair Francis --- hw/riscv/boot.c | 53 +++++++++++++++++++++++++++++++++++-------------- hw/riscv/sifive_u.c | 28 ++++++++++++-------------- hw/riscv/spike.c | 7 ++++++- hw/riscv/virt.c | 7 ++++++- include/hw/riscv/boot.h | 4 +++- 5 files changed, 66 insertions(+), 33 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 3df8023..c62f545 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -159,45 +159,68 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, return *start + size; } +uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) +{ + uint32_t temp, fdt_addr; + hwaddr dram_end = dram_base + mem_size; + int fdtsize = fdt_totalsize(fdt); + + if (fdtsize <= 0) { + error_report("invalid device-tree"); + exit(1); + } + + /* + * We should put fdt as far as possible to avoid kernel/initrd overwriting + * its content. But it should be addressable by 32 bit system as well. + * Thus, put it at an aligned address that less than fdt size from end of + * dram or 4GB whichever is lesser. + */ + temp = MIN(dram_end, 4096 * MiB); + fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); + + fdt_pack(fdt); + /* copy in the device tree */ + qemu_fdt_dumpdtb(fdt, fdtsize); + + rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr, + &address_space_memory); + + return fdt_addr; +} + void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, - hwaddr rom_size, void *fdt) + hwaddr rom_size, + uint32_t fdt_load_addr, void *fdt) { int i; /* reset vector */ - uint32_t reset_vec[8] = { + uint32_t reset_vec[10] = { 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) + 0x0202a583, /* lw a1, 32(t0) */ 0x0182a283, /* lw t0, 24(t0) */ #elif defined(TARGET_RISCV64) + 0x0202b583, /* ld a1, 32(t0) */ 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ 0x00000000, start_addr, /* start: .dword */ 0x00000000, + fdt_load_addr, /* fdt_laddr: .dword */ + 0x00000000, /* dtb: */ }; /* copy in the reset vector in little_endian byte order */ - for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + for (i = 0; i < ARRAY_SIZE(reset_vec); i++) { reset_vec[i] = cpu_to_le32(reset_vec[i]); } rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), rom_base, &address_space_memory); - /* copy in the device tree */ - if (fdt_pack(fdt) || fdt_totalsize(fdt) > - rom_size - sizeof(reset_vec)) { - error_report("not enough space to store device-tree"); - exit(1); - } - qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); - rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt), - rom_base + sizeof(reset_vec), - &address_space_memory); - return; } diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 0695c93..3992320 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -379,6 +379,7 @@ static void sifive_u_machine_init(MachineState *machine) MemoryRegion *flash0 = g_new(MemoryRegion, 1); target_ulong start_addr = memmap[SIFIVE_U_DRAM].base; int i; + uint32_t fdt_load_addr; /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC); @@ -450,40 +451,37 @@ static void sifive_u_machine_init(MachineState *machine) } } + /* Compute the fdt load address in dram */ + fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DRAM].base, + machine->ram_size, s->fdt); + /* reset vector */ - uint32_t reset_vec[8] = { + uint32_t reset_vec[11] = { s->msel, /* MSEL pin state */ 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) + 0x0202a583, /* lw a1, 32(t0) */ 0x0182a283, /* lw t0, 24(t0) */ #elif defined(TARGET_RISCV64) - 0x0182e283, /* lwu t0, 24(t0) */ + 0x0202b583, /* ld a1, 32(t0) */ + 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ 0x00000000, start_addr, /* start: .dword */ + 0x00000000, + fdt_load_addr, /* fdt_laddr: .dword */ + 0x00000000, /* dtb: */ }; /* copy in the reset vector in little_endian byte order */ - for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + for (i = 0; i < ARRAY_SIZE(reset_vec); i++) { reset_vec[i] = 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_memory); - - /* copy in the device tree */ - 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); } static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index a8a0588..13fa045 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -163,6 +163,7 @@ static void spike_board_init(MachineState *machine) MemoryRegion *main_mem = g_new(MemoryRegion, 1); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); unsigned int smp_cpus = machine->smp.cpus; + uint32_t fdt_load_addr; /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -208,9 +209,13 @@ static void spike_board_init(MachineState *machine) } } + /* Compute the fdt load address in dram */ + fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base, + machine->ram_size, s->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base, - memmap[SPIKE_MROM].size, s->fdt); + memmap[SPIKE_MROM].size, + fdt_load_addr, s->fdt); /* initialize HTIF using symbols found in load_kernel */ htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0)); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 3463cf5..9d87319 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -478,6 +478,7 @@ static void virt_machine_init(MachineState *machine) char *plic_hart_config; size_t plic_hart_config_len; target_ulong start_addr = memmap[VIRT_DRAM].base; + uint32_t fdt_load_addr; int i; unsigned int smp_cpus = machine->smp.cpus; @@ -532,9 +533,13 @@ static void virt_machine_init(MachineState *machine) start_addr = virt_memmap[VIRT_FLASH].base; } + /* Compute the fdt load address in dram */ + fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base, + machine->ram_size, s->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, - virt_memmap[VIRT_MROM].size, s->fdt); + virt_memmap[VIRT_MROM].size, + fdt_load_addr, s->fdt); /* create PLIC hart topology configuration string */ plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus; diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 3e9759c..35b6ddf 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -35,7 +35,9 @@ target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb); hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, uint64_t kernel_entry, hwaddr *start); +uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base, - hwaddr rom_size, void *fdt); + hwaddr rom_size, + uint32_t fdt_load_addr, void *fdt); #endif /* RISCV_BOOT_H */ -- cgit v1.1 From dc144fe13d336caac2f03b57f1df738e84f984ec Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Wed, 1 Jul 2020 11:39:48 -0700 Subject: riscv: Add opensbi firmware dynamic support OpenSBI is the default firmware in Qemu and has various firmware loading options. Currently, qemu loader uses fw_jump which has a compile time pre-defined address where fdt & kernel image must reside. This puts a constraint on image size of the Linux kernel depending on the fdt location and available memory. However, fw_dynamic allows the loader to specify the next stage location (i.e. Linux kernel/U-Boot) in memory and other configurable boot options available in OpenSBI. Add support for OpenSBI dynamic firmware loading support. This doesn't break existing setup and fw_jump will continue to work as it is. Any other firmware will continue to work without any issues as long as it doesn't expect anything specific from loader in "a2" register. Signed-off-by: Atish Patra Reviewed-by: Alistair Francis Reviewed-by: Bin Meng Tested-by: Bin Meng Message-Id: <20200701183949.398134-4-atish.patra@wdc.com> Signed-off-by: Alistair Francis --- hw/riscv/boot.c | 42 ++++++++++++++++++++++++++--- hw/riscv/sifive_u.c | 20 ++++++++++---- hw/riscv/spike.c | 13 ++++++--- hw/riscv/virt.c | 12 ++++++--- include/hw/riscv/boot.h | 5 +++- include/hw/riscv/boot_opensbi.h | 58 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 include/hw/riscv/boot_opensbi.h diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index c62f545..feff6e3 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -25,6 +25,7 @@ #include "hw/boards.h" #include "hw/loader.h" #include "hw/riscv/boot.h" +#include "hw/riscv/boot_opensbi.h" #include "elf.h" #include "sysemu/device_tree.h" #include "sysemu/qtest.h" @@ -33,8 +34,10 @@ #if defined(TARGET_RISCV32) # define KERNEL_BOOT_ADDRESS 0x80400000 +#define fw_dynamic_info_data(__val) cpu_to_le32(__val) #else # define KERNEL_BOOT_ADDRESS 0x80200000 +#define fw_dynamic_info_data(__val) cpu_to_le64(__val) #endif void riscv_find_and_load_firmware(MachineState *machine, @@ -189,15 +192,45 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) return fdt_addr; } +void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size, + uint32_t reset_vec_size, uint64_t kernel_entry) +{ + struct fw_dynamic_info dinfo; + size_t dinfo_len; + + dinfo.magic = fw_dynamic_info_data(FW_DYNAMIC_INFO_MAGIC_VALUE); + dinfo.version = fw_dynamic_info_data(FW_DYNAMIC_INFO_VERSION); + dinfo.next_mode = fw_dynamic_info_data(FW_DYNAMIC_INFO_NEXT_MODE_S); + dinfo.next_addr = fw_dynamic_info_data(kernel_entry); + dinfo.options = 0; + dinfo.boot_hart = 0; + dinfo_len = sizeof(dinfo); + + /** + * copy the dynamic firmware info. This information is specific to + * OpenSBI but doesn't break any other firmware as long as they don't + * expect any certain value in "a2" register. + */ + if (dinfo_len > (rom_size - reset_vec_size)) { + error_report("not enough space to store dynamic firmware info"); + exit(1); + } + + rom_add_blob_fixed_as("mrom.finfo", &dinfo, dinfo_len, + rom_base + reset_vec_size, + &address_space_memory); +} + void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, - hwaddr rom_size, + hwaddr rom_size, uint64_t kernel_entry, uint32_t fdt_load_addr, void *fdt) { int i; /* reset vector */ uint32_t reset_vec[10] = { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ + 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */ + 0x02828613, /* addi a2, t0, %pcrel_lo(1b) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) 0x0202a583, /* lw a1, 32(t0) */ @@ -207,12 +240,11 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ - 0x00000000, start_addr, /* start: .dword */ 0x00000000, fdt_load_addr, /* fdt_laddr: .dword */ 0x00000000, - /* dtb: */ + /* fw_dyn: */ }; /* copy in the reset vector in little_endian byte order */ @@ -221,6 +253,8 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, } rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), rom_base, &address_space_memory); + riscv_rom_copy_firmware_info(rom_base, rom_size, sizeof(reset_vec), + kernel_entry); return; } diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 3992320..46e6ed9 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -380,6 +380,7 @@ static void sifive_u_machine_init(MachineState *machine) target_ulong start_addr = memmap[SIFIVE_U_DRAM].base; int i; uint32_t fdt_load_addr; + uint64_t kernel_entry; /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC); @@ -436,8 +437,7 @@ static void sifive_u_machine_init(MachineState *machine) riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL); if (machine->kernel_filename) { - uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename, - NULL); + kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL); if (machine->initrd_filename) { hwaddr start; @@ -449,6 +449,12 @@ static void sifive_u_machine_init(MachineState *machine) qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", end); } + } else { + /* + * If dynamic firmware is used, it doesn't know where is the next mode + * if kernel argument is not set. + */ + kernel_entry = 0; } /* Compute the fdt load address in dram */ @@ -458,7 +464,8 @@ static void sifive_u_machine_init(MachineState *machine) /* reset vector */ uint32_t reset_vec[11] = { s->msel, /* MSEL pin state */ - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ + 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */ + 0x02828613, /* addi a2, t0, %pcrel_lo(1b) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) 0x0202a583, /* lw a1, 32(t0) */ @@ -468,12 +475,11 @@ static void sifive_u_machine_init(MachineState *machine) 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ - 0x00000000, start_addr, /* start: .dword */ 0x00000000, fdt_load_addr, /* fdt_laddr: .dword */ 0x00000000, - /* dtb: */ + /* fw_dyn: */ }; /* copy in the reset vector in little_endian byte order */ @@ -482,6 +488,10 @@ static void sifive_u_machine_init(MachineState *machine) } rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), memmap[SIFIVE_U_MROM].base, &address_space_memory); + + riscv_rom_copy_firmware_info(memmap[SIFIVE_U_MROM].base, + memmap[SIFIVE_U_MROM].size, + sizeof(reset_vec), kernel_entry); } static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 13fa045..b17d96a 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -164,6 +164,7 @@ static void spike_board_init(MachineState *machine) MemoryRegion *mask_rom = g_new(MemoryRegion, 1); unsigned int smp_cpus = machine->smp.cpus; uint32_t fdt_load_addr; + uint64_t kernel_entry; /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -194,8 +195,8 @@ static void spike_board_init(MachineState *machine) htif_symbol_callback); if (machine->kernel_filename) { - uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename, - htif_symbol_callback); + kernel_entry = riscv_load_kernel(machine->kernel_filename, + htif_symbol_callback); if (machine->initrd_filename) { hwaddr start; @@ -207,6 +208,12 @@ static void spike_board_init(MachineState *machine) qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", end); } + } else { + /* + * If dynamic firmware is used, it doesn't know where is the next mode + * if kernel argument is not set. + */ + kernel_entry = 0; } /* Compute the fdt load address in dram */ @@ -214,7 +221,7 @@ static void spike_board_init(MachineState *machine) machine->ram_size, s->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base, - memmap[SPIKE_MROM].size, + memmap[SPIKE_MROM].size, kernel_entry, fdt_load_addr, s->fdt); /* initialize HTIF using symbols found in load_kernel */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 9d87319..bc25ec6 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -479,6 +479,7 @@ static void virt_machine_init(MachineState *machine) size_t plic_hart_config_len; target_ulong start_addr = memmap[VIRT_DRAM].base; uint32_t fdt_load_addr; + uint64_t kernel_entry; int i; unsigned int smp_cpus = machine->smp.cpus; @@ -510,8 +511,7 @@ static void virt_machine_init(MachineState *machine) memmap[VIRT_DRAM].base, NULL); if (machine->kernel_filename) { - uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename, - NULL); + kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL); if (machine->initrd_filename) { hwaddr start; @@ -523,6 +523,12 @@ static void virt_machine_init(MachineState *machine) qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", end); } + } else { + /* + * If dynamic firmware is used, it doesn't know where is the next mode + * if kernel argument is not set. + */ + kernel_entry = 0; } if (drive_get(IF_PFLASH, 0, 0)) { @@ -538,7 +544,7 @@ static void virt_machine_init(MachineState *machine) machine->ram_size, s->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, - virt_memmap[VIRT_MROM].size, + virt_memmap[VIRT_MROM].size, kernel_entry, fdt_load_addr, s->fdt); /* create PLIC hart topology configuration string */ diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 35b6ddf..4513387 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -37,7 +37,10 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, uint64_t kernel_entry, hwaddr *start); uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base, - hwaddr rom_size, + hwaddr rom_size, uint64_t kernel_entry, uint32_t fdt_load_addr, void *fdt); +void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size, + uint32_t reset_vec_size, + uint64_t kernel_entry); #endif /* RISCV_BOOT_H */ diff --git a/include/hw/riscv/boot_opensbi.h b/include/hw/riscv/boot_opensbi.h new file mode 100644 index 0000000..0d5ddd6 --- /dev/null +++ b/include/hw/riscv/boot_opensbi.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Based on include/sbi/{fw_dynamic.h,sbi_scratch.h} from the OpenSBI project. + */ +#ifndef OPENSBI_H +#define OPENSBI_H + +/** Expected value of info magic ('OSBI' ascii string in hex) */ +#define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f + +/** Maximum supported info version */ +#define FW_DYNAMIC_INFO_VERSION 0x2 + +/** Possible next mode values */ +#define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0 +#define FW_DYNAMIC_INFO_NEXT_MODE_S 0x1 +#define FW_DYNAMIC_INFO_NEXT_MODE_M 0x3 + +enum sbi_scratch_options { + /** Disable prints during boot */ + SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0), + /** Enable runtime debug prints */ + SBI_SCRATCH_DEBUG_PRINTS = (1 << 1), +}; + +/** Representation dynamic info passed by previous booting stage */ +struct fw_dynamic_info { + /** Info magic */ + target_long magic; + /** Info version */ + target_long version; + /** Next booting stage address */ + target_long next_addr; + /** Next booting stage mode */ + target_long next_mode; + /** Options for OpenSBI library */ + target_long options; + /** + * Preferred boot HART id + * + * It is possible that the previous booting stage uses same link + * address as the FW_DYNAMIC firmware. In this case, the relocation + * lottery mechanism can potentially overwrite the previous booting + * stage while other HARTs are still running in the previous booting + * stage leading to boot-time crash. To avoid this boot-time crash, + * the previous booting stage can specify last HART that will jump + * to the FW_DYNAMIC firmware as the preferred boot HART. + * + * To avoid specifying a preferred boot HART, the previous booting + * stage can set it to -1UL which will force the FW_DYNAMIC firmware + * to use the relocation lottery mechanism. + */ + target_long boot_hart; +}; + +#endif -- cgit v1.1 From 8590f53661ec678fd3aa97b4da212b0c00056c2e Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Wed, 1 Jul 2020 11:39:49 -0700 Subject: RISC-V: Support 64 bit start address Even though the start address in ROM code is declared as a 64 bit address for RV64, it can't be used as upper bits are set to zero in ROM code. Update the ROM code correctly to reflect the 64bit value. Signed-off-by: Atish Patra Reviewed-by: Bin Meng Tested-by: Bin Meng Message-Id: <20200701183949.398134-5-atish.patra@wdc.com> Signed-off-by: Alistair Francis --- hw/riscv/boot.c | 6 +++++- hw/riscv/sifive_u.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index feff6e3..4c6c101 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -226,7 +226,11 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, uint32_t fdt_load_addr, void *fdt) { int i; + uint32_t start_addr_hi32 = 0x00000000; + #if defined(TARGET_RISCV64) + start_addr_hi32 = start_addr >> 32; + #endif /* reset vector */ uint32_t reset_vec[10] = { 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */ @@ -241,7 +245,7 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, #endif 0x00028067, /* jr t0 */ start_addr, /* start: .dword */ - 0x00000000, + start_addr_hi32, fdt_load_addr, /* fdt_laddr: .dword */ 0x00000000, /* fw_dyn: */ diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 46e6ed9..6595ab3f 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -378,6 +378,7 @@ static void sifive_u_machine_init(MachineState *machine) MemoryRegion *main_mem = g_new(MemoryRegion, 1); MemoryRegion *flash0 = g_new(MemoryRegion, 1); target_ulong start_addr = memmap[SIFIVE_U_DRAM].base; + uint32_t start_addr_hi32 = 0x00000000; int i; uint32_t fdt_load_addr; uint64_t kernel_entry; @@ -460,6 +461,9 @@ static void sifive_u_machine_init(MachineState *machine) /* Compute the fdt load address in dram */ fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DRAM].base, machine->ram_size, s->fdt); + #if defined(TARGET_RISCV64) + start_addr_hi32 = start_addr >> 32; + #endif /* reset vector */ uint32_t reset_vec[11] = { @@ -476,7 +480,7 @@ static void sifive_u_machine_init(MachineState *machine) #endif 0x00028067, /* jr t0 */ start_addr, /* start: .dword */ - 0x00000000, + start_addr_hi32, fdt_load_addr, /* fdt_laddr: .dword */ 0x00000000, /* fw_dyn: */ -- cgit v1.1 From 9eb8b14a70e57bc1449afc08aa4bf3131ee680d8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 9 Jul 2020 03:05:43 -0700 Subject: hw/riscv: Modify MROM size to end at 0x10000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present the size of Mask ROM for sifive_u / spike / virt machines is set to 0x11000, which ends at an unusual address. This changes the size to 0xf000 so that it ends at 0x10000. Signed-off-by: Bin Meng Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1594289144-24723-1-git-send-email-bmeng.cn@gmail.com> Signed-off-by: Alistair Francis --- hw/riscv/sifive_u.c | 2 +- hw/riscv/spike.c | 2 +- hw/riscv/virt.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 6595ab3f..19a976c 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -70,7 +70,7 @@ static const struct MemmapEntry { hwaddr size; } sifive_u_memmap[] = { [SIFIVE_U_DEBUG] = { 0x0, 0x100 }, - [SIFIVE_U_MROM] = { 0x1000, 0x11000 }, + [SIFIVE_U_MROM] = { 0x1000, 0xf000 }, [SIFIVE_U_CLINT] = { 0x2000000, 0x10000 }, [SIFIVE_U_L2LIM] = { 0x8000000, 0x2000000 }, [SIFIVE_U_PLIC] = { 0xc000000, 0x4000000 }, diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index b17d96a..7b23a29 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -52,7 +52,7 @@ static const struct MemmapEntry { hwaddr base; hwaddr size; } spike_memmap[] = { - [SPIKE_MROM] = { 0x1000, 0x11000 }, + [SPIKE_MROM] = { 0x1000, 0xf000 }, [SPIKE_CLINT] = { 0x2000000, 0x10000 }, [SPIKE_DRAM] = { 0x80000000, 0x0 }, }; diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index bc25ec6..55a907b 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -53,7 +53,7 @@ static const struct MemmapEntry { hwaddr size; } virt_memmap[] = { [VIRT_DEBUG] = { 0x0, 0x100 }, - [VIRT_MROM] = { 0x1000, 0x11000 }, + [VIRT_MROM] = { 0x1000, 0xf000 }, [VIRT_TEST] = { 0x100000, 0x1000 }, [VIRT_RTC] = { 0x101000, 0x1000 }, [VIRT_CLINT] = { 0x2000000, 0x10000 }, -- cgit v1.1 From 7acafcfa844fd93f5ff073077007627338bd6739 Mon Sep 17 00:00:00 2001 From: Frank Chang Date: Fri, 10 Jul 2020 18:48:15 +0800 Subject: target/riscv: fix rsub gvec tcg_assert_listed_vecop assertion gvec should provide vecop_list to avoid: "tcg_tcg_assert_listed_vecop: code should not be reached bug" assertion. Signed-off-by: Frank Chang Reviewed-by: Richard Henderson Message-Id: <20200710104920.13550-2-frank.chang@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rvv.inc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index dc333e6..433cdac 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -958,22 +958,27 @@ static void gen_rsub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) static void tcg_gen_gvec_rsubs(unsigned vece, uint32_t dofs, uint32_t aofs, TCGv_i64 c, uint32_t oprsz, uint32_t maxsz) { + static const TCGOpcode vecop_list[] = { INDEX_op_sub_vec, 0 }; static const GVecGen2s rsub_op[4] = { { .fni8 = gen_vec_rsub8_i64, .fniv = gen_rsub_vec, .fno = gen_helper_vec_rsubs8, + .opt_opc = vecop_list, .vece = MO_8 }, { .fni8 = gen_vec_rsub16_i64, .fniv = gen_rsub_vec, .fno = gen_helper_vec_rsubs16, + .opt_opc = vecop_list, .vece = MO_16 }, { .fni4 = gen_rsub_i32, .fniv = gen_rsub_vec, .fno = gen_helper_vec_rsubs32, + .opt_opc = vecop_list, .vece = MO_32 }, { .fni8 = gen_rsub_i64, .fniv = gen_rsub_vec, .fno = gen_helper_vec_rsubs64, + .opt_opc = vecop_list, .prefer_i64 = TCG_TARGET_REG_BITS == 64, .vece = MO_64 }, }; -- cgit v1.1 From 1989205c4e973bc7f9fac0ce0700993f30582538 Mon Sep 17 00:00:00 2001 From: Frank Chang Date: Fri, 10 Jul 2020 18:48:16 +0800 Subject: target/riscv: correct the gvec IR called in gen_vec_rsub16_i64() Signed-off-by: Frank Chang Reviewed-by: Richard Henderson Message-Id: <20200710104920.13550-3-frank.chang@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rvv.inc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 433cdac..7cd08f0 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -937,7 +937,7 @@ static void gen_vec_rsub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b) static void gen_vec_rsub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b) { - tcg_gen_vec_sub8_i64(d, b, a); + tcg_gen_vec_sub16_i64(d, b, a); } static void gen_rsub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -- cgit v1.1 From a69f97c1110205bc173657c77ce2d16877cad683 Mon Sep 17 00:00:00 2001 From: Frank Chang Date: Fri, 10 Jul 2020 18:48:17 +0800 Subject: target/riscv: fix return value of do_opivx_widen() do_opivx_widen() should return false if check function returns false. Signed-off-by: Frank Chang Reviewed-by: Richard Henderson Message-Id: <20200710104920.13550-4-frank.chang@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rvv.inc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 7cd08f0..c0b7375 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -1151,7 +1151,7 @@ static bool do_opivx_widen(DisasContext *s, arg_rmrr *a, if (opivx_widen_check(s, a)) { return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s); } - return true; + return false; } #define GEN_OPIVX_WIDEN_TRANS(NAME) \ -- cgit v1.1 From fbcbafa2c1c33ae6630e7717f7f4141befb5b31a Mon Sep 17 00:00:00 2001 From: Frank Chang Date: Fri, 10 Jul 2020 18:48:18 +0800 Subject: target/riscv: fix vill bit index in vtype register vill bit is at vtype[XLEN-1]. Signed-off-by: Frank Chang Reviewed-by: Richard Henderson Message-Id: <20200710104920.13550-5-frank.chang@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index eef20ca..a804a5d 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -98,7 +98,7 @@ FIELD(VTYPE, VLMUL, 0, 2) FIELD(VTYPE, VSEW, 2, 3) FIELD(VTYPE, VEDIV, 5, 2) FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9) -FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 2, 1) +FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1) struct CPURISCVState { target_ulong gpr[32]; -- cgit v1.1 From 940aabb9f47712da87182fee7163f1d3f7def36d Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Thu, 9 Jul 2020 15:04:48 -0700 Subject: hw/char: Convert the Ibex UART to use the qdev Clock model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conver the Ibex UART to use the recently added qdev-clock functions. Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Message-id: b0136fad870a29049959ec161c1217b967d7e19d.1594332223.git.alistair.francis@wdc.com Message-Id: --- hw/char/ibex_uart.c | 30 +++++++++++++++++++++++++++--- include/hw/char/ibex_uart.h | 3 +++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c index 45cd724..ab6247d 100644 --- a/hw/char/ibex_uart.c +++ b/hw/char/ibex_uart.c @@ -28,6 +28,7 @@ #include "qemu/osdep.h" #include "hw/char/ibex_uart.h" #include "hw/irq.h" +#include "hw/qdev-clock.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/log.h" @@ -203,6 +204,17 @@ static void ibex_uart_reset(DeviceState *dev) ibex_uart_update_irqs(s); } +static uint64_t ibex_uart_get_baud(IbexUartState *s) +{ + uint64_t baud; + + baud = ((s->uart_ctrl & UART_CTRL_NCO) >> 16); + baud *= clock_get_hz(s->f_clk); + baud >>= 20; + + return baud; +} + static uint64_t ibex_uart_read(void *opaque, hwaddr addr, unsigned int size) { @@ -329,9 +341,7 @@ static void ibex_uart_write(void *opaque, hwaddr addr, "%s: UART_CTRL_RXBLVL is not supported\n", __func__); } if (value & UART_CTRL_NCO) { - uint64_t baud = ((value & UART_CTRL_NCO) >> 16); - baud *= 1000; - baud >>= 20; + uint64_t baud = ibex_uart_get_baud(s); s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10; } @@ -385,6 +395,16 @@ static void ibex_uart_write(void *opaque, hwaddr addr, } } +static void ibex_uart_clk_update(void *opaque) +{ + IbexUartState *s = opaque; + + /* recompute uart's speed on clock change */ + uint64_t baud = ibex_uart_get_baud(s); + + s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10; +} + static void fifo_trigger_update(void *opaque) { IbexUartState *s = opaque; @@ -444,6 +464,10 @@ static void ibex_uart_init(Object *obj) { IbexUartState *s = IBEX_UART(obj); + s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock", + ibex_uart_clk_update, s); + clock_set_hz(s->f_clk, IBEX_UART_CLOCK); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty); diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h index 2bec772..6d81051 100644 --- a/include/hw/char/ibex_uart.h +++ b/include/hw/char/ibex_uart.h @@ -72,6 +72,7 @@ #define IBEX_UART_TIMEOUT_CTRL 0x2c #define IBEX_UART_TX_FIFO_SIZE 16 +#define IBEX_UART_CLOCK 50000000 /* 50MHz clock */ #define TYPE_IBEX_UART "ibex-uart" #define IBEX_UART(obj) \ @@ -101,6 +102,8 @@ typedef struct { uint32_t uart_val; uint32_t uart_timeout_ctrl; + Clock *f_clk; + CharBackend chr; qemu_irq tx_watermark; qemu_irq rx_watermark; -- cgit v1.1 From 59093cc407cb044c72aa786006a07bd404eb36b9 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Thu, 9 Jul 2020 15:04:51 -0700 Subject: hw/char: Convert the Ibex UART to use the registerfields API Signed-off-by: Alistair Francis Message-id: 06372c9cdeec715077899e71c858d9f0a2a3395b.1594332223.git.alistair.francis@wdc.com Message-Id: <06372c9cdeec715077899e71c858d9f0a2a3395b.1594332223.git.alistair.francis@wdc.com> --- hw/char/ibex_uart.c | 130 ++++++++++++++++++++++---------------------- include/hw/char/ibex_uart.h | 76 ++++++++++++-------------- 2 files changed, 100 insertions(+), 106 deletions(-) diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c index ab6247d..cc49a35 100644 --- a/hw/char/ibex_uart.c +++ b/hw/char/ibex_uart.c @@ -36,25 +36,25 @@ static void ibex_uart_update_irqs(IbexUartState *s) { - if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_WATERMARK) { + if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_WATERMARK_MASK) { qemu_set_irq(s->tx_watermark, 1); } else { qemu_set_irq(s->tx_watermark, 0); } - if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_WATERMARK) { + if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_RX_WATERMARK_MASK) { qemu_set_irq(s->rx_watermark, 1); } else { qemu_set_irq(s->rx_watermark, 0); } - if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) { + if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_EMPTY_MASK) { qemu_set_irq(s->tx_empty, 1); } else { qemu_set_irq(s->tx_empty, 0); } - if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) { + if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_RX_OVERFLOW_MASK) { qemu_set_irq(s->rx_overflow, 1); } else { qemu_set_irq(s->rx_overflow, 0); @@ -65,7 +65,7 @@ static int ibex_uart_can_receive(void *opaque) { IbexUartState *s = opaque; - if (s->uart_ctrl & UART_CTRL_RX_ENABLE) { + if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) { return 1; } @@ -75,16 +75,16 @@ static int ibex_uart_can_receive(void *opaque) static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size) { IbexUartState *s = opaque; - uint8_t rx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_RXILVL) - >> FIFO_CTRL_RXILVL_SHIFT; + uint8_t rx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_RXILVL_MASK) + >> R_FIFO_CTRL_RXILVL_SHIFT; s->uart_rdata = *buf; - s->uart_status &= ~UART_STATUS_RXIDLE; - s->uart_status &= ~UART_STATUS_RXEMPTY; + s->uart_status &= ~R_STATUS_RXIDLE_MASK; + s->uart_status &= ~R_STATUS_RXEMPTY_MASK; if (size > rx_fifo_level) { - s->uart_intr_state |= INTR_STATE_RX_WATERMARK; + s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK; } ibex_uart_update_irqs(s); @@ -94,8 +94,8 @@ static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) { IbexUartState *s = opaque; - uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL) - >> FIFO_CTRL_TXILVL_SHIFT; + uint8_t tx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_TXILVL_MASK) + >> R_FIFO_CTRL_TXILVL_SHIFT; int ret; /* instant drain the fifo when there's no back-end */ @@ -105,10 +105,10 @@ static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond, } if (!s->tx_level) { - s->uart_status &= ~UART_STATUS_TXFULL; - s->uart_status |= UART_STATUS_TXEMPTY; - s->uart_intr_state |= INTR_STATE_TX_EMPTY; - s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK; + s->uart_status &= ~R_STATUS_TXFULL_MASK; + s->uart_status |= R_STATUS_TXEMPTY_MASK; + s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK; + s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK; ibex_uart_update_irqs(s); return FALSE; } @@ -131,18 +131,18 @@ static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond, /* Clear the TX Full bit */ if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) { - s->uart_status &= ~UART_STATUS_TXFULL; + s->uart_status &= ~R_STATUS_TXFULL_MASK; } /* Disable the TX_WATERMARK IRQ */ if (s->tx_level < tx_fifo_level) { - s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK; + s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK; } /* Set TX empty */ if (s->tx_level == 0) { - s->uart_status |= UART_STATUS_TXEMPTY; - s->uart_intr_state |= INTR_STATE_TX_EMPTY; + s->uart_status |= R_STATUS_TXEMPTY_MASK; + s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK; } ibex_uart_update_irqs(s); @@ -153,8 +153,8 @@ static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf, int size) { uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL) - >> FIFO_CTRL_TXILVL_SHIFT; + uint8_t tx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_TXILVL_MASK) + >> R_FIFO_CTRL_TXILVL_SHIFT; if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) { size = IBEX_UART_TX_FIFO_SIZE - s->tx_level; @@ -165,16 +165,16 @@ static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf, s->tx_level += size; if (s->tx_level > 0) { - s->uart_status &= ~UART_STATUS_TXEMPTY; + s->uart_status &= ~R_STATUS_TXEMPTY_MASK; } if (s->tx_level >= tx_fifo_level) { - s->uart_intr_state |= INTR_STATE_TX_WATERMARK; + s->uart_intr_state |= R_INTR_STATE_TX_WATERMARK_MASK; ibex_uart_update_irqs(s); } if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) { - s->uart_status |= UART_STATUS_TXFULL; + s->uart_status |= R_STATUS_TXFULL_MASK; } timer_mod(s->fifo_trigger_handle, current_time + @@ -208,7 +208,7 @@ static uint64_t ibex_uart_get_baud(IbexUartState *s) { uint64_t baud; - baud = ((s->uart_ctrl & UART_CTRL_NCO) >> 16); + baud = ((s->uart_ctrl & R_CTRL_NCO_MASK) >> 16); baud *= clock_get_hz(s->f_clk); baud >>= 20; @@ -221,43 +221,43 @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr, IbexUartState *s = opaque; uint64_t retvalue = 0; - switch (addr) { - case IBEX_UART_INTR_STATE: + switch (addr >> 2) { + case R_INTR_STATE: retvalue = s->uart_intr_state; break; - case IBEX_UART_INTR_ENABLE: + case R_INTR_ENABLE: retvalue = s->uart_intr_enable; break; - case IBEX_UART_INTR_TEST: + case R_INTR_TEST: qemu_log_mask(LOG_GUEST_ERROR, "%s: wdata is write only\n", __func__); break; - case IBEX_UART_CTRL: + case R_CTRL: retvalue = s->uart_ctrl; break; - case IBEX_UART_STATUS: + case R_STATUS: retvalue = s->uart_status; break; - case IBEX_UART_RDATA: + case R_RDATA: retvalue = s->uart_rdata; - if (s->uart_ctrl & UART_CTRL_RX_ENABLE) { + if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) { qemu_chr_fe_accept_input(&s->chr); - s->uart_status |= UART_STATUS_RXIDLE; - s->uart_status |= UART_STATUS_RXEMPTY; + s->uart_status |= R_STATUS_RXIDLE_MASK; + s->uart_status |= R_STATUS_RXEMPTY_MASK; } break; - case IBEX_UART_WDATA: + case R_WDATA: qemu_log_mask(LOG_GUEST_ERROR, "%s: wdata is write only\n", __func__); break; - case IBEX_UART_FIFO_CTRL: + case R_FIFO_CTRL: retvalue = s->uart_fifo_ctrl; break; - case IBEX_UART_FIFO_STATUS: + case R_FIFO_STATUS: retvalue = s->uart_fifo_status; retvalue |= s->tx_level & 0x1F; @@ -266,17 +266,17 @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr, "%s: RX fifos are not supported\n", __func__); break; - case IBEX_UART_OVRD: + case R_OVRD: retvalue = s->uart_ovrd; qemu_log_mask(LOG_UNIMP, "%s: ovrd is not supported\n", __func__); break; - case IBEX_UART_VAL: + case R_VAL: retvalue = s->uart_val; qemu_log_mask(LOG_UNIMP, "%s: val is not supported\n", __func__); break; - case IBEX_UART_TIMEOUT_CTRL: + case R_TIMEOUT_CTRL: retvalue = s->uart_timeout_ctrl; qemu_log_mask(LOG_UNIMP, "%s: timeout_ctrl is not supported\n", __func__); @@ -296,95 +296,95 @@ static void ibex_uart_write(void *opaque, hwaddr addr, IbexUartState *s = opaque; uint32_t value = val64; - switch (addr) { - case IBEX_UART_INTR_STATE: + switch (addr >> 2) { + case R_INTR_STATE: /* Write 1 clear */ s->uart_intr_state &= ~value; ibex_uart_update_irqs(s); break; - case IBEX_UART_INTR_ENABLE: + case R_INTR_ENABLE: s->uart_intr_enable = value; ibex_uart_update_irqs(s); break; - case IBEX_UART_INTR_TEST: + case R_INTR_TEST: s->uart_intr_state |= value; ibex_uart_update_irqs(s); break; - case IBEX_UART_CTRL: + case R_CTRL: s->uart_ctrl = value; - if (value & UART_CTRL_NF) { + if (value & R_CTRL_NF_MASK) { qemu_log_mask(LOG_UNIMP, "%s: UART_CTRL_NF is not supported\n", __func__); } - if (value & UART_CTRL_SLPBK) { + if (value & R_CTRL_SLPBK_MASK) { qemu_log_mask(LOG_UNIMP, "%s: UART_CTRL_SLPBK is not supported\n", __func__); } - if (value & UART_CTRL_LLPBK) { + if (value & R_CTRL_LLPBK_MASK) { qemu_log_mask(LOG_UNIMP, "%s: UART_CTRL_LLPBK is not supported\n", __func__); } - if (value & UART_CTRL_PARITY_EN) { + if (value & R_CTRL_PARITY_EN_MASK) { qemu_log_mask(LOG_UNIMP, "%s: UART_CTRL_PARITY_EN is not supported\n", __func__); } - if (value & UART_CTRL_PARITY_ODD) { + if (value & R_CTRL_PARITY_ODD_MASK) { qemu_log_mask(LOG_UNIMP, "%s: UART_CTRL_PARITY_ODD is not supported\n", __func__); } - if (value & UART_CTRL_RXBLVL) { + if (value & R_CTRL_RXBLVL_MASK) { qemu_log_mask(LOG_UNIMP, "%s: UART_CTRL_RXBLVL is not supported\n", __func__); } - if (value & UART_CTRL_NCO) { + if (value & R_CTRL_NCO_MASK) { uint64_t baud = ibex_uart_get_baud(s); s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10; } break; - case IBEX_UART_STATUS: + case R_STATUS: qemu_log_mask(LOG_GUEST_ERROR, "%s: status is read only\n", __func__); break; - case IBEX_UART_RDATA: + case R_RDATA: qemu_log_mask(LOG_GUEST_ERROR, "%s: rdata is read only\n", __func__); break; - case IBEX_UART_WDATA: + case R_WDATA: uart_write_tx_fifo(s, (uint8_t *) &value, 1); break; - case IBEX_UART_FIFO_CTRL: + case R_FIFO_CTRL: s->uart_fifo_ctrl = value; - if (value & FIFO_CTRL_RXRST) { + if (value & R_FIFO_CTRL_RXRST_MASK) { qemu_log_mask(LOG_UNIMP, "%s: RX fifos are not supported\n", __func__); } - if (value & FIFO_CTRL_TXRST) { + if (value & R_FIFO_CTRL_TXRST_MASK) { s->tx_level = 0; } break; - case IBEX_UART_FIFO_STATUS: + case R_FIFO_STATUS: qemu_log_mask(LOG_GUEST_ERROR, "%s: fifo_status is read only\n", __func__); break; - case IBEX_UART_OVRD: + case R_OVRD: s->uart_ovrd = value; qemu_log_mask(LOG_UNIMP, "%s: ovrd is not supported\n", __func__); break; - case IBEX_UART_VAL: + case R_VAL: qemu_log_mask(LOG_GUEST_ERROR, "%s: val is read only\n", __func__); break; - case IBEX_UART_TIMEOUT_CTRL: + case R_TIMEOUT_CTRL: s->uart_timeout_ctrl = value; qemu_log_mask(LOG_UNIMP, "%s: timeout_ctrl is not supported\n", __func__); @@ -409,7 +409,7 @@ static void fifo_trigger_update(void *opaque) { IbexUartState *s = opaque; - if (s->uart_ctrl & UART_CTRL_TX_ENABLE) { + if (s->uart_ctrl & R_CTRL_TX_ENABLE_MASK) { ibex_uart_xmit(NULL, G_IO_OUT, s); } } diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h index 6d81051..b6bd5a6 100644 --- a/include/hw/char/ibex_uart.h +++ b/include/hw/char/ibex_uart.h @@ -26,50 +26,44 @@ #define HW_IBEX_UART_H #include "hw/sysbus.h" +#include "hw/registerfields.h" #include "chardev/char-fe.h" #include "qemu/timer.h" -#define IBEX_UART_INTR_STATE 0x00 - #define INTR_STATE_TX_WATERMARK (1 << 0) - #define INTR_STATE_RX_WATERMARK (1 << 1) - #define INTR_STATE_TX_EMPTY (1 << 2) - #define INTR_STATE_RX_OVERFLOW (1 << 3) -#define IBEX_UART_INTR_ENABLE 0x04 -#define IBEX_UART_INTR_TEST 0x08 - -#define IBEX_UART_CTRL 0x0c - #define UART_CTRL_TX_ENABLE (1 << 0) - #define UART_CTRL_RX_ENABLE (1 << 1) - #define UART_CTRL_NF (1 << 2) - #define UART_CTRL_SLPBK (1 << 4) - #define UART_CTRL_LLPBK (1 << 5) - #define UART_CTRL_PARITY_EN (1 << 6) - #define UART_CTRL_PARITY_ODD (1 << 7) - #define UART_CTRL_RXBLVL (3 << 8) - #define UART_CTRL_NCO (0xFFFF << 16) - -#define IBEX_UART_STATUS 0x10 - #define UART_STATUS_TXFULL (1 << 0) - #define UART_STATUS_RXFULL (1 << 1) - #define UART_STATUS_TXEMPTY (1 << 2) - #define UART_STATUS_RXIDLE (1 << 4) - #define UART_STATUS_RXEMPTY (1 << 5) - -#define IBEX_UART_RDATA 0x14 -#define IBEX_UART_WDATA 0x18 - -#define IBEX_UART_FIFO_CTRL 0x1c - #define FIFO_CTRL_RXRST (1 << 0) - #define FIFO_CTRL_TXRST (1 << 1) - #define FIFO_CTRL_RXILVL (7 << 2) - #define FIFO_CTRL_RXILVL_SHIFT (2) - #define FIFO_CTRL_TXILVL (3 << 5) - #define FIFO_CTRL_TXILVL_SHIFT (5) - -#define IBEX_UART_FIFO_STATUS 0x20 -#define IBEX_UART_OVRD 0x24 -#define IBEX_UART_VAL 0x28 -#define IBEX_UART_TIMEOUT_CTRL 0x2c +REG32(INTR_STATE, 0x00) + FIELD(INTR_STATE, TX_WATERMARK, 0, 1) + FIELD(INTR_STATE, RX_WATERMARK, 1, 1) + FIELD(INTR_STATE, TX_EMPTY, 2, 1) + FIELD(INTR_STATE, RX_OVERFLOW, 3, 1) +REG32(INTR_ENABLE, 0x04) +REG32(INTR_TEST, 0x08) +REG32(CTRL, 0x0C) + FIELD(CTRL, TX_ENABLE, 0, 1) + FIELD(CTRL, RX_ENABLE, 1, 1) + FIELD(CTRL, NF, 2, 1) + FIELD(CTRL, SLPBK, 4, 1) + FIELD(CTRL, LLPBK, 5, 1) + FIELD(CTRL, PARITY_EN, 6, 1) + FIELD(CTRL, PARITY_ODD, 7, 1) + FIELD(CTRL, RXBLVL, 8, 2) + FIELD(CTRL, NCO, 16, 16) +REG32(STATUS, 0x10) + FIELD(STATUS, TXFULL, 0, 1) + FIELD(STATUS, RXFULL, 1, 1) + FIELD(STATUS, TXEMPTY, 2, 1) + FIELD(STATUS, RXIDLE, 4, 1) + FIELD(STATUS, RXEMPTY, 5, 1) +REG32(RDATA, 0x14) +REG32(WDATA, 0x18) +REG32(FIFO_CTRL, 0x1c) + FIELD(FIFO_CTRL, RXRST, 0, 1) + FIELD(FIFO_CTRL, TXRST, 1, 1) + FIELD(FIFO_CTRL, RXILVL, 2, 3) + FIELD(FIFO_CTRL, TXILVL, 5, 2) +REG32(FIFO_STATUS, 0x20) +REG32(OVRD, 0x24) +REG32(VAL, 0x28) +REG32(TIMEOUT_CTRL, 0x2c) #define IBEX_UART_TX_FIFO_SIZE 16 #define IBEX_UART_CLOCK 50000000 /* 50MHz clock */ -- cgit v1.1 From 895bfa84fec27899bf8e8c17f46358d31df2ab4f Mon Sep 17 00:00:00 2001 From: Liao Pingfang Date: Mon, 13 Jul 2020 08:33:41 +0800 Subject: tcg/riscv: Remove superfluous breaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove superfluous breaks, as there is a "return" before them. Signed-off-by: Liao Pingfang Signed-off-by: Yi Wang Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Reviewed-by: Alistair Francis Message-Id: <1594600421-22942-1-git-send-email-wang.yi59@zte.com.cn> Signed-off-by: Alistair Francis --- tcg/riscv/tcg-target.inc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c index 2bc0ba71..3c11ab8 100644 --- a/tcg/riscv/tcg-target.inc.c +++ b/tcg/riscv/tcg-target.inc.c @@ -502,10 +502,8 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type, break; case R_RISCV_JAL: return reloc_jimm20(code_ptr, (tcg_insn_unit *)value); - break; case R_RISCV_CALL: return reloc_call(code_ptr, (tcg_insn_unit *)value); - break; default: tcg_abort(); } -- cgit v1.1 From cfad709bceb629a4ebeb5d8a3acd1871b9a6436b Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Mon, 6 Jul 2020 10:45:50 +0200 Subject: target/riscv: Fix pmp NA4 implementation The end address calculation for NA4 mode is wrong because the address used isn't shifted. It doesn't watch 4 bytes but a huge range because the end address calculation is wrong. The solution is to use the shifted address calculated for start address variable. Modifications are tested on Zephyr OS userspace test suite which works for other RISC-V boards (E31 and E34 core). Signed-off-by: Alexandre Mergnat Reviewed-by: Alistair Francis Message-id: 20200706084550.24117-1-amergnat@baylibre.com Message-Id: <20200706084550.24117-1-amergnat@baylibre.com> [ Changes by AF: - Improve the commit title and message ] Signed-off-by: Alistair Francis --- target/riscv/pmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 9418660..2a2b9f5 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -171,7 +171,7 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index) case PMP_AMATCH_NA4: sa = this_addr << 2; /* shift up from [xx:0] to [xx+2:2] */ - ea = (this_addr + 4u) - 1u; + ea = (sa + 4u) - 1u; break; case PMP_AMATCH_NAPOT: -- cgit v1.1