syspage_entry cacheattr

The cacheattr area contains information about the configuration of the on-chip and off-chip cache system. It also contains the control() callout used for cache control operations. This entry is filled by the library routines init_cpuinfo() and init_cacheattr().

Note that init_cpuinfo() deals with caches implemented on the CPU itself; init_cacheattr() handles board-level caches.

Each entry in the cacheattr area consists of the following:

Member Description
next index to next lower level entry
line_size size of cache line in bytes
num_lines number of cache lines
flags See below
control callout supplied by startup code (see below).

The total number of bytes described by a particular cacheattr entry is defined by line_size × num_lines.

The flags parameter is a bitmapped variable consisting of the following:

This constant: Means that the cache:
CACHE_FLAG_INSTR Holds instructions.
CACHE_FLAG_DATA Holds data.
CACHE_FLAG_UNIFIED Holds both instructions and data.
CACHE_FLAG_SHARED Is shared between multiple processors in an SMP system.
CACHE_FLAG_SNOOPED Implements a bus-snooping protocol.
CACHE_FLAG_VIRTUAL Is virtually tagged.
CACHE_FLAG_WRITEBACK Does write-back, not write-through.
CACHE_FLAG_CTRL_PHYS Takes physical addresses via its control() function.
CACHE_FLAG_SUBSET Obeys the subset property. This means that one cache level caches something from another level as well. As you go up each cache level, if something is in a particular level, it will also be in all the lower-level caches as well. This impacts the flushing operations of the cache in that a "subsetted" level can be effectively "ignored" by the control() function, since it knows that the operation will be performed on the lower-level cache.
CACHE_FLAG_NONCOHERENT Is noncoherent on SMP.
CACHE_FLAG_NONISA Doesn't obey ISA cache instructions.

The cacheattr entries are organized in a linked list, with the next member indicating the index of the next lower cache entry. This was done because some architectures will have separate instruction and data caches at one level, but a unified cache at another level. This linking allows the system page to efficiently contain the information. Note that the entry into the cacheattr tables is done through the cpuinfo's ins_cache and data_cache. Since the cpuinfo is an array indexed by the CPU number for SMP systems, it's possible to construct a description of caches for CPUs with different cache architectures. Here's a diagram showing a two-processor system, with separate L1 instruction and data caches as well as a unified L2 cache:

Figure 1. Two-processor system with separate L1 instruction and data caches.

Given the above memory layout, here's what the cpuinfo and cacheattr fields will look like:

/*
 * CPUINFO
 */
cpuinfo [0].ins_cache  = 0;
cpuinfo [0].data_cache = 1;

cpuinfo [1].ins_cache  = 0;
cpuinfo [1].data_cache = 1;

/*
 * CACHEATTR
 */
cacheattr [0].next = 2;
cacheattr [0].linesize = linesize;
cacheattr [0].numlines = numlines;
cacheattr [0].flags = CACHE_FLAG_INSTR;

cacheattr [1].next = 2;
cacheattr [1].linesize = linesize;
cacheattr [1].numlines = numlines;
cacheattr [1].flags = CACHE_FLAG_DATA;

cacheattr [2].next = CACHE_LIST_END;
cacheattr [2].linesize = linesize;
cacheattr [2].numlines = numlines;
cacheattr [2].flags = CACHE_FLAG_UNIFIED;

Note that the actual values chosen for linesize and numlines will, of course, depend on the actual configuration of the caches present on the system.