一. CP15寄存器
mcr |
將ARM處理器的寄存器中的數據寫到CP15中的寄存器中 |
mrc |
將CP15中的寄存器中的數據讀到ARM處理器的寄存器中 |
4.1.2 CP15寄存器介紹
寄存器編號 |
基本作用 |
在MMU中的作用 |
在PU中的作用 |
0 |
ID編碼(只讀) |
ID編碼和cache類型 |
|
1 |
控制位(可讀寫) |
各種控制位 |
|
2 |
存儲保護和控制 |
地址轉換表基地址 |
Cachability的控制位 |
3 |
存儲保護和控制 |
域訪問控制位 |
Bufferablity控制位 |
5 |
存儲保護和控制 |
內存失效狀態 |
訪問權限控制位 |
6 |
存儲保護和控制 |
內存失效地址 |
保護區域控制 |
7 |
高速緩存和寫緩存 |
高速緩存和寫緩存控制 |
|
8 |
存儲保護和控制 |
TLB控制 |
保留 |
9 |
高速緩存和寫緩存 |
高速緩存鎖定 |
|
10 |
存儲保護和控制 |
TLB鎖定 |
保留 |
13 |
進程標識符 |
進程標識符 |
|
CP15的寄存器C0
CP15中寄存器C0對應兩個標識符寄存器,由訪問CP15中的寄存器指令中的<opcode_2>指定要訪問哪個具體物理寄存器,<opcode_2>與兩個標識符寄存器的對應關係如下所示:
0b000 |
主標識符寄存器 |
0b001 |
cache類型標識符寄存器 |
1)主標識符寄存器
訪問主標識符寄存器的指令格式如下所示:
mrc p15, 0, r0, c0, c0, 0 ;將主標識符寄存器C0,0的值讀到r0中
ARM不同版本體系處理器中主標識符寄存器的編碼格式說明如下。
ARM7之後處理器的主標識符寄存器編碼格式如下所示:
31 24 23 20 19 16 15 4 3 0 |
|||||
由生產商確定 |
產品子編號 |
ARM體系版本號 |
產品主編號 |
處理器版本號 |
|
位 |
說 明 |
||||
位[3: 0] |
生產商定義的處理器版本號 |
||||
位[15: 4] |
生產商定義的產品主編號,最高4位可能的取值爲0~7但不能是0,7 |
||||
位[19: 16] |
0x1 ARM體系版本4 |
||||
位[23: 20] |
生產商的產品子編號,使用子編號來區分不同的產品子類,如產品中不同的高速緩存的大小等 |
||||
位[31: 24] |
生產廠商的編號0x41 =A ARM公司;0x69 =I intel公司 |
2)cache類型標識符寄存器
訪問cache類型標識符寄存器的指令格式如下所示:
mrc p15, 0, r0, c0, c0, 1 ;將cache類型標識符寄存器C0,1的值讀到r0中
ARM處理器中cache類型標識符寄存器的編碼格式如下所示:
位[28: 25] |
指定控制字段位[24: 0]指定的屬性之外的cache的其他屬性 |
位[24] |
定義系統中的數據cache和指令cache是分開的還是統一的: 0 系統的數據cache和指令cache是統一的; 1 系統的數據cache和指令cache是分開的 |
位[23: 12] |
定義數據cache的相關屬性,如果位[24]爲0,本字段定義整個cache的屬性 |
位[31: 24] |
定義指令cache的相關屬性,如果位[24]爲0,本字段定義整個cache的屬性 |
其中控制字段位[28:25]的含義說明如下:
編 碼 |
cache類型 |
cache內容清除方法 |
cache內容鎖定方法 |
0b0000 |
寫通類型 |
不需要內容清除 |
不支持內容鎖定 |
0b0001 |
寫回類型 |
數據塊讀取 |
不支持內容鎖定 |
0b0010 |
寫回類型 |
由寄存器C7定義 |
不支持內容鎖定 |
0b0110 |
寫回類型 |
由寄存器C7定義 |
支持格式A |
0b0111 |
寫回類型 |
由寄存器C7定義 |
支持格式B |
cache塊大小字段bits[1: 0]的含義如下所示:
編 碼 |
cache塊大小 |
0b00 |
2個字(8字節) |
0b01 |
4個字(16字節) |
0b10 |
8個字(32字節) |
0b11 |
16個字(64字節) |
CP15的寄存器C1
訪問主標識符寄存器的指令格式如下所示:
mrc p15, 0, r0, c1, c0{, 0} ;將CP15的寄存器C1的值讀到r0中
mcr p15, 0, r0, c1, c0{, 0} ;將r0的值寫到CP15的寄存器C1中
CP15中的寄存器C1的編碼格式及含義說明如下:
M |
0:禁止MMU或者PU;1:使能MMU或者PU |
A |
0:禁止地址對齊檢查;1:使能地址對齊檢查 |
C |
0:禁止數據/整個cache;1:使能數據/整個cache |
W |
0:禁止寫緩衝;1:使能寫緩衝 |
P |
0:異常中斷處理程序進入32位地址模式;1:異常中斷處理程序進入26位地址模式 |
D |
0:禁止26位地址異常檢查;1:使能26位地址異常檢查 |
L |
0:選擇早期中止模型;1:選擇後期中止模型 |
B |
0:little endian;1:big endian |
S |
在基於MMU的存儲系統中,本位用作系統保護 |
R |
在基於MMU的存儲系統中,本位用作ROM保護 |
F |
0:由生產商定義 |
Z |
0:禁止跳轉預測功能;1:使能跳轉預測指令 |
I |
0:禁止指令cache;1:使能指令cache |
V |
0:選擇低端異常中斷向量0x0~0x1c;1:選擇高端異常中斷向量0xffff0000~ 0xffff001c |
RR |
0:常規的cache淘汰算法,如隨機淘汰;1:預測性淘汰算法,如round-robin淘汰算法 |
L4 |
0:保持ARMv5以上版本的正常功能;1:將ARMv5以上版本與以前版本處理器兼容,不根據跳轉地址的bit[0]進行ARM指令和Thumb狀態切換:bit[0]等於0表示ARM指令,等於1表示Thumb指令 |
CP15中的寄存器C2保存的是頁表的基地址,即一級映射描述符表的基地址。
CP15中的寄存器C3定義了ARM處理器的16個域的訪問權限。
CP15中的寄存器C5是失效狀態寄存器,編碼格式如下所示:
31 9 8 7 4 3 0 |
|||
UNP/SBZP |
0 |
域標識 |
狀態標識 |
其中,域標識bit[7:4]表示存放引起存儲訪問失效的存儲訪問所屬的域。
狀態標識bit[3:0]表示放引起存儲訪問失效的存儲訪問類型,該字段含義如表4-3所示(優先級由上到下遞減)。
表4-3 狀態標識字段含義
引起訪問失效的原因 |
狀態標識 |
域標識 |
C6 |
終端異常(Terminal Exception) |
0b0010 |
無效 |
生產商定義 |
中斷向量訪問異常(Vector Exception) |
0b0000 |
無效 |
有效 |
地址對齊 |
0b00x1 |
無效 |
有效 |
一級頁表訪問失效 |
0b1100 |
無效 |
有效 |
二級頁表訪問失效 |
0b1110 |
有效 |
有效 |
基於段的地址變換失效 |
0b0101 |
無效 |
有效 |
基於頁的地址變換失效 |
0b0111 |
有效 |
有效 |
基於段的存儲訪問中域控制失效 |
0b1001 |
有效 |
有效 |
基於頁的存儲訪問中域控制失效 |
0b1101 |
有效 |
有效 |
基於段的存儲訪問中訪問權限控制失效 |
0b1111 |
有效 |
有效 |
基於頁的存儲訪問中訪問權限控制失效 |
0b0100 |
有效 |
有效 |
基於段的cache預取時外部存儲系統失效 |
0b0110 |
有效 |
有效 |
基於頁的cache預取時外部存儲系統失效 |
0b1000 |
有效 |
有效 |
基於段的非cache預取時外部存儲系統失效 |
0b1010 |
有效 |
有效 |
CP15中的寄存器C6
CP15中的寄存器C5是失效地址寄存器,編碼格式如下所示:
31 0 |
失效地址(虛擬地址) |
CP15中的寄存器C7
CP15的C7寄存器用來控制cache和寫緩存,它是一個只寫寄存器,讀操作將產生不可預知的後果。
訪問CP15的C7寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c7>, crm, <opcode_2> ;<rd>、<crm>和<opcode_2>的不同取值組合 實現不同功能
CP15中的寄存器C8
CP15的C8寄存器用來控制清除TLB的內容,是隻寫寄存器,讀操作將產生不可預知的後果。
訪問CP15的C8寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c8>, crm, <opcode_2> ;<rd>、<crm>和<opcode_2>的不同取值組合實現不同功能,見第4.2節
CP15中的寄存器C9
CP15的C9寄存器用於控制cache內容鎖定。
訪問CP15的C9寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c9>, c0, <opcode_2>
mrc p15, 0, <rd>, <c9>, c0, <opcode_2>
如果系統中包含獨立的指令cache和數據cache,那麼對應於數據cache和指令cache分別有一個獨立的cache內容鎖定寄存器,<opcode_2>用來選擇其中的某個寄存器:
<opcode_2>=1選擇指令cache的內容鎖定寄存器;
<opcode_2>=0選擇數據cache的內容鎖定寄存器。
CP15的C9寄存器有A、B兩種編碼格式。編碼格式A如下所示:
31 32-W 31-W 0 |
|
cache組內塊序號index |
0 |
其中index表示當下一次發生cache未命中時,將預取的存儲塊存入cache中該塊對應的組中序號爲index的cache塊中。此時序號爲0~index-1的cache塊被鎖定,當發生cache替換時,從序號爲index到ASSOCIATIVITY的塊中選擇被替換的塊。
編碼格式B如下所示:
31 30 W W-1 0 |
|||
L |
0 |
cache組內塊序號index |
|
位 |
說 明 |
||
L=0 |
當發生cache未命中時,將預取的存儲塊存入cache中該塊對應的組中序號爲index的cache塊中 |
續表
位 |
說 明 |
L=1 |
如果本次寫操作之前L=0,並且index值小於本次寫入的index,本次寫操作執行的結果不可預知;否則,這時被鎖定的cache塊包括序號爲0~index-1的塊,當發生cache替換時,從序號爲index到ASSOCIATIVITY的塊中選擇被替換的塊 |
CP15的寄存器C10
CP15的C10寄存器用於控制TLB內容鎖定。
訪問CP15的C10寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c10>, c0, <opcode_2>
mrc p15, 0, <rd>, <c10>, c0, <opcode_2>
如果系統中包含獨立的指令TLB和數據TLB,那麼對應於數據TLB和指令TLB分別有一個獨立的TLB內容鎖定寄存器,<opcode_2>用來選擇其中的某個寄存器:
<opcode_2>=1選擇指令TLB的內容鎖定寄存器;
<opcode_2>=0選擇數據TLB的內容鎖定寄存器。
C10寄存器的編碼格式如下:
31 30 32-W 31-W 32-2W 31-2W 1 0 |
|||||
可被替換的條目起始地址的base |
下一個將被替換的條目地址victim |
0 |
P |
||
位 |
說 明 |
||||
victim |
指定下一次TLB沒有命中(所需的地址變換條目沒有包含在TLB中)時,從內存頁表中讀取所需的地址變換條目,並把該地址變換條目保存在TLB中地址victim處 |
||||
base |
指定TLB替換時,所使用的地址範圍,從(base)到(TLB中條目數-1);字段victim的值應該包含在該範圍內 |
||||
P |
1:寫入TLB的地址變換條目不會受使整個TLB無效操作的影響,一直保持有效;0:寫入TLB的地址變換條目將會受到使整個TLB無效操作的影響 |
CP15的寄存器C13
C13寄存器用於快速上下文切換FCSE。
訪問CP15的C13寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c13>, c0, 0
mrc p15, 0, <rd>, <c13>, c0, 0
C13寄存器的編碼格式如下所示:
31 25 24 0 |
|
PID |
0 |
其中,PID表示當前進程的所在的進程空間塊的編號,即當前進程的進程標識符,取值爲0~127。
0:MVA(變換後的虛擬地址)= VA(虛擬地址),禁止FCSE(快速上下文切換技術),系統復位後PID=0;
非0:使能FCSE。
二.MMU原理介紹
ARM地址轉換過程中涉及三個概念:virtual addr(VA),變換後的虛擬地址(不同進程使用相同虛擬地址的問題)(MVA),物理地址(PA).
三.MMU編程實例
MMU是由協處理器(cp15)控制的,最多會用到兩級頁表:以段(Section,1MB)的方式進行轉換時只用到一級頁表,以頁(page)的方式進行轉換時用到兩級頁表。頁的大小有3種:大頁(64KB),小頁(4KB),極小頁(1KB)。
條目也稱爲"描述符"(Descriptor),有:段描述符,大頁描述符,小頁描述符,極小頁描述符----它們保存段、大頁、小頁或極小頁的起始物理地址;粗頁表描述符、細頁表描述符---他們保存二級頁表的物理地址
TTB保存了一級頁表所存放的實際物理地址,要求16KB對齊,以段的方式映射,4GB的虛擬地址空間,需要段描述符4096個(每個段描述符映射1M空間),每個描述符佔用4byte,所以映射一級頁表佔用的空間爲16KB。
我們假設一級頁表存放在物理地址:0x30000000.
第一步:
獲得虛擬地址所對應的段描述符所在的地址
addr = TTB&0xffffc000 | ((viraddr >> 20) << 2 ) = 0x30000000 & 0xfffc000 | ((0xa0004000 >> 20) << 2)= 0x30000000 | (0xa00 << 2) = 0x30002800
第二步:
從0x30002800取出虛擬地址所對應的段描述符
段描述的構造我們到後面再來講解,這裏我們假設我們把0xa0004000映射到實際的物理地址0x30004000,則這裏的[31:20]爲0x300
第三步:
組合成實際的物理地址
phyaddr = 0x300 << 20 | (0xa0004000 & 0xfffff) = 0x30004000
三.實驗
目標:以段的方式映射s3c2410的地址空間,一級頁表存放在0x30000000
流程:
A.計算每個虛擬地址對應段描述符所在的地址(addr),方法如下:
B.構造段描述符
注意:Section base address 存放的是實際的物理地址的[31:20]
C.存放段描述符
(unsigned int *)addr = section descriptor
實例代碼:
/*頁表項內容*/
#define PAGE_TABLE_SECTION_AP (0x01 << 10)
#define APGE_TABLE_SECTION_DOMAIN (0x0 << 5)
#define PAGE_TABLE_SECTION_CACHE_WB (0x0 << 2)
#define PAGE_TABLE_SECTION_4BIT (1 << 4)
#define PAGE_TABLE_SECTION_TYPE (0x2)
/*段大小*/
#define SECTION_SIZE 0x100000
//根據虛擬地址和頁表基地址確定頁表項所在的物理地址
unsigned int get_pgtindex_addr(unsigned int viraddr,unsigned int pgtaddr)
{
unsigned int addr;
/*[31:14]頁表基地地址 [13: 2]虛擬地址>>20位得到的page index [1 : 0]總是爲0,因爲每一項佔用4byte*/
addr = (pgtaddr & PAGE_TABLE_BASE_MASK) | (((viraddr & VIRADDR_MASK) >> 20) << 2);
return addr;
}
//獲取頁表項
unsigned int get_page_entry(unsigned int phyaddr)
{
unsigned int entry_value;
/*[31:20]section base address *[19:12] *[11:10]AP *[9] *[8:5]Domain
*[4]:1 *[3]:C *[2]:B *[1:0]:Type*/
entry_value = (phyaddr & PHYADDR_MASK) | PAGE_TABLE_SECTION_AP |\
PAGE_TABLE_SECTION_CACHE_WB | PAGE_TABLE_SECTION_4BIT|\
PAGE_TABLE_SECTION_TYPE;
return entry_value;
}
/*創建一級頁表:段描述符*/
void create_page_table()
{int i;
unsigned int pgt_index_addr;
unsigned int viraddr,phyaddr,pgtaddr;
/*在這裏我們將0x00000000開始的1M物理空間映射到0x00000000開始的虛擬地址空間*/
phyaddr = SRAM_START_ADDR;
viraddr = phyaddr;
pgtaddr = PAGE_TABLE_BASE;
pgt_index_addr = get_pgtindex_addr(viraddr,pgtaddr);
*(volatile unsigned int *)pgt_index_addr = get_page_entry(phyaddr);
/*映射64MSDRAM*/
for(phyaddr = SDRAM_ADDR_START,viraddr = VMRAM_ADDR_START;
phyaddr < SDRAM_ADDR_END;phyaddr += SECTION_SIZE,viraddr += SECTION_SIZE)
{
pgtaddr = PAGE_TABLE_BASE;
pgt_index_addr = get_pgtindex_addr(viraddr,pgtaddr);
*(volatile unsigned int *)pgt_index_addr = get_page_entry(phyaddr);
}
/*映射IO地址空間*/
phyaddr = PHIO_ADDR_START;
viraddr = VMIO_ADDR_START;
pgtaddr = PAGE_TABLE_BASE;
pgt_index_addr = get_pgtindex_addr(viraddr,pgtaddr);
*(volatile unsigned int *)pgt_index_addr = get_page_entry(phyaddr);
return;
}
void init_mmu()
{
unsigned long mmu_table_base = PAGE_TABLE_BASE;
asm(
/*set Translation Table Base(TTB) register*/
"mrc p15,0,r0,c2,c0,0\n"
"mov r0,%0\n"
"mcr p15,0,r0,c2,c0,0\n"
/*set Domain Access Control register*/
"mrc p15,0,r0,c3,c0,0\n"
"mvn r0,#0\n"
"mcr p15,0,r0,c3,c0,0\n"
/*Enable MMU*/
"mrc p15,0,r0,c1,c0,0\n"
"orr r0, #0x1\n"
"mcr p15,0,r0,c1,c0,0\n"
"mov r0,r0\n"
"mov r0,r0\n"
"mov r0,r0\n"
:
:"r"(mmu_table_base)
:"r0"
);
return;
}
adrl r1,SMRDATA @13個寄存器值存放的地址
.ltorg @聲明一個數據緩衝池的開始
SMRDATA:
.word 0x2201d110 @BWSCON 設置BANK3位寬16,使能nWait,使能UB/LB
.word 0x0700 @BANKCON0
.word 0x700 @BANKCON1
.word 0x700 @BANKCON2
.word 0x700 @BANKCON3
.word 0x700 @BANKCON4
.word 0x700 @BANKCON5
.word (3 << 15) + (1 << 0) @BANKCON6
.word 0x18001 @BANKCON7
.word (1 << 23) + (2 << 18) + (1256 << 0) @REFRESH
.word (1 << 7) + (1 << 0) @BANKSIZE
.word (3 << 4) @MRSRB6
.word (3 << 4) @MRSRB7