Disabling Cache for Shared Memory in Cortex-A9

Disabling Cache for Shared Memory in Cortex-A9

In Xilinx’s Z7000, there are two ARM processors that can exchange information using shared memory.
Then, according to a design note from Xilinx, it is recommended to disable the cache for the shared memory area. The fisherman sees this function.

Xil_SetTlbAttributes(SHARE_BASE, 0x14de2);

I asked CoPilot for the details of this function, and this guy clearly didn’t understand, mumbling and dodging. CoPilot fed with websites like Zhihu is just like this. I wonder why the ARM technical manuals and Xilinx technical manuals are not fed to CoPilot?

These manuals are large and quite difficult to find, and the content that needs to be searched is the details required by programmers, which need to be precise and have no profound principles, making them suitable for this stage of AI to play with. Since domestic companies have no innovation capability, why not strive towards a precise encyclopedia like the fisherman said? Instead, they are imitating a tiger as a dog?

Speaking of which, the fisherman has a post that says writing programs in a confused manner is very dangerous. When I was young, I was almost always clear about the result of each line of code I wrote. For this clarity, the fisherman had to carry a dozen pounds of various manuals to write programs on-site.

Nowadays, many times, in a hurry, it is often difficult to find detailed sources, but many snippets or cases can be found online, and often copying a segment solves the problem. This trend of not seeking understanding is very prevalent, and the punishment is not frequent. However, once something is copied incorrectly, it can be a big pit, even a bottomless one.

Let’s take a look at the program content from Xilinx.

void Xil_SetTlbAttributes(INTPTR Addr, u32 attrib)
{
    u32 *ptr;
    u32 section;
    section = Addr / 0x100000U;
    ptr = &MMUTable;
    ptr += section;
    if (ptr != NULL) {
        *ptr = (Addr & 0xFFF00000U) | attrib;
    }
    Xil_DCacheFlush();
    mtcp(XREG_CP15_INVAL_UTLB_UNLOCKED, 0U);
    /* Invalidate all branch predictors */
    mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0U);
    dsb();//ensure completion of the BP and TLB invalidation
    isb(); /* synchronize context on this processor */
}

Assuming MMUTable is the L1 TLB table, each element is like this:

Disabling Cache for Shared Memory in Cortex-A9

section = Addr / 0x100000U; In this statement, 0x100000 represents 1M. Does it mean that the granularity of the TLB level 1 table is 1M?

The domain provides 16 domains (0~15), each corresponding to two bits in the DACR register. In this case, domain = 14; (the e in 0x14de2). This corresponds to bits D28~D29 in the DACR register.

These two bits: 00 means invalid, which means accessing this domain will result in an error, 01 means client state, security permissions will be restricted, 10 is reserved, and the result is unpredictable; 11 means Manager.

Disabling Cache for Shared Memory in Cortex-A9

When the highest bit of TEX equals 1, in the current case of 0x14de2, XX = 00, CB = 00. Looking at the table below, we know that the outer policy is Non-cacheable, and the inner policy is also Non-cacheable.

Disabling Cache for Shared Memory in Cortex-A9

Disabling Cache for Shared Memory in Cortex-A9

S = 1, indicating Sharable, shared memory.

XN = 0; Execute Never bit (xN).

Non-Global Region Bit (nG) = 0, indicating global memory.

Disabling Cache for Shared Memory in Cortex-A9

APX= 0 AP= 11, indicating read/write full access.

Things took a big turn when I first found this book:

Disabling Cache for Shared Memory in Cortex-A9

Disabling Cache for Shared Memory in Cortex-A9

Disabling Cache for Shared Memory in Cortex-A9

It has over 1300 pages, providing authoritative references for many details about ARM.

Disabling Cache for Shared Memory in Cortex-A9

The D18 of parameter 0x14de2 equals 0, so the section granularity is 1M bytes. For shared memory larger than 1M bytes, this function needs to be called multiple times to disable the cache for the shared memory interval.

Another twist was finding the definition of Xilinx’s MMU constants.

/* Memory type */
#define NORM_NONCACHE 0x11DE2 /* Normal Non-cacheable */
#define STRONG_ORDERED 0xC02 /* Strongly ordered */
#define DEVICE_MEMORY 0xC06 /* Device memory */
#define RESERVED 0x0 /* reserved memory */

/* Normal write-through cacheable shareable */
#define NORM_WT_CACHE 0x16DEA

/* Normal write back cacheable shareable */
#define NORM_WB_CACHE 0x15DE6

/* shareability attribute */
#define SHAREABLE (0x1 << 16)
#define NON_SHAREABLE (~(0x1 << 16))

/* Execution type */
#define EXECUTE_NEVER ((0x1 << 4) | (0x1 << 0))

Thus, the programming basis for disabling the cache in the shared memory interval has been found.

Dear viewers, due to the rush, this is a bit rough, sorry about that.

Leave a Comment

×