FPGA開発日記

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

Linux on RISC-V 2022を読む (2)

SNSで見つけた、Linux on RISC-Vが現状のRISC-Vを非常に端的に説明していて勉強になると思ったので、読んでみることにした。 以下は読書メモ。といってもほぼ一対一に翻訳してしまっている。

前回の続き。今回は例外処理とOpenSBIとか。

kernel-recipes.org

mobile.twitter.com


RISC-Vの例外処理

  • 例外は同期的に発生する
  • 割り込みは非同期的に発生する
  • <x>cause CSRはどの例外・割り込みが発生したかを記録する
    • m-modeではmcause, s-modeではscause
  • <x>E/IP CSRレジスタの適切なビットが設定される。

Hartとは何か?

  • Hardware Threadを意味する
  • RISC-Vの各コアは命令フェッチユニットにおいて独立である。
  • RISC-Vコアはマルチスレッドにより複数のHartをコア内に持つことができる
  • 各Hartは、Linuxにおいては各プロセッサに相当する
    • RISC-Vラップトップが、2コアでそれぞれ2Hartを持っている場合
    • Linuxからは、4プロセッサとしてみることができる。

RISC-Vの割り込み

  • ローカルのHart毎の割り込み
    • CLINT (Core Local Interruptor)
    • CLIC (Core Local Interrupt Controller)
  • グローバルな割り込み
    • PLIC (Platform Level Interrupt Controller)

Advanced Interrupt Architecture (AIA)

  • AIA SIGメーリングリストにより開発されている。
  • APLIC (Advanced Platform-Level Interrupt Controller)がPLICに置き換えられる
  • IMSIC (Incoming Message-Signaled Interrupt Controller) によるPCIeがサポートされている。
  • AIAはACLINT (Advanced Core Local Interruptor)を含む
    • tech-unixplatformspecメーリングリストによって開発されている
    • CLINTに対する互換性がある。
    • RISC-V SummitのTalkにてJohn Hauserが語っている。

RISC-V Boot Flow

Untitled

Supervisor Binary Interface (SBI)

  • ISAではないRISC-Vの仕様
    • これによりRISC-V命令に修正が入ることはない
  • S-modeとM-modeにおける関数呼び出し規約
    • Linuxのようなスーパーバイザモード(s-mode)上で動作するソフトウェアをRISC-V実装間でポータブルな実装にするために、特定の機能をプラットフォームで抽象化する。
  • UNIX-Class Platform Specificationで議論が行われている。
    • RISC-V Platform Specificationで置き換えが行われる予定。
  • いくつかのオプションとなる拡張が定義される予定
    • Base拡張: マシンモードでの基本的な情報
    • Timer拡張: 次のイベントのためのクロックを用いるプログラム向け
    • IPI拡張: プロセッサ間割り込みを送信するための機能
    • RFENCE拡張: リモートのHartに対するFENCE.I命令の実装

SBIの拡張

  • Hart State Management (HSM)
    • S-modeはHartのstop/start/suspend をリクエストすることができる
  • システムリセット
    • スーパーバイザモードのソフトウェアはシステムレベルのリブートもしくはシャットダウンをリクエストできる。
  • パフォーマンスモニタユニット
    • スーパーバイザモードのがRISC-VのMachineモードに実装されているハードウェアパフォーマンスカウンタを構成することができるインタフェースを持っている。
    • Performance Monitoring in RISC-V using perf

ハイパーバイザー拡張

  • ハイパーバイザースーパーバイザーモード(HS-mode): ホストカーネルが動作する
  • 仮想化スーパーバイザーモード(VS-mode): ゲストカーネルが動作する

Untitled

OpenSBI

  • SBIのオープンソースな実装
    • Core Library
    • Platform Specific Libraries
    • Full refence firmware for some platforms
  • S-modeソフトウェアのためのランタイムサービスを提供
    • SBI拡張により、プラットフォームが使用可能なランタイム拡張を定義する
    • 未実装な命令については、OpenSBIがトラップを行いエミュレートする

OpenSBI汎用プラットフォーム

  • 新しいプラットフォームに対して新しいOpenSBIのコードを追加する必要はない。
    • First-stage Bootloader, U-Boot SPLはOpenSBIのデバイスツリーを通して、プラットフォーム特有の機能を認識する。
  • 異なるプラットフォーム間でOpenSBIバイナリを共通化できる

OpenSBIドメインサポート

  • OpenSBIドメインは、ハードウェアで異なるメモリ空間とHARTを分離するためにシステムレベルでの分割をするための機能
  • Anup Patelにより説明がある。

UEFIサポート

  • UEFIファームウェアオペレーティングシステム委のケル標準インタフェース。ほとんどのx86とArm64プラットフォームで使用されている。
  • U-BootとTianoCore EDK2は両方ともRISC-VにおけるUEFIの実装を持っている。
  • Grub2はRISC-VにおいてUEFIのぺいろーと度して使用できる。
  • RISC-VにおけるUEFIのサポートはLinux 5.10で加えられた。
  • ブート時のHartIDはブート時およびACPIテーブルもしくはDTの機能を読み取る前に識別されている。
  • UEFI以外のシステムでは、HartIDはa0に渡される。しかしUEFIアプリ―ケーションではこれを許さない
  • RISC-V EFIブートプロトコルでは、OSがブート時のHartIDを探すことが許されている。
  • パブリックレビューは終了し、Sunil V LはLinuxカーネルにおけるEFIブートプロトコルのサポートを挿入した。

RISC-Vプラットフォーム仕様

  • 目的は、「既存のソフトウェア」のハードウェアプラットフォームとオペレーティングシステムのインタフェースを統一すること。
  • Platform Horizontal Subcommitteにより議論がなされている。
  • RISC-V Summit 2021にてプラットフォームのトークがある。
  • OS-Aプラットフォーム
    • “A”: アプリケーション向け、LinuxのようなフルOSが動作するプラットフォームをサポートする
    • OS-A共通仕様
    • OS-A組み込みプラットフォーム
    • OS_Aサーバプラットフォーム
  • RVM-CSIプラットフォーム
    • ベアメタルアプリケーションもしくはRTOSが動作するRISC-Vのマイクロコントローラ向け
    • CSIはCommon Software Interfaceのこと; 簡単にポーティングできることを目的とし、バイナリの互換性は要求しない。
  • OS-A共通仕様
    • RVA22U / RVA22S ISAプロファイルを守っている必要がある。
    • デバッグ、タイマ、割り込みコントローラなどの仕様が定義されている
    • UART 8250, UART 16550などのシリアルコンソールが要求されている。
    • SBI拡張などのランタイムサービスが要求されている
    • ソフトウェアコンポーネントは、RISC-V Calling Convention SpecificationおよびRISC-V ELF specificationを守っている必要がある。
  • OS-A組み込み仕様
    • Single Board Computerもしくはモバイルデバイス向け
    • PMUカウンタおよびイベントパフォーマンスモニタ
    • Bootプロセスは、Embedded Base Boot Requirements (EBBR)規格に準拠する必要がある
    • EBBRはUEFIスペックのサブセットであり、U-Bootには実装されている。
    • Device Tree(DT)はハードウェアのコンフィグレーションを認識するために必要である。
    • GPT partitioningは、共有ストレージのために必要である。
  • OS-Aサーバプラットフォーム
    • RHELなどのエンタープライズ向けのLinuxディストリビューションがサーバクラスハードウェアにおいて動作すること
    • システムの周辺機器、PCIe, Watchdog timer, システム日時、時刻などの機能をサポート
    • RAS (Reliability, Availability, Serviceability)が必要となり、ECC RAMなどがサポートされる
    • ACPIによりハードウェアの復帰やコンフィグレーションがサポートされる
    • RISC-V ACPI Platform Requirementsを準拠することが必要である。
  • RISC-V ACPI Platform仕様
    • RISC-Vサーバプラットフォーム向けに十分なACPIテーブルを定義している
    • RISC-V向けに新しいテーブルが必要になる
      • RISC-V Hart Capabilities Table (RHCT)
      • RISC-V Timer Description Table (RTDT)
    • より詳細については、 ‘ACPI for RISC-V: Enabling Server Class Platforms’を参照のこと
      • Sunil V LがRISC-Vサミットにて講演している。

Linux on RISC-V 2022を読む (1)

SNSで見つけた、Linux on RISC-Vが現状のRISC-Vを非常に端的に説明していて勉強になると思ったので、読んでみることにした。 以下は読書メモ。といってもほぼ一対一に翻訳してしまっている。

連続で投稿する。何回かに分けて読んでいこうと思う。

kernel-recipes.org

mobile.twitter.com


RISC-V: フリーでオープンなISA

  • カリフォルニア大学バークレイ校の新しいコンピュータアーキテクチャ研究グループで開発された命令セットアーキテクチャ
  • Vはローマ数字の5の意味であり、UCバークレイから開発された5番目のRISCである、という意味。
  • フリーでオープンというのは、仕様書がオープンソースライセンスで配布されているということを意味する: Creative Commons Attribution 4.0 International

RISC-Vはこれまでと何が違うのか

  • シンプルで白紙のデザイン
    • マイクロアーキテクチャのスタイルに関する依存性を除去する(インオーダ、アウトオブオーダなど)
  • モジュラーデザイン
    • マイクロコントローラからスーパーコンピュータまでに適用できる。
  • 安定したベースライン
    • ベースとなる整数ISAと標準拡張は完全に決定された。
    • オプションとなる拡張については、最新ではない。

RISC-Vベース整数ISA

  • RV32I: 32ビット
    • 50命令以下で実現可能!
  • RV64I: 64ビット
    • Linuxにおいて、もっとも重要
  • RV128: 128ビット

RISC-Vベース整数レジスタ

RISC-V ABI

  • x1からx31はプロセッサにとって、同様に扱われる。
  • RISC-V psABIによると、これらのレジスタの機能が定義されている。
    • s0からs11までを関数コール内で予約して使用している。
    • a0からa7までの引数レジスタ、テンポラリレジスタであるt0からt6は異なる。

RISC-V標準拡張

  • M: 整数乗算・除算
  • A: アトミックメモリアクセス
  • F, D, Q: 浮動所数点、単精度、倍精度、4倍精度
  • G: 「標準仕様」、IMAFDと同一
  • C: メモリとキャッシュを節約するための圧縮命令
  • 多くのLinuxディストリビューションはRV64GCをターゲットとしている。

2021年に標準化された使用

  • 新たに15個の命令仕様により、40以上の拡張が定義された
  • ベクトル
  • ハイパーバイザー
  • スカラ暗号化
  • ビット操作

RISC-Vのプロファイル

  • RISC-Vは高いモジュラリティと拡張性のあるアーキテクチャである
    • プロセッサのデザインによって、適切な命令仕様を柔軟にピックアップできるようになっているが、それに応じて多くの命令仕様の組み合わせが生じてしまう。
  • RISC-Vのプロファイルは多くのユースケースにおいて代表的な最小限のISAを定義している。
    • RVM: ベアメタルコードもしくはRTOSが動作することを目的としたもの
    • RVA: Linuxなどのオペレーティングシステムが動作することを目的としたアプリケーションプロセッサ向けの仕様
  • RISC-V Summit TalkにてGreg Favorが説明を行っている。

RISC-Vについてより知りたい方には

  • RISC-V Readerを読んでRISC-Vについて知ろう。

RISC-Vについてより深く知りたい方には

  • Computer Organization and Design, RISC-V Edition

産業界におけるRISC-V

  • RISC-V Internationalが仕様自体を制御している。
    • 70か国以上から非営利団体や大学含む2,700を超えるメンバが参入している。
    • 非営利団体や個人は無料で加入できる
    • RISC-V InternationalがYoutubeチャネルを公開しており多くの発表が聞ける
  • 数百万以上のRISC-Vコアが企業により出荷されている

RISC-Vと産業界

  • ISAのライセンス料とロイヤリティが必要ない
    • リーガルコストと複雑なライセンス同意による遅延を防ぐ
  • マイクロアーキテクチャの実装が自由
    • オープンISAというのは、すべての人がアーキテクチャライセンスを持っているということ。
  • 既存のオープンソース実装を向上させる自由

RISC-Vはオープンソースプロセッサなのか?

RISC-Vのオープンソースコア

  • アカデミア
    • Rocket / BOOM / PULP
  • 産業界
    • SweRV / Core-V / OpenTitan
  • FPGAソフトコア
    • PicRV32, RVfpga, SERV, VexRiscV
  • FOSSI Fondation
    • EI Correo Libre : 月間のニュースレターにて、最新のオープンソースコアについてレポート
  • オープンソースSoCをオープンソースシリコンツールチェインにて実装

RISC-Vソフトウェアエコシステム

RISC-V特権アーキテクチャ

制御と状態レジスタ (CSR)

  • CSRは読み書きのために専用の命令を持っている。
  • CSRはそれぞれのモード(m-mode, s-mode)で専用のレジスタを持っている。
  • マシン状態 (mstatus) は重要なCSRである。

RISC-V仮想メモリ

  • satp(Supervisor Address Translation and Protection)CSRによってスーパーバイザモードのアドレス変換が制御されている。
  • Sv32: 3レベルのページテーブル
  • Sv39: 3レベルのページテーブル
  • Sv48: 4レベルのページテーブル
  • Sv57: 5レベルのページテーブル

M1 macOSでLLVMをビルドする際に必要なCMakeのオプションまとめ

M1 macOS上でLLVMをビルドして、C言語プログラム注で#include <stdio.h>を使用しようとするとエラーになったりするのだが、これを回避する方法を色々と探していた。

stackoverflow.com

結論から言うと以下のコマンドでビルドできる。

cmake -G Ninja \
  -DCMAKE_OSX_ARCHITECTURES='arm64' \
  -DDEFAULT_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/ \
  -DCMAKE_BUILD_TYPE="Debug" \
  -DLLVM_TARGETS_TO_BUILD="X86;RISCV;AArch64" \
  -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi" 
  ../llvm

肝となるのは、-DDEFAULT_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/macOSSDKの場所を指定すること。 これでmacOSでのLLVMデバッグビルド環境がだいぶ進んだ。

  • test.c
#include <stdio.h>

int main ()
{
  int total = 0;
  for (int i = 1; i <= 10; i++) {
    total += i;
  }

  printf ("Total = %d\n", total);
}
build/bin/clang x86_test.c
./a.out
Total = 55

clangでRISC-V Vector ExtensionのAuto Vectorizationを試す

Ubuntu 22.04 LTS上でインストールできるclang14を試す。

void vector_test (const long long *a, const long long *b, long long *c)
{
  for (int i = 0; i < 256; i++) {
    c[i] = a[i] + b[i];
  }

  return;
}
clang-14 -c vector_test.c -menable-experimental-extensions -march=rv64gcv -target riscv64 -O3 -mllvm --riscv-v-vector-bits-min=256
riscv64-unknown-elf-objdump -d vector_test.o
  4e:   00e507b3                add     a5,a0,a4
  52:   c5827057                vsetivli        zero,4,e64,m1,ta,mu
  56:   0207f407                vle64.v v8,(a5)
  5a:   02078793                addi    a5,a5,32
  5e:   0207f487                vle64.v v9,(a5)
  62:   00e587b3                add     a5,a1,a4
  66:   0207f507                vle64.v v10,(a5)
  6a:   02078793                addi    a5,a5,32
  6e:   0207f587                vle64.v v11,(a5)
  72:   02a40457                vadd.vv v8,v10,v8
  76:   02b484d7                vadd.vv v9,v11,v9
  7a:   00e607b3                add     a5,a2,a4
  7e:   0207f427                vse64.v v8,(a5)
  82:   02078793                addi    a5,a5,32
  86:   04070713                addi    a4,a4,64
  8a:   0207f4a7                vse64.v v9,(a5)
  8e:   fc5710e3                bne     a4,t0,4e <vector_test+0x4e>
  92:   8082                    ret

IBM POWER7の論文を読む (4. 命令フェッチ)

マイクロアーキテクチャに関する論文を読んでいる。今回はIBM POWER7に関する論文。

ieeexplore.ieee.org

戻って命令フェッチを見ていく。


命令フェッチ

  • 命令キャッシュ : 32KB、4ウェイセットアソシアティブ
  • 16ウェイバンク設計
  • IEADIRを使用して、この中から4ウェイを選択する。
  • IEADIR : 命令有効アドレスディレクト
    • ウェイ選択の高速予測を行う。
      • 64エントリ
      • 命令アドレスのEA → RA変換 (IERAT)
      • 最初の32エントリでスレッド0/2をサポート
      • 以降の32エントリでスレッド1/3をサポート
    • フル命令キャッシュディレクトリ : IDIR
  • IFU : L2ユニファイドキャッシュからL1Iキャッシュに命令をフェッチする。
    • 命令フェッチリクエストから、32バイトの4セクタのデータが返ってくる。
    • デマンドフェッチ
    • 命令プリフェッチ
      • デマンドフェッチ要求に対して、2つのシーケンシャルキャッシュラインに対して、最大2つの追加L2プリフェッチを開始する。
    • これらのフェッチは、4つのスレッドに対してそれぞれ独立に実行される。
  • 命令がフェッチされると、L1Iキャッシュに命令が書き込まれる前に、プリデコードとパリティを作成する。

    • 2サイクル消費する。
    • 分岐命令のスキャン、グループ形成の支援
    • 例外ケースの表示に使用される。
    • 最終的にIキャッシュに書き込まれるのは3サイクル後
    • その間に、IFUはキャッシュを迂回して命令バッファ(IBUF)と分岐スキャンロジックに命令を分配する。
  • IFAR : 命令フェッチアドレスレジスタ

    • 各スレッドのプログラムカウンタアドレスを追跡している。

IBM POWER7の論文を読む (3. LSUの概要2)

マイクロアーキテクチャに関する論文を読んでいる。今回はIBM POWER7に関する論文。

ieeexplore.ieee.org

LSUの続き。


アドレス変換

  • EA (Effective Address) : 有効アドレス。64-bit
  • RA (Real Address) : 実アドレス : 46-bit
  • 第1レベル変換
    • EAからRAへ変換する。
    • D-ERATキャッシュ : 64エントリx2
    • IERATキャッシュ : 64エントリ
  • ERATにキャッシュミスが発生した場合、第2レベルの変換が呼び出され、変換が生成される。
    • SLBキャッシュ : 32エントリ
    • TLB : 512エントリ

L1Dキャッシュの構成

  • L1Dキャッシュの構成 32KB 8ウェイ セットアソシアティブ バンク型
    • キャッシュラインサイズ : 128バイト (1024-bit)
      • 32バイトの4セクタ
      • L2キャッシュからの32バイトサイズの専用リロードインタフェースが入っている。
      • 1クロック毎に32バイトのデータを供給可能
    • 2リードポート (ロード命令用)
    • 1ライトポート (ストア命令用 / キャッシュラインのリロード用)
    • 書き込みは読み込みよりも遊園度が高い
    • データバイト毎に編成された4つの物理マクロから構成されている
      • EAビットを基準に16個のバンクに分割されている。
      • 合計64バンク
      • 書き込みと同じバンクに読み込まない限り、同じサイクルで1回の書き込みと2回の読み出しが可能
    • ライトスルー設計
      • 書き込みはすべてL2キャッシュに送られる。L1Dキャッシュの掃き出しは必要ない
    • L1DキャッシュはEAビットでインデックスされる
    • バイナリツリーのLRU置き換えポリシで置き換えられる
    • 1セットあたり4kBととなる。
  • ロード命令の実行
    • 生成されたEA (52:56)がSet Predict Arrayのインデックスとして使用される
    • EA (33:51)はハッシュ化され、8つのエントリの集合の内容と比較される。
    • ハッシュの一致を確認した後、L1Dキャッシュから実アドレスを取得して、比較を行って始めてキャッシュヒットが確定する。

ロードミスハンドリング

  • L1Dキャッシュミスが発生したロード命令は、L2キャッシュへのキャッシュライン再ロード要求を行う。
  • この再発行キューのエントリを開放する
  • L1Dキャッシュへのキャッシュラインのロードを追跡するために、LMQにエントリが作成させる。
  • L2キャッシュからリロードデータが戻ってくると、LSUパイプライン上でより高い優先度で再実行される。
  • LMQは、最大2つのロード命令を与えられたLMQエントリとキャッシュラインの再ロード要求に関連できるロードマージをサポートしている。

IBM POWER7の論文を読む (2. LSUの概要)

マイクロアーキテクチャに関する論文を読んでいる。今回はIBM POWER7に関する論文。

ieeexplore.ieee.org

先に興味のあるデータアクセス用のLSUについて読んでいく。


データフェッチユニット

  • LSUはLS0とLS1の対称な実行パイプラインを持っている。1サイクルでロード・ストア動作を実行することが可能。
  • 図6は、LSUパイプラインのマイクロアーキテクチャを示している。
    • LS AGEN
    • Execute
    • SRQ (Store Request Queue)
    • SDQ (Store Data Queue)
    • LRQ (Load Request QUeue)
    • LMQ (Load Miss Queue)
    • D-ERAT
    • ERATミスキュー
    • SLB (Segment Lookaside Buffer)
    • TLB / MMU
    • L1Dキャッシュアレイ
    • データディレクトリ(DDIR)
    • Data Prefetch Request Queue (PRQ)
図は本論文より引用

LS実行

  • STモードとSMT2モードでは、LS命令はどちらのパイプラインでも実行できる。
    • SMT4モードでは、スレッド0/1の命令はパイプライン0で実行され、スレッド2/3の命令はパイプライン1で実行される。
  • LSUへの命令は順番に発行され、古い命令から優先的に発行される。
  • ストア命令は2回発行される。
    • AGENはLSUに発行される
    • データステアリング操作はFXUおよびVSUに発行される
  • LSUの入出力のデータフローバスの構成
    • L2キャッシュからのリロードデータ(32バイト)
    • L2キャッシュへのストアデータ(16バイト)
    • VSUへの実行パイプライン毎の全体で16バイトのロードデータ
    • VSUから16バイトのストアデータ
    • FXUからの実行パイプライン毎の8バイトストアデータ
  • L1 DCacheサイズは32KBである。
    • データキャッシュアクセスによるロードユースは2サイクル。

LSの順序付け

  • LSUはプログラムの順序の効果を保証する必要があるため、SRQとLRQという2つのメインキューを搭載している。
  • SRQ : 32エントリのCAM (Content Addressable Memory)である。
    • 各スレッドは64エントリの仮想エントリを持っている。
    • SRQエントリは発行時に割り当てられる。
    • SRQエントリには、16バイトの対応するSDQエントリが存在している。
    • ストア命令用の最大16バイトのデータをL2キャッシュに払い出すことができる。
      • ヒットした場合にはL1Dキャッシュにも書き込まれる。つまりライトスルーモード。
    • ストアフォワーディングをサポートしている。
      • SRQエントリからのデータは、ロード命令に対してフォワードされる。
  • LRQ : 32エントリのCAM (Content Addressable Memory)である。
    • 各スレッドは64エントリの仮想エントリを持っている。
    • LRQは順不同のロードを追跡し、ハザードを監視する。
      • 若いロード命令が同じアドレスへの古いロード命令やストア命令の前に実行された場合。
      • LRQは若いロード命令とそれに続くすべての命令をフラッシュすることができる。