S3C2410 支持MMU,具体的内容可见附录3 “RealView MDK 中如何对MMU 进行操作”。当程序运行在SDRAM 中时,需要运行MMU,以便能够找到正确的异常入
口。具体的函数实现过程如下:
/****************************************************************
* name: EnableMMU
* func: Enable the MMU
* para: none
* ret: none
* modify:
* comment:
****************************************************************/
void EnableMMU()
{
unsigned int ctl;
ctl = ARM_ReadControl();
ctl |= (1 << 0);
ARM_WriteControl(ctl);
}
/***********************************************************
* name: InitMMU
* func: Initialization the MMU
* para: pTranslationTable-TranslationTable Address
* ret: none
* modify:
* comment:
*****************************************************************/
void InitMMU(unsigned int *pTranslationTable)
{
int i;
// Program the TTB
ARM_WriteTTB((unsigned int) pTranslationTable);
// Program the domain access register
ARM_WriteDomain(0xC0000000); // domain 15: access are not checked
// Reset table entries
for (i = 0; i < 0x200; ++i)
pTranslationTable[i] = 0;
// Program level 1 page table entry
pTranslationTable[0x0] =
(0x300 << 20) | // Physical Address
(1 << 10) | // Access in supervisor mode
(15 << 5) | // Domain
1 << 4 |
0x2; // Set as 1 Mbyte section
pTranslationTable[0x1] =
(0x301 << 20) | // Physical Address
(1 << 10) | // Access in supervisor mode
(15 << 5) | // Domain
1 << 4 |
0x2; // Set as 1 Mbyte section
pTranslationTable[0x2] =
(0x302 << 20) | // Physical Address
(1 << 10) | // Access in supervisor mode
(15 << 5) | // Domain
1 << 4 |
0x2; // Set as 1 Mbyte section
pTranslationTable[0x3] =
(0x303 << 20) | // Physical Address
(1 << 10) | // Access in supervisor mode
(15 << 5) | // Domain
1 << 4 |
0x2; // Set as 1 Mbyte section
for(i = 0x200; i < 0xFFF; ++i)
pTranslationTable[i] =
(i << 20) | // Physical Address
(1 << 10) | // Access in supervisor mode
(15 << 5) | // Domain
1 << 4 |
0x2; // Set as 1 Mbyte section
EnableMMU(); // Enable the MMU
}
/****************************************************************
* name: ARM_WriteTTB
* func: Write Translation table base register
* para: TTB Address
* ret: none
* modify:
* comment:
*************************************************************/
__inline void ARM_WriteTTB(unsigned int ttb)
{
__asm("MCR p15, 0, (ttb & 0xFFFFC000), c2, c0, 0");
}
/*************************************************************
* name: ARM_WriteDomain
* func: Write domain access control
* para: Domain NO.
* ret: none
* modify:
* comment:
*******************************************************************/
__inline void ARM_WriteDomain(unsigned int domain)
{
__asm("MCR p15, 0, domain, c3, c0, 0");
}
因为对于MMU 的控制必须在管理态下进行,故应该对启动代码进行相应的
修改。其中粗体部分为添加的内容。
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enable MMU Map Address 0x00 to 0x300000000,So if have no norflash the
interrupt can also work!
IF :DEF:ENABLEMMU
IMPORT InitMMU
STMFD SP!,{R0}
LDR R0, =TTB_ADDR
BL InitMMU
LDMFD SP!,{R0}
ENDIF
; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
注意设置:Option or target ==>选择Asm 标签页进行汇编器属性配置。因为程序运行在SDRAM 中时,需要MMU,故需要在Define 中预定义:ENABLEMMU。该标号用来作为启动代码中的“IF:DEF:ENABLEMMU”的判断条件。