天天看點

S3C2440 cp15協處理器詳解

2440的協處理器CP15總共有c0~c15這16個協處理器寄存器,各自具有一定的功能定義。但總的來說,cp15主要跟以下功能有關:

1、擷取device id和cache type等一些CPU相關資訊。

2、MMU操作。包括MMU的使能和禁止,虛拟位址到實體位址的映射機制建立

3、通路權限控制。主要用來實作安全機制和linux的寫時複制(copy on write)。

4、設定時鐘模式。init.S中MMU_SetAsyncBusMode和MMU_SetFastBusMode這兩個函數

下面我會分别就以上4種應用詳細分析,并配合代碼進行講解。

1、擷取device id和cache type。這兩個資訊存在p15的c0寄存器中,有意思的是c0寄存器有兩個實體,一個用來存device id(叫做c0.0),另一個用來存cache type(叫做c0.1)這兩個寄存器在讀取時指令不同,請參看以下示例代碼。

U32 P15_ReadID(void)
{
	U32 id;
	__asm{
		mrc	p15,0,id,c0,c0;
	}
	return id;
}

U32 P15_ReadCacheType(void)
{
	U32 id;
	__asm{
		mrc	p15,0,id,c0,c0,1;
	}
	return id;
}
           

對以上代碼的說明:

(1) CPU從p15讀出寄存器隻能使用mrc指令。同樣,寫入p15寄存器隻能使用mcr指令。這兩個指令也是p15唯一可以接受的兩個指令。

(2) __asm{ }用來在c代碼中内嵌彙編。

(3) 從代碼中可以看出,讀出c0.0和c0.1的代碼,在opcode2處有所不同。(讀出c0.1時,opcode2為1.c0.0時opcode2省略)。

(4) 我使用的S3C2440實際讀出的device id為 0x41129200;cache type為:0xd172172。和Jlink Commander識别出得參數對比是相同的。

2、MMU操作。

和MMU有關的p15寄存器為c1(control register)和c2(TTB translation table base register)。其中c2比較簡單,就是用來儲存從虛拟位址到實體位址的位址轉換表的基位址的(轉換表存放在記憶體中,譬如可以放在0x30000000位址),是以我們在初始化mmu的時候,隻要将規劃的轉換表基位址用mcr指令傳送到該c2寄存器即可。而c1寄存器為控制寄存器,詳細定義如下:

Register 1 - Control (read/write) 

All values set to 0 at power-up. 

o    Bit    0 - On-chip MMU turned off (0) or on (1)  用來關閉或使能MMU

o    Bit    1 - Address alignment fault disabled (0) or enabled (1)  關閉或打開位址對齊檢查

o    Bit    2 - Data cache turned off (0) or on (1)  資料cache打開或關閉

o    Bit    3 - Write buffer turned off (0) or on (1) 

o    Bit    7 - Little-endian operation if 0, big-endian if 1  用來選擇大小端格式

o    Bit    8 - System bit - controls the MMU permission system 

o    Bit    9 - ROM bit - controls the MMU permission system  bit8(S bit ) and bit9(R bit)用來管理MMU通路權限,第3部分會詳述

o    Bit  12 - Instruction cache turned off (0) or on (1)”  指令cache打開或關閉

o    Bit  13 - Base location of exception registers. 0x00000000(0) or 0xffff0000(1) 上電啟動位址。

o    Bit  14 - Round robin replacement ,random replacement(0) or round-robin replacement(1). 不太懂這個

o    Bit  15 ~ Bit29   reserved

o    Bit  30  nF bit bit30 和 bit31共同用來決定總線模式。 iA:nF = 00 FastBus mode 

o    Bit  31  iA bit 01 Synchronous mode  10 reserved 11 Asynchronous mode

結合以上對c1寄存器的位定義的分析,我們來看看下面這個函數:

void MMU_Init(void)
{
 	__asm{
 
    	mov r0,#0x30000000; 	// r0=TTBase 即頁表的基位址
      	mcr p15,0,r0,c2,c0,0; 	// C2中存放位址轉換表基位址
    
      	mvn r0, #0;   			// 資料取反傳送指令
        mcr p15,0,r0,c3,c0,0; 	// 通路類型為管理者權限

   	mrc p15,0,r0,c1,c0,0; 	// 讀出協處理器C1
   	orr r0,r0,#01;   		// 或操作,使最低位為1
   	mcr p15,0,r0,c1,c0,0; 	// 給C1指派 
  	}	
}
           

函數中使用ARM寄存器r0作為和協處理器寄存器的接口。mcr p15,0,r0,c2,c0,0這句将r0中得值(0x30000000,這個是我們規劃的轉換表的基位址)放入(是以是mcr,是以是從ARM寄存器到p15協處理器寄存器)c2中。c2即是p15中的轉換表基址。

mrc p15,0,r0,c1,c0,0; 	// 讀出協處理器C1
   	orr r0,r0,#01;   		// 或操作,使最低位為1
   	mcr p15,0,r0,c1,c0,0; 	// 給C1指派 
    典型的讀-改-寫三步操作,目的就是将c1寄存器的bit0置1而同時不影響其他位。根據上面的寄存器定義可知,c1的bit0為MMU enable or disable,是以該三句代碼實際上是打開了MMU。(注意MMU打開前後,位址空間發生了變化。MMU打開前程式是工作在實體位址空間的,而MMU打開後程式便工作在了虛拟位址空間)
           

c1中跟MMU有關的還有data cache和instruction cache的打開和關閉,S bit和 R bit聯合組成的通路權限控制等位。另外,c1中還有其他一些我們可能會用到的資訊位。

譬如:Bit7用來選擇大小端模式,bootloader中一般會有代碼,通過設定該位來告知CPU目前闆子使用的是little endian or big endian。(因為該位上電預設是0,是以預設的模式為小端模式。); Bit13為上電啟動位址,也就是reset excetion複位異常的入口位址。上電預設也是0,是以預設的上電啟動位址為0x00000000。當我們使用mcr指令将該位置1時,便可以将reset exception設定到 0xffff0000,記得這個好像是為了WinCE的移植支援設計的。

3、通路權限控制。

通路權限控制主要由c3(domain access control register)和c1中的S bit 和R bit共同控制。詳細情況請參考 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0151c/I273867.html。

從上面連結中的介紹可以看出,c3中的32bit正好組成16組,每組占用2bit,這兩bit若為0x00,那麼具體的通路規則則由S bit + R bit決定。若為0x01或0x10或0x11則S bit和R bit不起作用。 其實所有的情況都包含在下面這張表中了

AP S R

Supervisor

permissions

User permissions Description
00 No access No access Any access generates a permission fault
00 1 Read-only No access Only Supervisor read permitted
00 1 Read-only Read-only Any write generates a permission fault
00 1 1 Reserved - -
01 x x Read/write No access Access allowed only in Supervisor mode
10 x x Read/write Read-only Writes in User mode cause permission fault
11 x x Read/write Read/write All access types permitted in both modes
xx 1 1 Reserved - -

4、設定bus mode

bootloader中有兩個函數是用來設定bus mode的,關于這個bus mode不是很清楚具體情況,我們這裡隻是分析其操作過程。

MMU_SetAsyncBusMode

    mrc p15,0,r0,c1,c0,0 ;  讀出c1

    orr r0,r0,#R1_nF:OR:R1_iA ;  

    mcr p15,0,r0,c1,c0,0 ; R1的nF和iA位置1,11對應 Asynchronus bus mode

    MOV_PC_LR

MMU_SetFastBusMode

   mrc p15,0,r0,c1,c0,0

   bic r0,r0,#R1_iA:OR:R1_nF ; 清零nF和iA這兩位,00對應 fast bus mode

   mcr p15,0,r0,c1,c0,0

   MOV_PC_LR