FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages/

Freedom-U-SDKで生成したLinuxバイナリを自作RISC-Vシミュレータで実行 (3. シェル実行)

HiFive Unleashedは高くて買えないのだけれども、RISC-V SDKであるFreedom-U-SDKを使ってみることにした。

自作RISC-Vシミュレータを使ってRISC-VのLinuxをブートさせたいのだけれども、なかなか動作しないので四苦八苦していた。 #自作RISC-Vシミュレータは、そのうちGitHubに公開できるように調整中。

ログイン画面までは動いていたのだが、キー入力がうまくいかなくてそこから先に進んでいなかったのだった。 ターミナルののモジュールとか、Spikeとの動作の違いを見ながら進めていった結果、ログインしてからシェルが動くようになったぞ!

f:id:msyksphinz:20180829230543g:plain
図. 自作RISC-VシミュレータでLinuxを立ち上げログイン・シェルを動かす。

肝となったのは、デバイスにコマンドを渡すときにデバイスIDも一緒に渡すのだが、デバイスの処理が完了した際にFromHostにデータを戻すとき、同様にどのデバイスからのデータであるかを示さなければならないということだ。これを間違えていたため、いつまでたってもキーボードの入力値を受け付けなかった。

  void StdInRead () {
    int read_data;
    // DWord_t fromhost;
    // GetPeThread()->LoadFrom_FromHost (&fromhost);
    // if (fromhost == 0) {
    if ((m_req_count > 0) &&
        ((read_data = read()) != -1)) {
      read_data = 0x100 | read_data;

      // デバイスIDも一緒にFromHostに返す。
      uint64_t resp_data = static_cast<uint64_t>(GetDevId()) << 56 | read_data;
      GetPeThread()->StoreTo_FromHost (resp_data);
      GetPeThread()->DebugPrint("<Info: Tick read enable() = %x, resp_data = %016lx>\n", read_data, resp_data);
      m_req_count--;
      //}
    }
  }

とりあえずシミュレータのメンテナンスはここまでで終了かな。もう少し高速化しなければ... そのためには、今一番足かせになっているメモリアクセスのルーチンを高速化しなければ。

Google Perftoolsで解析すると、以下のようになっている。やはり、メモリアクセスが遅いんだな。

(pprof) top
Total: 19415 samples
    3750  19.3%  19.3%     5083  26.2% Memory::LoadMemory
    3088  15.9%  35.2%     6920  35.6% RiscvPeThread::WalkPageTable
    1457   7.5%  42.7%    19198  98.9% RiscvPeThread::StepExec
    1384   7.1%  49.9%     9034  46.5% RiscvPeThread::FetchMemory
    1185   6.1%  56.0%     1185   6.1% CsrEnv::Riscv_Read_CSR
    1173   6.0%  62.0%     1173   6.0% RiscvDec::DecodeInst
     872   4.5%  66.5%      872   4.5% __memmove_avx_unaligned_erms
     768   4.0%  70.4%      768   4.0% TraceInfo::RecordTrace
     543   2.8%  73.2%     2056  10.6% RiscvPeThread::CheckInterrupt
     397   2.0%  75.3%     3561  18.3% EnvBase::LoadMemoryDebug