FPGA開発日記

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

RISC-V Testに実装されているページテーブルの実装を調査する (3. 仮想アドレスからのジャンプを調査する)

riscv-testsには、もう一つ、vm.cevict()という関数が用意されている。evict()はどうもECALLが呼び出されたときに実行されるようだ。ECALLはテストパタンが終了したときに呼ばれるので、最後の処理に使用されるようだ。

void handle_trap(trapframe_t* tf)
{
  if (tf->cause == CAUSE_USER_ECALL)
  {
    int n = tf->gpr[10];

    for (long i = 1; i < MAX_TEST_PAGES; i++)
      evict(i*PGSIZE);

    terminate(n);
  }

最後にterminate()が呼び出されるので、終了前の処理であることは間違いない。evict()なので読みだしたページテーブルを吐き出しているのだろうけども、良く分からないのがmemcpyの方向がページテーブル割り当ての時と同じこと。カーネルモードのアドレスと、ユーザモードのアドレスが一致している場合にはmemcpy()は実行しないが一致していない場合にはmemcpy()でデータをコピーする。

static void evict(unsigned long addr)
{
  assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
  addr = addr/PGSIZE*PGSIZE;

  freelist_t* node = &user_mapping[addr/PGSIZE];
  if (node->addr)
  {
    // check accessed and dirty bits
    assert(user_l3pt[addr/PGSIZE] & PTE_A);
    uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
    if (memcmp((void*)addr, uva2kva(addr), PGSIZE)) {
      assert(user_l3pt[addr/PGSIZE] & PTE_D);
      memcpy((void*)addr, uva2kva(addr), PGSIZE);
    }
    write_csr(sstatus, sstatus);
    /* ... 中略 ... */
      

ログを見てみると、0xffffから始まるユーザモードから、0x0000から始まるカーネルモードへのコピーをしているようだ。

     13430:S:Sv39:ffffffffffe027b0:P0000800027b0:000d8593:addi       x11,x27,0x000        :x27=>ffffffffffe04000 x11<=ffffffffffe04000 
     13431:S:Sv39:ffffffffffe027b4:P0000800027b4:00040513:addi       x10,x08,0x000        :x08=>0000000000004000 x10<=0000000000004000 
     13432:S:Sv39:ffffffffffe027b8:P0000800027b8:849ff0ef:jal        x01,43231            :x01<=ffffffffffe027bc pc<=ffffffffffe02000 
     // x10 = カーネルモードでのメモリ領域
     // x11 = ユーザモードでのメモリ領域

新たに割り当てたNew Pageからカーネルの用意しているページへデータを書き戻しているものと思われる、が、新たに確保したページ側に書き戻しているのはなんでだ?

     13441:S:Sv39:ffffffffffe02044:P000080002044:ff85b703:ld         x14,0xff8(x11)       :x11=>ffffffffffe04008 (0000000080004000)=>deadbeefdeadbeef x14<=deadbeefdeadbeef 
     13443:S:Sv39:ffffffffffe0204c:P00008000204c:fee7bc23:sd         x14,0xff8(x15)       :x15=>0000000000004008 x14=>deadbeefdeadbeef (0000000080064000)<=deadbeefdeadbeef