最新のSpikeの実装にアップデートして、PLICとCLINTを動かすためにいろいろやってみる。
LiteXのBIOSを動かしたくて、いろいろやっている。
../spike_dpi/riscv-isa-sim/spike -l --log-commits --dtb=../dts/rv64imafdc.dtb --pc=0 -m0x0:0x100000,0x10000000:0x1000000 ../tests/litex_soc/software/bios/bios.elf
rv64imafdc.dts
は以下のようにして、PLICとCLINTを認識させている。こうしないと、SpikeがPLICとCLINTを識別してくれない。
soc { #address-cells = <2>; #size-cells = <2>; compatible = "ucbbar,spike-bare-soc", "simple-bus"; ranges; clint@2000000 { compatible = "riscv,clint0"; interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7 >; reg = <0x0 0x2000000 0x0 0xc0000>; }; PLIC: plic@c000000 { compatible = "riscv,plic0"; #address-cells = <2>; interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 >; reg = <0x0 0xc000000 0x0 0x1000000>; riscv,ndev = <0x1f>; riscv,max-priority = <0xf>; #interrupt-cells = <1>; interrupt-controller; }; };
それでも、0x5b90へのアクセスでトラップが発生してしまう。ここは、アクセス許可しているはずなんだけど...
core 0: 0x0000000000000124 (0x00628c63) beq t0, t1, pc + 24 core 0: 3 0x0000000000000124 (0x00628c63) core 0: 0x0000000000000128 (0x0003be03) ld t3, 0(t2) core 0: exception trap_load_access_fault, epc 0x0000000000000128 core 0: tval 0x0000000000005b90 core 0: >>>> trap_entry core 0: 0x0000000000000020 (0xfe113c23) sd ra, -8(sp) core 0: 3 0x0000000000000020 (0xfe113c23) mem 0x0000000010001ff8 0x0000000000000000 core 0: 0x0000000000000024 (0xfe513823) sd t0, -16(sp) core 0: 3 0x0000000000000024 (0xfe513823) mem 0x0000000010001ff0 0x0000000010000000 core 0: 0x0000000000000028 (0xfe613423) sd t1, -24(sp) core 0: 3 0x0000000000000028 (0xfe613423) mem 0x0000000010001fe8 0x00000000100001e0 core 0: 0x000000000000002c (0xfe713023) sd t2, -32(sp) core 0: 3 0x000000000000002c (0xfe713023) mem 0x0000000010001fe0 0x0000000000005b90 core 0: 0x0000000000000030 (0xfca13c23) sd a0, -40(sp) core 0: 3 0x0000000000000030 (0xfca13c23) mem 0x0000000010001fd8 0x0000000000000000
これはいろいろ調べたら、デバイスの登録順序に基づくメモリアクセス領域のオーバラップによるものだった。
0x0000:0x10000
にメモリを登録した後、ブートROMとして0x1000
を登録して、0x5000あたりを検索すると0x1000
のブートROMが引っかかってアクセスエラーとなる。
これの解決策としては、ハードコードされたメモリアクセス領域を無理やり変更して、自分の所望のメモリマップにするしかない。
diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 1a0c8307..8d2c8c76 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -121,9 +121,9 @@ reg_t reg_from_bytes(size_t len, const uint8_t* bytes) bool mmu_t::mmio_ok(reg_t paddr, access_type UNUSED type) { - // Disallow access to debug region when not in debug mode - if (paddr >= DEBUG_START && paddr <= DEBUG_END && proc && !proc->state.debug_mode) - return false; + // // Disallow access to debug region when not in debug mode + // if (addr >= DEBUG_START && addr <= DEBUG_END && proc && !proc->state.debug_mode) + // return false; return true; } diff --git a/riscv/platform.h b/riscv/platform.h index 7fffdc84..d85e271f 100644 --- a/riscv/platform.h +++ b/riscv/platform.h @@ -3,7 +3,7 @@ #define _RISCV_PLATFORM_H #define DEFAULT_KERNEL_BOOTARGS "console=ttyS0 earlycon" -#define DEFAULT_RSTVEC 0x00001000 +#define DEFAULT_RSTVEC 0x20000000 #define CLINT_BASE 0x02000000 #define CLINT_SIZE 0x000c0000 #define PLIC_BASE 0x0c000000 @@ -16,6 +16,6 @@ #define NS16550_REG_IO_WIDTH 1 #define NS16550_INTERRUPT_ID 1 #define EXT_IO_BASE 0x40000000 -#define DRAM_BASE 0x80000000 +#define DRAM_BASE 0x00000000 #endif diff --git a/riscv/sim.cc b/riscv/sim.cc index f4919c91..f005db9b 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -69,7 +69,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, for (auto& x : mems) bus.add_device(x.first, x.second); - bus.add_device(DEBUG_START, &debug_module); + // bus.add_device(DEBUG_START, &debug_module); socketif = NULL; #ifdef HAVE_BOOST_ASIO
これで一応メモリアクセスエラーを回避して進めることができるようになった。 しかし、新しいSpikeはハードコードな部分が結構あって、面倒くさいな...