FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-VのPLICのためのテストケースを作って、Spikeの挙動を解析する

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

前回まででPLICについては結構仕様を勉強して、じゃあ次にRTLを作ってみて、テストしてみようということになったのだが、 とりあえず簡単なテストを動かしてみたい。PLICのメモリマップは0xc00_0000なので、ここにアクセスする簡単なテストパタンを作ってみる。

#define PLIC_BASE_ADDR         0xc000000
#define PLIC_SOURCE_BASE_ADDR  (PLIC_BASE_ADDR)
#define PLIC_PENDING_BASE_ADDR (PLIC_BASE_ADDR + 0x1000)
#define PLIC_ENABLE_BASE_ADDR  (PLIC_BASE_ADDR + 0x2000)
#define PLIC_THRESHOLD_ADDR    (PLIC_BASE_ADDR + 0x200000)

int plic_reg_rw_test()
{
  *((volatile unsigned int *)(PLIC_SOURCE_BASE_ADDR)) = 0xdeadbeef;
  *(volatile unsigned int *)(PLIC_SOURCE_BASE_ADDR);

  *((volatile unsigned int *)(PLIC_PENDING_BASE_ADDR)) = 0xdeadbeef;
  *(volatile unsigned int *)(PLIC_PENDING_BASE_ADDR);

  return 0;
}

が、Spikeの挙動が異なっており、Spikeは当該メモリ領域へのメモリアクセスは例外処理になっていた。

core   0: 3 0x00000000800025f0 (0x4581) x11 0x0000000000000000
core   0: 3 0x00000000800025f2 (0x4501) x10 0x0000000000000000
core   0: 3 0x00000000800025f4 (0x142000ef) x 1 0x00000000800025f8
core   0: 3 0x0000000080002736 (0xdeadc7b7) x15 0xffffffffdeadc000
core   0: 3 0x000000008000273a (0xeef78793) x15 0xffffffffdeadbeef
core   0: 3 0x000000008000273e (0x0c0006b7) x13 0x000000000c000000
// 0xc00_0000へのメモリストアを試行した
// ここで例外が発生している
core   0: 3 0x0000000080000090 (0x716d) x 2 0x0000000080022780
core   0: 3 0x0000000080000092 (0xe406) mem 0x0000000080022788 0x00000000800025f8
core   0: 3 0x0000000080000094 (0xe80a) mem 0x0000000080022790 0x0000000080022780
core   0: 3 0x0000000080000096 (0xec0e) mem 0x0000000080022798 0x0000000080002f70
core   0: 3 0x0000000080000098 (0xf012) mem 0x00000000800227a0 0x0000000080002940
core   0: 3 0x000000008000009a (0xf416) mem 0x00000000800227a8 0x0000000080000090
core   0: 3 0x000000008000009c (0xf81a) mem 0x00000000800227b0 0x0000000000000000
core   0: 3 0x000000008000009e (0xfc1e) mem 0x00000000800227b8 0x0000000000000000
core   0: 3 0x00000000800000a0 (0xe0a2) mem 0x00000000800227c0 0x0000000000000000

これをどうやって直せばいいのかすっかり忘れていたのだが、とりあえずDTSを改造してみても駄目なようだ。 これはDTSを追加するだけではなく、ちゃんとデバイスを追加しないと駄目なようだ。CLINTがその例である。

   void *fdt = (void *)dtb.c_str();
   //handle clic
   clint.reset(new clint_t(procs, CPU_HZ / INSNS_PER_RTC_TICK, real_time_clint));
   reg_t clint_base;
   if (fdt_parse_clint(fdt, &clint_base, "riscv,clint0")) {
     bus.add_device(CLINT_BASE, clint.get());
   } else {
     bus.add_device(clint_base, clint.get());
   }

したがって、同じようにPLICの領域に仮想的なデバイスを作って追加する必要があるようだ。Spikeの挙動をやっと理解できるようになってきた。