Cpu features

From LinuxMIPS
Jump to: navigation, search

Linux/MIPS supports a wide range of processors that differ slightly in many features. Kernels that support many different processor types are possible but such a kernel will be relativly large and slow compared to one that supports the bare minimum. <asm/cpu-features.h> contains a number of macros that allow kernel code to be written in a way such that during compilation it will be optimized for a particular target platform.

System-specific configuration

The basic concept is to narrow down the system configuration as much as possible in a config file. Any configuration property that isn't defined in the cpu-features-override.h configuration file will default to runtime detection. If no target-specific configuration file is supplied, Linux will fallback to use include/asm-mips/mach-default/cpu-features-override.h which an empty file. As the result all features will be runtime detected resulting in a somewhat larger and slower but generic kernel. When porting to a new target system this means it's not immediately necessary to supply a new cpu-feature-override.h file because Linux will get things right anyway. But eventually one that defines the target system properties as narrowly as possible should be supplied for optimal performance.

CPU feature test macros

cpu_has_tlb 
True if a processor has a TLB. Linux/MIPS does currently not support TLB-less processors.
cpu_has_4kex 
True if a processor has R4000-style exceptions.
cpu_has_4ktlb 
True if the CPU has an R4000-style TLB, that is a TLB where each entry maps two pages.
cpu_has_fpu 
True if the processor has a FPU.
cpu_has_32fpr 
True if the processor supports the 32/32  model, that is it has 32 double precision registers.
cpu_has_counter 
Set if the CPU has an R4000-style count / compare register.
cpu_has_watch 
True if the processor has an R4000-style watch register. Linux does not really make use of this.
cpu_has_mips16 
True if the processor supports the MIPS16 extension.
cpu_has_divec 
True if the processor supports a Nevada-style separate exception vector for interrupts.
cpu_has_vce 
True if a processor has virtual coherency exceptions.
cpu_has_cache_cdex_p 
True if the processor has a Create Dirty Exclusive cache operation for the D-cache. If this feature exists and a prefetch instruction exists also Linux will prefer the prefetch instruction.
cpu_has_cache_cdex_s 
True if the processor has a Create Dirty Exclusive cache operation for the S-cache. If this feature exists and a prefetch instruction exists also Linux will prefer the prefetch instruction.
cpu_has_prefetch 
True if the processor supports a prefetch instruction and the prefetch instruction actually delivers some performance. The latter condition is not true for the R5000 for example which implements the prefetch instructions as nops. Conditional prefetches are a bad idea, so you really want to define this as a constant only. For more more details see the prefetching page.
cpu_has_mcheck 
True if the processor supports a machine check exception.
cpu_has_ejtag 
True if the system supports EJTAG.
cpu_has_llsc 
True if the system has load linked and store conditional instructions.
cpu_has_vtag_icache 
True if the processor has a virtually tagged I-cache.
cpu_has_dc_aliases 
True if the D-cache of the processor might suffer from virtual aliases.
cpu_has_ic_fills_f_dc 
True if the I-cache may do refills on misses directly from the D-cache. This feature which currently is only implemented in AMD Alchemy processors allows getting away without D-cache flush after code has been modified.
cpu_icache_snoops_remote_store 
True if the I-cache snoops remote stores. This feature on for example the R10000 allows the cache to be optimized to only flush the local I-cache when code has been modified.

This only matters on SMP. Some multiprocessors such as the R10000 have I-Caches that snoop local stores; the embedded ones don't. For maintaining I-cache coherency this means we need to flush the D-cache all the way back to whever the I-cache does refills from, so the I-cache has a chance to see the new data at all. Then we have to flush the I-cache also. Note we may have been rescheduled and may no longer be running on the CPU that did the store so we can't optimize this into only doing the flush on the local CPU.

PLAT_TRAMPOLINE_STUFF_LINE 
RM7000 and RM9000 may throw bizarre exceptions if not the whole cacheline contains valid instructions. For these we ensure proper alignment of signal trampolines and pad them to the size of a full cache lines with nops. This is also used in structure definitions so can't be a test macro like the others.
cpu_has_nofpuex 
True if the CPU does not support FPU exceptions. This is needed for processors with R2000-style FPU coupling.
cpu_has_64bits 
True if the processor is a 64-bit processor. Note that MIPS64 makes the support for 64-bit addresses optional, so if testing for the precense of 64-bit address spaces use cpu_has_64bit_addresses.
cpu_has_64bit_zero_reg 
True if the $zero register has 64-bit. Since this register can't be corrupted it's safe to use as 64-bit register it even on 32-bit kernels, so this feature test macro should always return true on 64-bit processors.
cpu_has_64bit_gp_regs 
True if it's safe to use 64-bit general purpose registers, so this is only set on 64-bit kernels. Some code running with interrupts disabled may use 64-bit registers safely even in 32-bit kernels, so should use cpu_has_64bits instead.
cpu_has_64bit_addresses 
True if 64-bit virtual addresses are in use, that is at the moment this is equivalent to the kernel being 64-bit.
cpu_has_subset_pcaches 
True on processors where the primary caches must be a subset of the secondary cache. This for example is true for the R4000 but not for the RM7000.
cpu_dcache_line_size 
The line size of the data cache.
cpu_icache_line_size 
The line size of the primary I-cache.
cpu_scache_line_size 
The line size of the secondary S-cache, if present. Only used for CPUs with a builtin S-cache controller.