TOPPERS Confidential TOPPERSプロジェクト 設計メモ ARMのVMSAに関するメモ 作成者: 高田広章(名古屋大学) 最終更新: 2015年8月6日 ○メモの位置づけ このメモは,ARMのVMSA(Virtual Memory System Architecture)に関して, TOPPERSカーネルをポーティングするにあたって必要となる事項をまとめたもの である. ARMのVMSAは,ARMv5以前とARMv6以降ではかなり違っている.また,ARMv7では, セキュリティ拡張,ラージ物理アドレス拡張(LPAS; Large Physical Address Extension),仮想化拡張などが追加されている. このメモでは,ARMv5以前とARMv6以降の両方について扱うが,ARMv7における拡 張については,TOPPERSカーネルでは直接サポートしないため,扱わないことと する(現時点では,ARMv6を中心に記述してある). ○目次 ・参考文献 ○参考文献 [1] ARM Architecture Reference Manual, 2005 DDI 01001.pdf ※ ARMv6以前の定義 [2] ARM Architecture Reference Manual - ARMv7-A and ARv7-R edition, 2014 DDI0406C_C_arm_architecture_reference_manual.pdf ※ ARMv7の定義,ARMv6以前との差分についても記載あり ○ARMのVMSAの概要 ●主な特徴 ・2レベルのテーブルを用いたハードウェアによるアドレス変換 ・マッピングサイズ:4KB,16KB,1MB,16MB ・セクション(1MB,16MB)単位でのアクセス許可指定が可能 ・ラージページ(64KB)とスモールページ(4KB)単位でのアクセス許可指定 ・エントリに8ビットのASID(アドレス空間識別子)を付与可能(ARMv6以降) ・エントリをグローバルに設定可能(ARMv6以降) ・16個のドメイン ●セクションとページ スーパーセクション:16MB単位(ARMv6以降,ARMv5ではオプション) セクション:1MB単位 ラージページ:64KB単位 スモールページ:4KB単位 タイニーページ:1KB単位(ARMv6ではサポートされない) ●ARMv5からARMb6への拡張点 ARMv6のMMUは,ARMv5に対して様々な拡張がされている.ARMv6の(新しい)ア ドレス変換機構は,過去のものと互換性がないため,過去と互換のアドレス変 換機構もサポートしている.ARMv6での主な拡張点は次の通り. ・メモリ領域のタイプを拡張(メモリモデルの指定など). ・プロセス(ASID)毎のページとグローバルページをサポート. ・アクセス許可を拡張.実行禁止領域を指定可能. ・複数のプロセッサで共有するメモリ領域を指定可能. ・変換テーブルベースレジスタ(TTBR)が2つある. ・ファインページテーブルとタイニーページ(1KB)を廃止. プロセス(ASID)毎のページとグローバルページは,TLBのフラッシュを不必要 にし,TLBミスが減るため,ARMv6では新しいアドレス変換機構を使用すべきで ある. 参考:ARM11 MPCoreのVMSAの特徴 ・ラウンドロビンリプレースメント ・64エントリの統合TLBと8エントリのロックダウンTLB ・マイクロTLBとマクロTLBの2階層のTLB(実装の問題) ●ドメイン ドメインは,メモリ領域の集合である.すべてのメモリ領域は,いずれかのド メインに属する.ドメインの最大数は16個である. ドメインアクセス制御レジスタ(DACR; Domain Access Control Register)に より,各ドメインに対して次のいずれかのアクセス許可を設定できる. ・アクセスできない ・TLBエントリのアクセス許可に従う(client) ・TLBエントリのアクセス許可にかかわらず必ずアクセスできる(manager) メモリ領域がどのドメインに属するかは,第1レベルディスクリプタ中で指定さ れる.そのため,異なるドメインに属するように設定できるのは,1MB単位とい うことになる. スーパーセクション(16MB単位のメモリ領域)は,必ずドメイン0に属する. ●ページテーブルのマッピング制限 仮想インデックス物理タグ(VIPT)キャッシュにおけるエイリアスの処理を容 易にするための制限として,以下を設ける(命令キャッシュでは無害). ・複数の論理アドレスが同じ物理アドレスにマッピングされる場合に,論理ア ドレスのビット[13:12]と,マッピングされる物理アドレスのビット[13:12]を 必ず一致させること. ・または,すべてのマッピングが4KB単位の場合には,同じ物理アドレスにマッ ピングされる論理アドレスのビット[13:12]がすべて同じであること. MPCoreでは,物理インデックス物理タグ(PIPT)キャッシュを用いているため, この制限は適用されない.PIPTキャッシュで高速アクセスを実現するために, 超高速・小容量のマイクロTLBを備えている. → HRP3カーネルでは,論理アドレスと物理アドレスを一致させているため,上 の制限が常に満たされる. ○アドレス変換機構 ●ARMv6の新しいアドレス変換機構 ここでは,(過去と互換のアドレス変換機構ではなく)ARMv6の(新しい)アド レス変換機構について説明する.CP15制御レジスタc1のXPビット(ビット23) で,サブページAPビットをディスエーブルすることで,ARMv6の(新しい)アド レス変換機構が使われる. 論理アドレスから物理アドレスへの変換は,2レベルの変換テーブルによって行 われる.1段目の変換テーブルを第1レベルテーブル,2段目の変換テーブルを第 2レベルテーブルと呼ぶ. *変換テーブルベースレジスタ 第1レベルテーブルは,変換テーブルベースレジスタ(TTBR)によって指定され る.ARMv6には,2つの変換テーブルベースレジスタ(TTBR0とTTBR1)があり, 論理アドレスの上位ビットによって使い分けることができる.具体的には,論 理アドレスの上位Nビットがすべて0の場合にTTBR0が使われ,そうでない時に TTBR1が使われる.Nは,変換テーブルベース制御レジスタ(TTBCR)で設定する. Nに0を設定すると,常にTTBR0が使われる. TTBRには,第1レベルテーブルのアドレスに加えて,キャッシュ可能/不可能を 制御するビットがある(詳細省略). → TTBR1をカーネル,TTBR0をユーザプロセスに使うことを想定した機構である が,HRP3ではアドレス変換を行わないため,TTBR1をうまく活用できない.常に TTBR0を使う設定で用いることにする. *第1レベルディスクリプタ 論理アドレスのビット[31:20](上位12ビット)をインデックスとして,第1レ ベルテーブルを検索し,第1レベルディスクリプタを取り出す.そのため,第1 レベルディスクリプタは,1MBのメモリ領域に対応する. 第1レベルディスクリプタには,次の種類がある. フォルト ・下位2ビットが00または11 ・変換フォルトを引き起こす ※サブページを使う時(ARMv5互換モード)は,下位2ビットが11は予約 コアースページテーブル ・下位2ビットが01 ・第2レベルテーブル(コアースページテーブル)を指す ビット31〜10(22ビット):第2レベルテーブルのアドレス ビット9:実装定義,MPCoreではPビット(ECCが有効であることを示す) ビット8〜5:属するドメイン ビット4〜2:0に設定(未使用) ビット1〜0:01に設定(コアースページテーブルを示す) セクション ・下位2ビットが10で,ビット18が0 ・セクション(1MB単位のメモリ領域)を示す ビット31〜20(12ビット):セクションのアドレス ビット19:0に設定(未使用) ビット18:0に設定(セクションを示す) ビット17:nGビット(グローバルでない) ビット16:Sビット(プロセッサ間で共有) ビット15:APXビット ビット14〜12:TEXビット ビット11〜10:APビット ビット9:実装定義,MPCoreではPビット(ECCが有効であることを示す) ビット8〜5:属するドメイン ビット4:XNビット(実行禁止) ビット3:Cビット ビット2:Bビット ビット1〜0:10に設定(セクション/スーパーセクションを示す) スーパーセクション ・下位2ビットが10で,ビット18が1 ・セクション(16MB単位のメモリ領域)を示す ビット31〜24(8ビット):セクションのアドレス ビット23〜19:0に設定(未使用) ビット18:1に設定(スーパーセクションを示す) 以降,セクションと同じ(nG,S,APX,TEX,AP,P,XN,C,B) ただし,ドメインは無視される(必ずドメイン0) ・第1レベルテーブルには,同じディスクリプタを16回繰り返して入れておく *第2レベルディスクリプタ 第1レベルディスクリプタが,コアースページテーブルを指す場合には,論理ア ドレスのビット[19:12](中央の8ビット)をインデックスとしてそのテーブル を検索し,第2レベルディスクリプタを取り出す.そのため,第2レベルディス クリプタは,4KBのメモリ領域に対応する. 第2レベルディスクリプタには,次の種類がある. フォルト ・下位2ビットが00 ・メモリアクセスフォルトを引き起こす スモールページ ・下位2ビットが10または11 ・スモールページ(4KB単位のメモリ領域)を示す ビット31〜12(20ビット):ページのアドレス ビット11:nGビット(グローバルでない) ビット10:Sビット(プロセッサ間で共有) ビット9:APXビット ビット8〜6:TEXビット ビット5〜4:APビット ビット3:Cビット ビット2:Bビット ビット1:1に設定(スモールページを示す) ビット0:XNビット(実行禁止) ※ セクションと比べると,ドメインとPビットがない. ラージページ ・下位2ビットが01 ・ラージページ(64KB単位のメモリ領域)を示す ビット31〜16(16ビット):ページのアドレス ビット15:XNビット(実行禁止) ビット14〜12:TEXビット ビット11:nGビット(グローバルでない) ビット10:Sビット(プロセッサ間で共有) ビット9:APXビット ビット8〜6:0に設定(未使用) ビット5〜4:APビット ビット3:Cビット ビット2:Bビット ビット1〜0:01に設定(ラージページを示す) ・第2レベルテーブルには,同じディスクリプタを16回繰り返して入れておく ●アクセス許可と属性 アクセス許可(詳しくは下記) APXビット(1ビット)書込みアクセス禁止の場合に1 APビット(2ビット) ユーザアクセスを制御 キャッシュとメモリモデル TEXビット(3ビット)タイプ拡張フィールド Cビット(1ビット) (元々は)キャッシュ可能 Bビット(1ビット) (元々は)バッファ可能 その他 nGビット(1ビット) グローバルなメモリ領域でない場合に1 Sビット(1ビット) プロセッサ間で共有するメモリ領域の場合に1 XNビット(1ビット) 実行不可のメモリ領域の場合に1 ●アクセス許可 CPのSビットとRビットを共に0に設定した場合(それ以外の使い方は推奨されな い) APX AP 特権アクセス ユーザアクセス × 0 0 0 アクセス禁止 アクセス禁止 常にアクセス禁止 0 0 1 R/W アクセス禁止 0 1 0 R/W RO 0 1 1 R/W R/W × 1 0 0 <予約> 1 0 1 RO アクセス禁止 1 1 0 RO RO × 1 1 1 RO RO 凡例)×は,HRP3では用いないことを示す. ●キャッシュとメモリモデル(ARMv6以降) TEX C B 000 0 0 ストロングオーダ,共有可能 000 0 1 デバイス,共有可能 000 1 0 外側・内側ライトスルー,no write allocate,Sビットで × 000 1 1 外側・内側ライトバック,no write allocate,Sビットで 001 0 0 外側・内側キャッシュ不可 001 1 1 外側・内側ライトバック,write allocate,Sビットで × 010 0 0 デバイス,非共有 × 1BB A A キャッシュされるメモリ,共有かどうかはSビットで BB … 外側のキャッシュポリシー AA … 内側のキャッシュポリシー(L1キャッシュ) AAとBBの値 00 … キャッシュ不可,バッファ不可 01 … ライトバック,write allocate,バッファ可 10 … ライトスルー,no write allocate,バッファ可 11 … ライトバック,no write allocate,バッファ可 凡例)×は,HRP3では用いないことを示す. ストロングオーダメモリ属性 … 前後にメモリバリア命令があるのと同等 デバイスメモリ属性 … バッファはされる,キャッシュはされない,回数が保存 通常メモリ属性 ●キャッシュとメモリモデル(ARMv5以前) ARMv5TEより前は,TEXビットはサポートされていない.また,第2レベルのスモー ルページディスクリプタには,TEXビットがない.そこで,標準では,TEXビッ トを使わないコードを出すことにする. C B 0 0 ストロングオーダ 0 1 デバイス 1 0 内側ライトスルー 1 1 内側ライトバック ○CP15コプロセッサの構成 ●TTBCR(Translation Table Base Control Register)… (0, c2, c0, 2) ・TTBR0を使うか,TTBR1を使うかを制御する ・TTBR0が指すセクションテーブルのサイズを制御する ・下位3ビット(N)の意味 000 TTBR0のみを使う.ARMv5との互換モード TTBR0が指すセクションテーブルのサイズは16KB(4Kエントリ) 001 アドレスのMSBが0ならTTBR0を使う.そうでなければTTBR1を使う TTBR0が指すセクションテーブルのサイズは8KB(2Kエントリ) 010 アドレスの上位2ビットがすべて0ならTTBR0を使う.以下同じ TTBR0が指すセクションテーブルのサイズは4KB(1Kエントリ) … … 111 アドレスの上位7ビットがすべて0ならTTBR0を使う.以下同じ TTBR0が指すセクションテーブルのサイズは128B(32エントリ) ・上位29ビットは未使用 → HRP3では,TTBR0のみを使うため,下位3ビットを000に設定する. ●TTBR0(Translation Table Base Register 0)… (0, c2, c0, 0) ・第1レベルテーブルの物理アドレスを保持するレジスタ ・プロセス切換え時に書き換える ・上位18+Nビット 第1レベルテーブルの物理アドレス ・ビット[4:3] ページテーブル領域に対する外側のキャッシュポリシー 00:Outer Noncachable 01:Outer Cachable Write-Back cached, Write Allocate 10:Outer Cachable Write-Through, No Allocate on Write 11:Outer Cachable Write-Back, No Allocate on Write ・ビット[1] ページテーブル領域が共有(1)か非共有(0)か ・他のビットは未使用 ●TTBR1(Translation Table Base Register 1)… (0, c2, c0, 1) → HRP3では使わない. ●DACR(Domain Access Control Register)… (0, c3, c0, 0) ・各ドメインに対して,以下のいずれかを設定する. 00:アクセスできない 01:TLBエントリのアクセス許可に従う(client) 10:<予約> 11:TLBエントリのアクセス許可にかかわらず必ずアクセスできる(manager) ・ビット[31:30] … ドメイン15の設定 …  ビット[1:0] … ドメイン0の設定 → HRP3カーネルでは,0x01U(ドメイン0に対してTLBエントリのアクセス許可 に従う,他のドメインはアクセスできない)に設定する. ●定数定義 /* * サイズの定義 */ #define ARM_SSECTION_SIZE 0x1000000 /* スーパーセクション(16MB)*/ #define ARM_SECTION_SIZE 0x0100000 /* セクション(1MB)*/ #define ARM_LPAGE_SIZE 0x0010000 /* ラージページ(64KB)*/ #define ARM_PAGE_SIZE 0x0001000 /* スモールページ(4KB)*/ /* * 第1レベルディスクリプタの設定値 */ #define ARMV6_MMU_DSCR1_FAULT 0x00000 /* フォルト */ #define ARMV6_MMU_DSCR1_PAGETABLE 0x00001 /* コアースページテーブル */ #define ARMV6_MMU_DSCR1_SECTION 0x00002 /* セクション */ #define ARMV6_MMU_DSCR1_SSECTION 0x40002 /* スーパーセクション */ #define ARMV6_MMU_DSCR1_NONGLOBAL 0x20000 /* グローバルでない */ #define ARMV6_MMU_DSCR1_SHARED 0x10000 /* プロセッサ間で共有 */ #define ARMV6_MMU_DSCR1_APX0 0x00000 /* APXビットが0 */ #define ARMV6_MMU_DSCR1_APX1 0x08000 /* APXビットが1 */ #define ARMV6_MMU_DSCR1_TEX000 0x00000 /* TEXビットが000 */ #define ARMV6_MMU_DSCR1_TEX001 0x01000 /* TEXビットが001 */ #define ARMV6_MMU_DSCR1_TEX010 0x02000 /* TEXビットが010 */ #define ARMV6_MMU_DSCR1_TEX100 0x04000 /* TEXビットが100 */ #define ARMV6_MMU_DSCR1_AP01 0x00400 /* APビットが01 */ #define ARMV6_MMU_DSCR1_AP10 0x00800 /* APビットが10 */ #define ARMV6_MMU_DSCR1_AP11 0x00c00 /* APビットが11 */ #define ARMV6_MMU_DSCR1_ECC 0x00200 /* ECCが有効(MPCore)*/ #define ARMV6_MMU_DSCR1_NOEXEC 0x00010 /* 実行不可 */ #define ARMV6_MMU_DSCR1_CB00 0x00000 /* Cビットが0,Bビットが0 */ #define ARMV6_MMU_DSCR1_CB01 0x00004 /* Cビットが0,Bビットが1 */ #define ARMV6_MMU_DSCR1_CB10 0x00008 /* Cビットが1,Bビットが0 */ #define ARMV6_MMU_DSCR1_CB11 0x0000c /* Cビットが1,Bビットが1 */ /* * 第2レベルディスクリプタの設定値 */ #define ARMV6_MMU_DSCR2_FAULT 0x0000 /* フォルト */ #define ARMV6_MMU_DSCR2_LARGE 0x0001 /* ラージページ */ #define ARMV6_MMU_DSCR2_SMALL 0x0002 /* スモールページ */ #define ARMV6_MMU_DSCR2_NONGLOBAL 0x0800 /* グローバルでない */ #define ARMV6_MMU_DSCR2_SHARED 0x0400 /* プロセッサ間で共有 */ #define ARMV6_MMU_DSCR2_APX0 0x0000 /* APXビットが0 */ #define ARMV6_MMU_DSCR2_APX1 0x0200 /* APXビットが1 */ #define ARMV6_MMU_DSCR2_AP01 0x0010 /* APビットが01 */ #define ARMV6_MMU_DSCR2_AP10 0x0020 /* APビットが10 */ #define ARMV6_MMU_DSCR2_AP11 0x0030 /* APビットが11 */ #define ARMV6_MMU_DSCR2_CB00 0x0000 /* Cビットが0,Bビットが0 */ #define ARMV6_MMU_DSCR2_CB01 0x0004 /* Cビットが0,Bビットが1 */ #define ARMV6_MMU_DSCR2_CB10 0x0008 /* Cビットが1,Bビットが0 */ #define ARMV6_MMU_DSCR2_CB11 0x000c /* Cビットが1,Bビットが1 */ /* ラージページのディスクリプタ用 */ #define ARMV6_MMU_DSCR2L_TEX000 0x0000 /* TEXビットが000 */ #define ARMV6_MMU_DSCR2L_TEX001 0x1000 /* TEXビットが001 */ #define ARMV6_MMU_DSCR2L_TEX010 0x2000 /* TEXビットが010 */ #define ARMV6_MMU_DSCR2L_TEX100 0x4000 /* TEXビットが100 */ #define ARMV6_MMU_DSCR2L_NOEXEC 0x8000 /* 実行不可 */ /* スモールページのディスクリプタ用 */ #define ARMV6_MMU_DSCR2S_TEX000 0x0000 /* TEXビットが000 */ #define ARMV6_MMU_DSCR2S_TEX001 0x0040 /* TEXビットが001 */ #define ARMV6_MMU_DSCR2S_TEX010 0x0080 /* TEXビットが010 */ #define ARMV6_MMU_DSCR2S_TEX100 0x0100 /* TEXビットが100 */ #define ARMV6_MMU_DSCR2S_NOEXEC 0x0001 /* 実行不可 */ 以上