RISC-Vのページテーブルを作っていて、riscv_testsでテストしようとしたのだがつまづいた。
vmモードのテストパタンでは、実際のテストを実行する前に、テストパタン上でページテーブルを作成している。 それが、vm_bootとよばれる関数だ。
void vm_boot(long test_addr, long seed) { if (read_csr(mhartid) > 0) coherence_torture(); assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t)); #if MAX_TEST_PAGES > PTES_PER_PT # error #endif // map kernel to uppermost megapage l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE; kernel_l2pt[PTES_PER_PT-1] = ((pte_t)kernel_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE; // map user to lowermost megapage l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE; user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE; write_csr(sptbr, l1pt);
この関数のなかで、Sv39と呼ばれるページテーブルの変換アルゴリズムの設定と、ページテーブルの作成を行っているのだが、ここでつまづいた。 テストパタンでは、この関数自体が0x2560に配置されており、このままではmstatusを設定してSv39を有効にすると、vpt[2]の領域にテーブルをアクセスしに行ってします。 しかし、ここで設定しているのはl1pt[0]とl1pt[PTES_PER_PT-1]だけだ。これではl1pt[2]にアクセスできない。
とりあえずISSの実装はここをクリアすればコミットできるレベルなのだが、これが解決できない限りはちゃんとした実装にならない。RISC-Vコミュニティに質問を送ってみたので、回答が分かればブログに追記しよう。