init_cacheattr()

Initialize board-level caches, and populate the cacheattr member in the system page.

Synopsis:

void init_cacheattr (void)

Arguments:

None.

Description:

This function initializes the system page's cacheattr member with information about board-level caches. This function may be a stub, if there are no board-level caches. However, it may also be used to handle hardware errata that affect board-level caches, or to improve performance.

For many x86 platforms, the generic function works. For ARM platforms, board-specific functions are often required.

Note: The init_cpuinfo() function initializes caches implemented in the CPU.

Example:

Below is the code for a init_cacheattr() function that looks after errata and improves performance of an ARM board (the Texas Instruments DRA74x and DRA75x (Jacinto 6) Vayu EVM):

#include "dra74x_startup.h"

/*
 * ARM errata 798870 says:
 * If back-to-back speculative cache line fills (fill A and fill B) are
 * issued from the L1 data cache of a CPU to the L2 cache, the second
 * request (fill B) is then cancelled, and the second request would have
 * detected a hazard against a recent write or eviction (write B) to the
 * same cache line as fill B then the L2 logic might deadlock.
 */
static void arm_errata_798870(void)
{
	unsigned val;
	unsigned monitor_id;

	/* Read Main ID Register (MIDR) */
	__asm__ __volatile__ ("mrc p15, 0, %0, c0, c0, 0" : "=r" (val));

	val = (val >> 4);
	val &= 0xf;

	/*
	 * L2ACTLR[7]: Enable hazard detect timeout for A15.
	 */
	if (val == 0xf) {
		__asm__ __volatile__ ("mrc p15, 1, %0, c15, c0, 0" : "=r" (val));

		/*
		 * Set L2ACTLR[7] to reissue any memory transaction in the L2 that has been
		 * stalled for 1024 cycles to verify that its hazard condition still exists
		 */
		val |= (1 << 7);
		monitor_id = 0x104;

		/* Set L2 Cache Auxiliary control register - value to write in R0 */
		secure_monitor_call(monitor_id, val, 0, NULL, NULL);
	}
}

void init_cacheattr()
{
    if(!in_hvc) {
        arm_errata_798870();
    }
}