FPGA開発日記

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

RISC-V Advanced Platform Interrupt Controller (APLIC) の概観

RISC-VのAdvanced Platform Interrupt Controller (APLIC) について勉強してみようと思う。

まずは以下のブログを読んで概観を掴もう。

blog.stephenmarz.com

APLICの概観

APLICはSiFiveのPLICを発展させたもので、PLICとの違いはメッセージによる割り込みの送信をサポートしていることである。 PLICの目的はハードウェア割り込み信号の集約と優先順位付け、そして割り込み通知信号の送信だった。 割り込み送信先はHARTで、HARTはClaimレジスタと呼ばれるPLICレジスタを読むことによって何が通知されたかを判断することができる。

APLICは、Incoming MSI Controller(IMSIC)と組み合わせることによって、APLICは他のハードウェアデバイスと同じようにメッセージを送信する能力を持つ。

APLICのメモリマップ

注意しなければならないのは、APLICとPLICの間に互換性はないということである。

struct Aplic {
    pub domaincfg: u32,           // Domain CSR that controls how this APLIC functions
    pub sourcecfg: [u32; 1023],   // Source configuration for 1023 interrupts
    _reserved1: [u8; 0xBC0],

    pub mmsiaddrcfg: u32,         // Machine-level MSI address (for APLIC to write MSIs)
    pub mmsiaddrcfgh: u32,
    pub smsiaddrcfg: u32,         // Supervisor-level MSI address
    pub smsiaddrcfgh: u32,
    _reserved2: [u8; 0x30],

    pub setip: [u32; 32],         // Bitset to set pending interrupts (32 IRQS per element)
    _reserved3: [u8; 92],

    pub setipnum: u32,            // Sets a pending interrupt by number
    _reserved4: [u8; 0x20],

    pub clrip: [u32; 32],         // Bitset to clear pending interrupts (opposite of setip)
    _reserved5: [u8; 92],

    pub clripnum: u32,            // Clears a pending interrupt by number
    _reserved6: [u8; 32],

    pub setie: [u32; 32],         // Bitset to enable interrupts
    _reserved7: [u8; 92],

    pub setienum: u32,            // Enable an interrupt by number
    _reserved8: [u8; 32],

    pub clrie: [u32; 32],         // Bitset to disable interrupts (opposite of setie)
    _reserved9: [u8; 92],

    pub clrienum: u32,            // Disable an interrupt by number
    _reserved10: [u8; 32],

    pub setipnum_le: u32,         // Set an interrupt pending by number always little end first
    pub setipnum_be: u32,         // Set an interrupt pending by number always big end first
    _reserved11: [u8; 4088],

    pub genmsi: u32,              // Used to generate MSIs
    pub target: [u32; 1023],      // Target control per interrupt
}

ドメイン構成レジスタ(domaincfg)

  • 割り込み許可ビット(Interrupt Enable: IE)は、APLICが割り込みを送信できるようにする(1 = 有効、0 = 無効)

    • これは割り込みが必ず通知されることを意味するのではなく、pendingビットをトリガすることによってAPLICが割り込みを送信できることを意味するだけである。
  • 配信モードビット(delivery mode): APLICは旧PLICのように通常の割り込みを送信するか、割り込みをメッセージ(MSI)として送信するかを設定する。

    • DM ビットが 0 に設定されると、古い APLIC のように direct 割り込みを送信する
    • DMビットが1に設定されると、代わりにMSIを送信する。
  • ビッグエンディアンビット(Big Endian)により、APLICはビッグエンディアン(BE=1)またはリトルエンディアン(BE=0)でメッセージを書き込むことができる。

    • BE ビットはマルチバイト・ドメイン・コンフィギュレーション・レジスタの順序にも影響する。

最上位バイトは、バイト順マークのような役割を果たすために、意図的に0x80に設定されている。

ソース設定レジスタ(sourcecfg)

すべての割り込みに対して 1 つの sourcecfg レジスタが定義されている。

  • delegateビット(ビット10)は、与えられた割り込みが委譲されているかどうかを判断するために読むことができます。 このビットは読み書き可能である。 このフィールドに1を書き込むと、子ドメインに委譲される。 特定のソースに子ドメインがない場合、このビットは常に0を読み取る。
  • ソース・モードビット(ビット2:0) は、委譲されていない割り込みについて、割り込みがどのようにトリガされるかを制御します。
  • 割り込みが委譲されている(D=1)場合、ビット9:0はそれが委譲された子のインデックスを記述します。
  • 割り込みが委譲されていない場合(D=0)、各割り込みソースは、以下のいずれかによって「保留中」割り込みをトリガするように構成することができます。