自作ISSのテストパタンが通らなくなってきた!
特に仮想メモリを使っているパタンが通らなくなった。大昔に自作ISSに仮想アドレスから物理アドレスの変換を実装していたのだが、どうやら仕様がv.1.9.1で変わっているらしい。 もう一度チェックしてみよう。
ちなみに、前回の解説はこちら。
ここから、いろんな仕様が変更されている。
sptbr(Supervisor Page-Table Base Register)の仕様について
v1.9.1には、sptbrの仕様変更が行われている。これまでは上位ビットにアドレス変換のベースアドレスが格納されていたが、sptbrのベースアドレスは下位(PPN)に移動されている。
Sv32の仕様ならば、PAGESIZE=2^12
を乗算してベースアドレスとしている。
ページテーブルエントリの仕様について
ページテーブルの変換では、メモリ上(あるいはTLB)上に存在するアドレス情報を探索していくが、ページテーブルのエントリの仕様も変更されている。
属性ビットがv.1.9.1では増強されている。
- V=Valid Bit. ページテーブルエントリが有効であることを示す。
- R=Read Bit. ページが読み込み可能であることを示す。
- W=Write Bit. ページが書き込み可能であることを示す。
- X=Executable Bit. ページがフェッチ可能であることを示す。 ちなみに、RWXがどれも1がセットされていない場合は、次のページテーブルへのポインタページとなっている。
- U=UserMode Bit. ユーザモードのソフトウェアはU=1のページテーブルでないとアクセスできない。
- G=Global Mapping Bit. グローバルマッピング。すべてのアドレス空間に存在していることを示す。
- A=Access Bit. アクセス済みビット
- D=Dirty Bit. 書き込み済みビット
アドレス変換処理の仕様変更について
v.1.7の場合
- i=LEVELS-1 (LEVEL=2)からスタートする。つまり、上位の変換ブロックから変換を始める。
- va.vpn[i]×PTSIZE(=4)+sptbr のアドレスを計算し(これが変換テーブルのアドレスとなる。つまり、va.vpn[i]をインデックスとして変換テーブルを参照している)、ページテーブルエントリ(=pte)を参照する。
- pte.Vビットを確認し、0であれば無効テーブルエントリなのでアドレスエラーを出力する。
- pte.type が2以上であれば、テーブルの参照の終端まで行ったことになるので、ステップ5に進む。ここでpte.typeの意味は以下のように定義されているようだ (Privileged Reference Manual参照)。
つまり、Type=0 or 1であれば次のテーブルへの参照となるが、それ以外は最終的なページテーブルとなる。 ここでテーブルのアクセスエラーを確認する。 Type=0,1のときは次のアドレスを計算する。a=pte.ppn×PAGESIZEとし(つまりベースアドレスを更新する)、再度ステップ2に進む。また、i<0となるとこれもテーブル不良のためアドレスエラーとなる。
ステップ5まで来たということは、i>=0の間にページテーブルの終端に到達したことを意味する。ここでpte.typeのアクセス権限を確認し、アクセス権限が足りなければエラーとなる。 そうでなければ、以下の方針でアドレス変換を実行する。
オフセットはそのまま利用する。 pa.pgoff = va.pgoff
- i>0(=つまり、インデックスの参照を0まで使い切らない)場合はi-1から0まで(つまり到達しなかったレベル)は、仮想アドレスをそのまま物理アドレスとして利用する。 pa.ppn[i-1:0]=va.vpn[i-1:0]。
- それ以外のインデックスはページテーブルを参照して変換する。pa.ppn[LEVELS-1:i] = pte.ppn[LEVELS-1:i]
v.1.9.1の場合
- i=LEVELS-1 (LEVEL=2)からスタートする。つまり、上位の変換ブロックから変換を始める。
- va.vpn[i]×PTSIZE(=4)+sptbr.PPN×PAGESIZE(=212) のアドレスを計算し(これが変換テーブルのアドレスとなる。つまり、va.vpn[i]をインデックスとして変換テーブルを参照している)、ページテーブルエントリ(=pte)を参照する。
- pte.Vビット、pte.Rビット、pte.Wビットを確認し、pte.V=0、もしくはpte.R=0&pte.W=1であれば無効テーブルエントリなのでアドレスエラーを出力する。
pte.R=1, pte.X=1であれば、テーブルの参照の終端まで行ったことになるので、ステップ5に進む。そうでなければ、a=pte.ppn×PAGESIZEとして2.に戻る。
ステップ5まで来たということは、i>=0の間にページテーブルの終端に到達したことを意味する。以下の方針でアドレス変換を実行する。
オフセットはそのまま利用する。 pa.pgoff = va.pgoff
- i>0(=つまり、インデックスの参照を0まで使い切らない)場合はi-1から0まで(つまり到達しなかったレベル)は、仮想アドレスをそのまま物理アドレスとして利用する。 pa.ppn[i-1:0]=va.vpn[i-1:0]。
- それ以外のインデックスはページテーブルを参照して変換する。pa.ppn[LEVELS-1:i] = pte.ppn[LEVELS-1:i]