Rocket-ChipのTLBは、TLBミスが発生すると外部のPTWにアクセスして当該メモリ領域の属性を取得する。
その実装を探していたのだが、Chiselで書いてあって非常に分かりにくい。PTWの実装のうち、おそらくこの辺がPMAのテーブルを作っているものと思われる。
sims/verilator/generated-src/chipyard.TestHarness.RocketConfig/chipyard.TestHarness.RocketConfig.top.v
module PTW(
input clock,
input reset,
output io_requestor_0_req_ready,
wire [16:0] s2_entry_vec_0_tag = uncorrected[42:26];
wire s2_hit_vec_0 = s2_valid_vec & r_tag == s2_entry_vec_0_tag;
wire s2_hit = s2_valid & s2_hit_vec_0;
wire [65:0] _pmaPgLevelHomogeneous_T_6 = pte_addr ^ 66'hc000000;
wire [66:0] _pmaPgLevelHomogeneous_T_7 = {1'b0,$signed(_pmaPgLevelHomogeneous_T_6)};
wire [66:0] _pmaPgLevelHomogeneous_T_9 = $signed(_pmaPgLevelHomogeneous_T_7) & -67'sh4000000;
wire _pmaPgLevelHomogeneous_T_10 = $signed(_pmaPgLevelHomogeneous_T_9) == 67'sh0;
wire [65:0] _pmaPgLevelHomogeneous_T_11 = pte_addr ^ 66'h80000000;
wire [66:0] _pmaPgLevelHomogeneous_T_12 = {1'b0,$signed(_pmaPgLevelHomogeneous_T_11)};
wire [66:0] _pmaPgLevelHomogeneous_T_14 = $signed(_pmaPgLevelHomogeneous_T_12) & -67'sh10000000;
wire _pmaPgLevelHomogeneous_T_15 = $signed(_pmaPgLevelHomogeneous_T_14) == 67'sh0;
wire pmaPgLevelHomogeneous_1 = _pmaPgLevelHomogeneous_T_10 | _pmaPgLevelHomogeneous_T_15;
wire [66:0] _pmaPgLevelHomogeneous_T_20 = {1'b0,$signed(pte_addr)};
wire [66:0] _pmaPgLevelHomogeneous_T_38 = $signed(_pmaPgLevelHomogeneous_T_20) & -67'sh5000;
この辺の実装についてはChisel側を眺めてみると、edge.manager
などが出てくるのでおそらくDiplomacyで接続された各デバイスからメモリアクセスの属性の情報を取得して、テーブルに纏めているものと思われる。
rocket-chip/src/main/scala/rocket/PTW.scala
val pageGranularityPMPs = pmpGranularity >= (1 << pgIdxBits)
val pmaPgLevelHomogeneous = (0 until pgLevels) map { i =>
val pgSize = BigInt(1) << (pgIdxBits + ((pgLevels - 1 - i) * pgLevelBits))
if (pageGranularityPMPs && i == pgLevels - 1) {
require(TLBPageLookup.homogeneous(edge.manager.managers, pgSize), s"All memory regions must be $pgSize-byte aligned")
true.B
} else {
TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), pgSize)(pte_addr).homogeneous
}
}
val pmaHomogeneous = pmaPgLevelHomogeneous(count)
val pmpHomogeneous = new PMPHomogeneityChecker(io.dpath.pmp).apply(pte_addr >> pgIdxBits << pgIdxBits, count)
val homogeneous = pmaHomogeneous && pmpHomogeneous