/*************************************** *********
Name: MMU. c
Desc:
Revision: 1.0
**************************************** ********/
# Include "def. H"
# Include "option. H"
# Include "2440addr. H"
# Include "2440lib. H"
# Include "2440slib. H"
# Include "MMU. H"
// 1) only the section table is used.
// 2) The cachable/non-cachable area can be changed by mmt_default value.
// The section size is 1 MB.
Extern char _ ENTRY [];
Void mmu_init (void)
{
Int I, J;
// ============================ Important note ============ ====================
// The current stack and code area can't be re-mapped in this routine.
// If you want memory map mapped freely, your own sophiscated MMU
// Initialization code is needed.
// ================================================ ==================================
Mmu_disabledcache ();
Mmu_disableicache ();
// If write-back is used, the dcache shocould be cleared.
For (I = 0; I <64; I ++)
For (j = 0; j <8; j ++)
Mmu_cleaninvalidatedcacheindex (I <26) | (j <5 ));
Mmu_invalidateicache ();
# If 0
// To complete mmu_init () fast, icache may be turned on here.
Mmu_enableicache ();
# Endif
Mmu_disablemmu ();
Mmu_invalidatetlb ();
// Mmu_setmtt (INT vaddrstart, int vaddrend, int paddrstart, int ATTR)
// Mmu_setmtt (0x00000000, 0x07f00000, 0x00000000, rw_cnb); // bank0
Mmu_setmtt (0x00000000, 0x03f00000, (INT) _ entry, rw_cb); // bank0
Mmu_setmtt (0x04000000, 0x07f00000, 0, rw_ncnb); // bank0
Mmu_setmtt (0x08000000, 0x0ff00000, 0x08000000, rw_cnb); // bank1
Mmu_setmtt (0x10000000, 0x17f00000, 0x10000000, rw_ncnb); // bank2
Mmu_setmtt (0x18000000, 0x1ff00000, 0x18000000, rw_ncnb); // bank3
// Mmu_setmtt (0x20000000, 0x27f00000, 0x20000000, rw_cb); // bank4
Mmu_setmtt (0x20000000, 0x27f00000, 0x20000000, rw_cnb); // bank4 for strata flash
Mmu_setmtt (0x28000000, 0x2ff00000, 0x28000000, rw_ncnb); // bank5
// 30f00000-> 30100000,310 00000-> 30200000
// The following three codes map the S3C2440 virtual address to the physical address (memory), and 2440 is bank6.
Mmu_setmtt (0x30000000,0x30100000,0x30000000, rw_cb); // bank6-1
Mmu_setmtt (0x30200000, 0x33e00000, 0x30200000, rw_ncnb); // bank6-2
//
Mmu_setmgr (0x33f00000, 0x33f00000, 0x33f00000, rw_cb); // bank6-3
Mmu_setmtt (0x38000000, 0x3ff00000, 0x38000000, rw_ncnb); // bank7
Mmu_setmtt (0x40000000, 0x47f00000, 0x40000000, rw_ncnb); // SFr
Mmu_setmtt (0x48000000, 0x5af00000, 0x48000000, rw_ncnb); // SFr
Mmu_setmtt (0x5b000000, 0x5b000000, 0x5b000000, rw_ncnb); // SFr
Mmu_setmtt (0x5b100000, 0xfff00000, 0x5b100000, rw_fault); // not used
Mmu_setttbase (_ mmutt_startaddress );
Mmu_setdomain (0x55555550 | domain1_attr | domain0_attr );
// Domain1: no_access, domain0, 2 ~ 15 = client (AP is checked)
Mmu_setprocessid (0x0 );
Mmu_enablealignfault ();
Mmu_enablemmu ();
Mmu_enableicache ();
Mmu_enabledcache (); // dcache shocould be turned on after MMU is turned on.
}
// ATTR = rw_cb, rw_cnb, rw_ncnb, rw_fault
Void changeromcachestatus (int attr)
{
Int I, J;
Mmu_disabledcache ();
Mmu_disableicache ();
// If write-back is used, the dcache shocould be cleared.
For (I = 0; I <64; I ++)
For (j = 0; j <8; j ++)
Mmu_cleaninvalidatedcacheindex (I <26) | (j <5 ));
Mmu_invalidateicache ();
Mmu_disablemmu ();
Mmu_invalidatetlb ();
Mmu_setmtt (0x00000000, 0x07f00000, 0x00000000, ATTR); // bank0
Mmu_setmtt (0x08000000, 0x0ff00000, 0x08000000, ATTR); // bank1
Mmu_enablemmu ();
Mmu_enableicache ();
Mmu_enabledcache ();
}
Void mmu_setmtt (INT vaddrstart, int vaddrend, int paddrstart, int ATTR)
{
Volatile u32 * PTT;
Volatile int I, nsec;
PTT = (u32 *) _ mmutt_startaddress + (vaddrstart> 20 );
Nsec = (vaddrend> 20)-(vaddrstart> 20 );
For (I = 0; I <= nsec; I ++)
* PTT ++ = ATTR | (paddrstart> 20) + I) <20 );
}
// The above function is the focus of analysis. Vaddrstart is the starting address of the virtual address, vaddrend is the ending address of the virtual address, and paddrstart is the starting address of the physical address, that is, to map the memory from paddrstart to the virtual address from paddrstart (vaddrend> 20)-(varrdstart> 20.
Take mmu_setmtt (0x30000000,0x30100000,0x30000000, rw_cb); // bank6-1 as an example:
The virtual start address is 0x30000000, the end address is 0x30100000, the physical address is 0x3000000, and rw_cb is the access permission control for the memory. The memory size from 0x30000000 (Starting address) to 0x300fffff is 1 m, and from 0x30100000 (ending address) to 0x301fffff is 1 m, therefore, the function maps the virtual addresses 0x30000000 to 0x30100000 to 2 m space starting with the physical address 0x30000000. Refer:
The value of _ mmutt_startaddress in the function is 0x33ff8000. This is the address from the virtual address of 2 ^ 32 which is used as the ing physical address.
PTT = (u32 *) _ mmutt_startaddress + (vaddrstart> 20); the resulting PTT is 0x33ff8300, that is, the physical address of 2 MB will be mapped from here.
Nsec = (vaddrend> 20)-(vaddrstart> 20); obtain the index of the section, where each segment is 1 m. Here we get nsec 1.
For (I = 0; I <= nsec; I ++) // I gets 0 and 1, that is, two segments (2 m)
* PTT ++ = ATTR | (paddrstart> 20) + I) <20 ); use the 12-bit high of the physical starting address + index as the Section base address in the translation table, or the memory permission control bit, and then add PTT as the final virtual address, next, map the next block in the next loop. The memory permission control space is rw_cb here. Check MMU. h and find out
# Define rw_cb (ap_rw | domain0 | CB | desc_sec) // calculated rw_cb: 1100 0001 1110, corresponding to 12 lower bits (AP2 bits, domain4 bits, the value of domain corresponds to the control register3: domain access control register in the 16 regions of the coprocessor CP15. Here, AP is 11, indicating that supervision and user are both readable and writable. The domain is 0000, which corresponds to file0 (Region 0) in control register3. The two in file0 determine whether to check the access permission for the memory area.
C-through (wt) and B-back (WB) modes cannot be set to 1 at the same time. Why is it set to 1 here ???
Previous Article: wince6.0 compiling environment
Next article: identify the source code error line only through the crash address