EmbDev.net

Forum: ARM programming with GCC/GNU tools Problem disabling cache on ARM926ej-s


von A. S. (aleksazr)


Rate this post
useful
not useful
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

von A. S. (aleksazr)


Rate this post
useful
not useful
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?

von A. S. (aleksazr)


Rate this post
useful
not useful
Got it!

"bne DisableCache" should be "bne disablecache"

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
No account? Register here.