AnsweredAssumed Answered

Enable Code Bus Cache for Cortex-M4

Question asked by Stefan Agner on May 23, 2017
Latest reply on Nov 28, 2017 by David Wightman

Hello,

 

I am trying to enable caches for DDR memory for the Cortex-M4. First I was surprised to see that only the first 2MB of the DDR memory seem to be cachable (according to 4.2.9.3.5 Cache Function). Does this also apply to the code bus? This is somewhat unfortunate since the default Linux relocation address is in this area... I continued the tests without Linux (just leave the A7 in U-Boot). I setup my linker file such that the firmware uses the code bus for code and data bus for data:

/* Specify the memory areas */
MEMORY
{
    m_interrupts (RX) : ORIGIN = 0x10000000, LENGTH = 0x00000240
    m_text (RX) :       ORIGIN = 0x10000240, LENGTH = 0x00070000
    m_data (RW) :       ORIGIN = 0x80080000, LENGTH = 0x00080000
}

I added an MPU entry like the one already present for the system bus (0x80000000) and enable the code cache (LMEM_PCCCR) in platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c the same way as the system cache has already been enabled (LMEM_PSCCR).

The results were rather disappointing: I measured 1296ms without caches and 1638ms with code cache enabled! When I use a linker file where I locate the code and data in the system bus region (0x80000000, the execution time drops to 87ms! Somehow it seems that the code cache is not working properly...

 

How can I use the code bus and enable the code cache?

 

Thanks

Stefan

 

Note: I use a C micro benchmark to and task ticks to measure execution speed (benchmark courtesy to the gist).

double squareroot(double x)
{
    double it = x;
    while (fabs(it*it - x) > 1e-13) {
       it = it - (it*it-x)/(2*it);
    }
    return it;
}

void benchmark(void)
{
    const int num_iter = 1000;
    TickType_t t = xTaskGetTickCount();
    volatile double sum_real = 0;
    for (int i = 0; i < num_iter; i++) {
        sum_real += squareroot(10000.0);
    }
    TickType_t ttot = xTaskGetTickCount() - t;
    PRINTF("%d milliseconds\n\r", ttot);
}

Outcomes