ARM9260EJ-S MMU初始化问题
我在初始化ARM9260EJ-S CPU(AT91SAM9260EJ-S)时遇到了一个问题,SDRAM 8M,按Section初始化,影射成8个块,每块1M,SDRAM的物理地址为0x20000000,未启动MMU时,SDRAM上的所有读写都正常,启动MMU之后,0x20500000开始的1M SDRAM读写就发现异常,MMU初始化的代码如下:
//*----------------------------------------
//* \fn AT91F_InitMMU
//* \brief Initialize MMU
//*----------------------------------------
void AT91_ARM_MMUInit(void)
{
int i;
unsigned int *pTranslationTable=(unsigned int *)_MMUTT_STARTADDRESS;
AT91_ARM_DisableDCache();
AT91_ARM_DisableICache();
AT91_ARM_CleanDCache();//
AT91_ARM_InvalidateICache();
AT91_ARM_DisableMMU();
AT91_ARM_InvalidateIDTLB();
// Program the TTB
AT91_ARM_WriteTTB(_MMUTT_STARTADDRESS);
// Program the domain access register
AT91_ARM_WriteDomain(0x55555555);
//能否访问将根据节或页描述符中的访问权限位确定
// Reset table entries
for (i = 0; i < 4096; ++i)
pTranslationTable[i] = 0;
// Program level 1 page table entry
pTranslationTable[0x0] =
(0x200 < < 20) | // Physical Address(SDRAM-1ST)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain 15
1 < < 4 | //
3 < < 2 | // C=B=1
0x2; // Set as 1 Mbyte section
//
pTranslationTable[0x1] =
(0x001 < < 20) | // Physical Address(INTROM)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain 15
(1 < < 4 ) | //
(0 < < 2 ) | // C=B=0
0x2; // Set as 1 Mbyte section
pTranslationTable[0x2] =
(0x002 < < 20) | // Physical Address(INTSRAM0)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain 15
(1 < < 4 ) | //
(3 < < 2 ) | // C=B=1
0x2; // Set as 1 Mbyte section
pTranslationTable[0x3] =
(0x003 < < 20) | // Physical Address(INTSRAM1)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain 15
(1 < < 4) | //
(3 < < 2) | // C=B=1
0x2; // Set as 1 Mbyte section
pTranslationTable[0x5] =
(0x005 < < 20) | // Physical Address(UHP)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain 15
(1 < < 4) | //
(0 < < 2) | // C=B=0
0x2; // Set as 1 Mbyte section
//map extern rom (flash 4M)
pTranslationTable[0x100] =
(0x100 < < 20) | // Physical Address(flash -1)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(0 < < 2 ) | // C=B=0
0x2; // Set as 1 Mbyte section
pTranslationTable[0x101] =
(0x101 < < 20) | // Physical Address
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(0 < < 2 ) | // C=B=0
0x2; // Set as 1 Mbyte section
pTranslationTable[0x102] =
(0x102 < < 20) | // Physical Address
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(0 < < 2 ) | // C=B=0
0x2; // Set as 1 Mbyte section
pTranslationTable[0x103] =
(0x103 < < 20) | // Physical Address
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(0 < < 2 ) | // C=B=0
0x2; // Set as 1 Mbyte section
//map sdram (8M)
pTranslationTable[0x200] =
(0x200 < < 20) | // Physical Address
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(3 < < 2 ) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x201] =
(0x201 < < 20) | // Physical Address
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(3 < < 2 ) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x202] =
(0x202 < < 20) | // Physical Address
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(3 < < 2 ) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x203] =
(0x203 < < 20) | // Physical Address
(3 < < 10) | // Access in user mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(3 < < 2 ) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x204] =
(0x204 < < 20) | // Physical Address
(3 < < 10) | // Access in user mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(3 < < 2 ) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x205] =
(0x205 < < 20) | // Physical Address
( 3 < < 10) | // Access in user mode
( 15 < < 5) | // Domain
( 1 < < 4) | //
( 3 < < 2) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x206] =
(0x206 < < 20) | // Physical Address
( 3 < < 10) | // Access in user mode
( 15 < < 5) | // Domain
( 1 < < 4) | //
( 3 < < 2) | // C=B=1
0x2; // Set as 1M byte section
pTranslationTable[0x207] =
(0x207 < < 20) | // Physical Address
( 1 < < 10) | // Access in supervisor mode
( 15 < < 5) | // Domain
( 1 < < 4) | //
( 3 < < 2) | // C=B=1
0x2; // Set as 1M byte section
//map regiseter
pTranslationTable[0xFFF] =
(0xFFF < < 20) | // Physical Address (REGISTER)
(1 < < 10) | // Access in supervisor mode
(15 < < 5) | // Domain
(1 < < 4 ) | //
(0 < < 2 ) | // C=B=0
0x2; // Set as 1M byte section
AT91_ARM_WriteFCSEPID(0);
AT91_ARM_EnableAlignFault();
// Enable the MMU
AT91_ARM_EnableMMU();
AT91_ARM_EnableICache();
AT91_ARM_EnableDCache();
}
[解决办法]
我只用汇编写过mmu地址映射,主要要记住两点:
1)开启mmu的一刹那,虚地址和实地址要处理好,一般是编译的时候把代码地址定为虚地址,这样虚实地址就一样了。
2)还有就是映射表不能被破坏。
你这种情况是部分出问题,那么第一条肯定没问题了,那我估计是在后面哪个地方你把映射表给破坏了。
那之所以后面3M有问题,是因为你前面5M正常读写已经有了缓存,所以即使被破坏也没关系。
如果你试一下,在开启mmu之后立刻把后面7M内存都隔1k写一下数据,如果这样就好了,那么就是这个问题了。
[解决办法]
xue xi
ARM926EJ-S, not 9260EJ-S