This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Program crashes when enabling I- and D-cache.

Hi,

After initializing and enabling the MMU I enable both the I- and the D-cache. However, having executed a few of the succeeding instructions(see below), the program ends up at a wrong address.

The following code is executed after having generated translation tables for GPMC, On-Chip memory, peripherals, SDRAM and EMIF. It looks like the program is executed correctly if the lines enabling the I- and the D-cache are commented out.

/* Invalidate the TLB. */

__asm __volatile (   "mcr p15, 0, r0, c8, c7, 0  \n" );

/* Set table base register. */

__asm __volatile (   "ldr r0,=__MMU_TABLE_START   \n":::"r0" );
__asm __volatile (   "mcr p15, 0, r0, c2, c0, 0  \n" );

/* Set domain 0 access rights to "client". Client = use MMU translation table access right settings. */

__asm __volatile (   "mov r0, #0x00000001        \n":::"r0" );
__asm __volatile (   "mcr p15, 0, r0, c3, c0, 0  \n" );

/* Enable MMU. */

__asm __volatile (   "mrc p15, 0, r0, c1, c0, 0  \n":::"r0" );
__asm __volatile (   "orr r0, r0, #0x1           \n":::"r0" );
__asm __volatile (   "mcr p15, 0, r0, c1, c0, 0  \n" );

/* Enable I- and D-cache */

__asm __volatile (   "mrc     p15, 0, r0, c1, c0, 0 \n":::"r0" );
__asm __volatile (   "orr     r0, r0, #0x1000       \n":::"r0" );  /* Enable I-cache */
__asm __volatile (   "orr     r0, r0, #0x0004       \n":::"r0" );  /* Enable D-cache */
__asm __volatile (   "mcr     p15, 0, r0, c1, c0, 0 \n" );

/* Set up and enable hardware timer. */

CM_CLKSEL_PER &= ~CLKSEL_GPT2;
CM_FCLKEN_PER |= EN_GPT2;
CM_ICLKEN_PER |= EN_GPT2;

/* Initialize tick interval. */

GPTR2_TCLR = 0;                  /*   <---  Program crashes here      */

Is there something else I have to initialize or what am I missing?

Thanks in advance,

Nicklas

  • Nicklas,

    1. Can you just try to enable either d-cache alone or i-cache alone?

    2. If d-cache is creating the trouble did you double check the page table that you've passed?

    3. Then the third thing would be to check whether the page table base address __MMU_TABLE_START is 14-bit aligned or not.

  • Thanks for your help but I have found the source to my problem.

    I'm not sure how many of you are writing your own setup rather than using Linux but I will mention a few important steps that I came across.

    1. Create page table and write location address where the page table must be located on a 16KB aligned boundary.
    2.  It is important that the code(which enables the MMU) is in a location where virtual and physical addresses are identical.
    3. The L2 cache was initially enabled so if you don't use that cache remember to turn it off.

    __MMUTABLE_START is defined in the link script and as described above has to be aligned on a 16KB (. = Align(0x4000)) boundary.

    /* Invalidate I-cache.*/
    __asm __volatile ( "mcr p15, 0, %0, c7, c5, 0" : : "r" (0) );

    /* Invalidate TLB */
    __asm __volatile( "mcr p15, 0, %0, c8, c7, 0" : : "r" (0) );

    /* Set table base register */
    __asm __volatile ( "mcr p15, 0, %0, c2, c0, 0" : : "r" (&__MMUTABLE_START) : "memory" );

    /* Set domain 0 access rights to "client" */
    __asm __volatile ( "mcr p15, 0, %0, c3, c0, 0" : : "r" (1) );

    /* Disable L2 cache. */
    __asm __volatile ( "mrc p15, 0, %0, c1, c0, 1" : "=r" (lInterim) : : "cc" );
    lInterim &= ~ENABLE_L2_CACHE;
    __asm __volatile ( "mcr p15, 0, %0, c1, c0, 1" : : "r" (lInterim) : "cc" );

    /* Enable L1 caches (I-cache and D-cache) and MMU.*/
    __asm __volatile ( "mrc p15, 0, %0, c1, c0, 0" : "=r" (lInterim) : : "cc" );
    lInterim |= ( ENABLE_I_CACHE | ENABLE_D_CACHE | ENABLE_MMU );
    __asm __volatile ( "dsb                                \t\n" \
                               "mcr p15, 0, %0, c1, c0, 0 \t\n" \
                               "isb "                                       \
                               : : "r" (lInterim) : "cc" );

    Hope this could be of any help.

    /Nicklas