I've been using mmu.c to setup my MMU table and enable the caches - for months now, so I think that part is OK. Now I need to disable the icache, dcache and mmu, do some stuff and re-enable them. But when I disable the cache, the prog starts to behave like it has a will of its own. If I don't disable the cache, then it works normally. Please take a look... // creates a mmu level 1 table with flat address space. #define not_cacheable (1 << 1) // C=B=0 (bit 1 must be set = section descriptor) #define cacheable (7 << 1) // C=B=1 (bit 1 must be set = section descriptor) #define SDRAMsize (32*M) #define SDRAMstart (AT91C_EBI_SDRAM >> 20) #define SDRAMend ((AT91C_EBI_SDRAM + SDRAMsize) >> 20) static void mmu (void) { uint f; uint *pSDRAM = (uint*) AT91C_EBI_SDRAM; // create table // setup all linear addresses, AP(3), domain(0), bit 4(1) // as non-cacheable and as invalid entry for (f = 0; f <= 4095; f++) pSDRAM[f] = (f << 20) | (3 << 10) | (1 << 4); // 1st MB is not user accesible pSDRAM[0] &= (DWORD) ~(1 << 11); // 1st 6MB are not cacheable for (f = 0; f <= 5; f++) pSDRAM[f] |= not_cacheable; // peripherals are not cacheable pSDRAM[4095] |= not_cacheable; // EBI 6 not cacheable pSDRAM[AT91C_EBI_CS6 >> 20] |= not_cacheable; // whole SDRAM is cacheable for (f = SDRAMstart; f < SDRAMend; f++) pSDRAM[f] |= cacheable; // TTBR asm("LDR R0, =0x20000000"); asm("MCR P15, 0, R0, C2, C0, 0"); //assert DACR.D0 (client mode) asm("MRC P15, 0, R0, C3, C0, 0"); asm("BIC R0, R0, #3"); asm("ORR R0, R0, #1"); asm("MCR P15, 0, R0, C3, C0, 0"); // Enable Icache(12), Dcache(2), Alignment(1) and MMU(0) asm("MRC P15, 0, R0, C1, C0, 0"); asm("ORR R0, R0, #4096"); asm("ORR R0, R0, #7"); asm("MCR P15, 0, R0, C1, C0, 0"); } This is in sram0, called from user mode with SVC instruction. disablecache: mov r0,#0 @ drain write buffer mcr p15, 0, r0, c7, c10, 4 mcr p15, 0, r0, c7, c6, 0 @ invalidate dcache mrc p15, 0, r0, c1, c0, 0 @ Disable Icache(12), Dcache(2) and MMU(0) bic r0, r0, #4096 bic r0, r0, #5 mcr p15, 0, r0, c1, c0, 0 mov pc,lr @ return to SWI handler When I'm done, I re-enable the cache (but the prog never reaches here) enablecache: mrc p15, 0, r0, c1, c0, 0 @ Enable Icache(12), Dcache(2), Alignment(1) and MMU(0) orr r0, r0, #4096 orr r0, r0, #7 mcr p15, 0, r0, c1, c0, 0 mov pc,lr
I've copied (almost) this from linux, and it still doesn't work. disablecache: mrc p15, 0, r15, c7, c14, 3 @ test, clean and invalidate bne DisableCache mov r0,#0 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mrc p15, 0, r0, c1, c0, 0 @ Disable Icache(12), Dcache(2) and MMU(0) bic r0, r0, #4096 bic r0, r0, #5 mcr p15, 0, r0, c1, c0, 0 mov pc,lr Can anyone see a problem here?
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.