按照mips的規範,在32位系統中程式位址(虛擬位址)空間分成4個部分:
其中,kseg0與kseg1指向的位址空間指向的是同一塊512mb實體地址,即0x00000000~0x20000000的實體地址,這一塊位址在龍芯1b的位址劃分中,是作為ddr的位址與i/o裝置位址
這兩段位址不需要經過mmu即可訪問,其中kseg0需要經過cache,所以在cache初始化之前不能訪問。也就是說不經過mmu的情況下,只能訪問到最多512mb的記憶體空間。
如果需要使用超過512mb空間則需要使用mmu進行程式位址(虛擬位址)與實體地址的轉換,否則未作對映的記憶體不能使用,這個時候就需要將tlb初始化。
假設:首先確定需要做對映的記憶體空間大小以及起始位置,假設需要將kuseg的2g記憶體空間都用上,那麼虛擬位址的大小就是2g,起始位址為0x00000000;需要對映到的實體地址大小也為2g,起始位址為0x30000000。
從手冊可以知道,gs232共有32個tlb表項,所以按照頁式的虛擬記憶體管理機制,2g的記憶體需要每頁的大小為:2048mb/32=64mb。
1、index暫存器:寫tlb索引項
配置方式:由於31~6位預設為0,所以寫這個暫存器的時候直接寫低位值即可,如第4項,則賦值為4(0x00000004)即可;
2、pagemask寄存:配置記憶體頁的大小
配置方式:根據暫存器的定義,只在28~13位進行有效賦值,所以這裡給mask暫存器的賦值只有9中:
頁尺寸賦值
配置方法:有效的位址位是31~13位,一般12 ~ 0位設定成0,所以寫暫存器賦值範圍:0x00000000 ~ 0xffffe000。
4、entrylo0、entrylo1暫存器:出口位址,即實體地址頁幀號,分別對應入口位址的兩個虛擬位址頁幀號(配置的時候乙個entryhi對應兩個entrylo)
配置方法:第25~6位是有效位址位,將需要指向的實體地址首位址右移6位,使位址位對齊暫存器的25 ~ 6位,之後將其餘位先置零(與上乙個0x3fffffc0,這裡之所以將29 ~ 26 也保留,是因為這幾位一般作為頁幀號的一部分,但是實際上直接寫0,所以開始就右移6位補零)。隨後根據定義對其餘為賦值。按照ls1b中的例子,將0、1、2、5四位置1,其餘保持0即可。
根據假設的條件,參照pmon原始碼中的tlb配置程式,重寫tlb的配置程式
li a1,0x80000000 //設定需要對映的位址空間大小
li a0,0x00000000 //設定虛擬位址的起始位址,即首頁的起始位址
li a4,0x30000000 //設定對映到的實體地址的首位址
li a3,0 //設定tlb index,起始為0
li a2,0x07ffe000 //設定記憶體頁大小,因為這裡設定的64mb,檢視暫存器的說明可知需要賦值7ffe000
mtc0 a2,cop_0_tlb_pg_mask //將值寫入暫存器
1://迴圈點
and a2,a0,0x0xfffff000 //將a0的虛擬頁首位址取高20位放到a2中
mtc0 a2,cop_0_tlb_hi //寫入entryhi暫存器。這裡相當於同時配置了兩個虛擬頁的首位址(原因檢視entryhi暫存器的說明)
//將上面兩個虛擬位址頁需要對應的物理頁位址
move a2,a4 //第乙個實體地址,先放入a2暫存器
srl a2,a2,6 //將位址右移6位,準備寫入entrylo0暫存器
and a2,a2,0x3fffffc0 //取29~6位
ori a2,0x00000017 //將0、1、2、5位置1
mtc0 a,cop_0_tlb_lo0 //寫入entrylo0暫存器
mtc0 a2,cop_0_tlb_lo1 //寫入entrylo1暫存器
mtc0 a3,cop_0_tlb_index //將開始設定的tlb索引號寫入index暫存器
addiu a3,1
li a2,0x08000000 //設定步長,由於一次配置了兩個記憶體頁,所以步長為128mb,即0x08000000
subu a1,a2 //將需要配置的記憶體空間減少128mb
noptlbwi //配置好的暫存器寫入tlb
bgtz a1,1b //判斷記憶體是否已經配置完畢,即看a1是否為0,否則跳轉到1處繼續配置
addu a0,a2 //如果配置完畢,將多減去的128mb加回
jr ra //跳轉回主程式
nop
配置完畢
see mips run
龍芯 1b 處理器使用者手冊
ls232使用者手冊