/* * At this point we don't know whether the cache is enabled or not - a * bootloader may have enabled it. There are at least 2 things that * could be dirty in the cache at this point: * 1. kernel command line set up by boot loader * 2. spilled registers from the prolog of this function * => before re-initialising the cache, we must do a purge of the whole * cache out to memory for safety. As long as nothing is spilled * during the loop to lines that have already been done, this is safe. * - RPC
*/ if (ccr & CCR_CACHE_ENABLE) { unsignedlong ways, waysize, addrstart;
waysize = current_cpu_data.dcache.sets;
#ifdef CCR_CACHE_ORA /* * If the OC is already in RAM mode, we only have * half of the entries to flush..
*/ if (ccr & CCR_CACHE_ORA)
waysize >>= 1; #endif
waysize <<= current_cpu_data.dcache.entry_shift;
#ifdef CCR_CACHE_EMODE /* If EMODE is not set, we only have 1 way to flush. */ if (!(ccr & CCR_CACHE_EMODE))
ways = 1; else #endif
ways = current_cpu_data.dcache.ways;
addrstart = CACHE_OC_ADDRESS_ARRAY; do { unsignedlong addr;
addrstart += current_cpu_data.dcache.way_incr;
} while (--ways);
}
/* * Default CCR values .. enable the caches * and invalidate them immediately..
*/
flags = CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE;
#ifdef CCR_CACHE_EMODE /* Force EMODE if possible */ if (current_cpu_data.dcache.ways > 1)
flags |= CCR_CACHE_EMODE; else
flags &= ~CCR_CACHE_EMODE; #endif
/* * Set the SR.DSP bit, wait for one instruction, and then read * back the SR value.
*/
__asm__ __volatile__ ( "stc\tsr, %0\n\t" "or\t%1, %0\n\t" "ldc\t%0, sr\n\t" "nop\n\t" "stc\tsr, %0\n\t"
: "=&r" (sr)
: "r" (SR_DSP)
);
/* If the DSP bit is still set, this CPU has a DSP */ if (sr & SR_DSP)
current_cpu_data.flags |= CPU_HAS_DSP;
/* Disable the DSP */ if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) {
printk("DSP Disabled\n");
current_cpu_data.flags &= ~CPU_HAS_DSP;
}
/* Now that we've determined the DSP status, clear the DSP bit. */
release_dsp();
} #else staticinlinevoid dsp_init(void) { } #endif/* CONFIG_SH_DSP */
/** * cpu_init * * This is our initial entry point for each CPU, and is invoked on the * boot CPU prior to calling start_kernel(). For SMP, a combination of * this and start_secondary() will bring up each processor to a ready * state prior to hand forking the idle loop. * * We do all of the basic processor init here, including setting up * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and * subsequently platform_setup()) things like determining the CPU * subtype and initial configuration will all be done. * * Each processor family is still responsible for doing its own probing * and cache configuration in cpu_probe().
*/
asmlinkage void cpu_init(void)
{
current_thread_info()->cpu = hard_smp_processor_id();
/* First, probe the CPU */
cpu_probe();
if (current_cpu_data.type == CPU_SH_NONE)
panic("Unknown CPU");
/* First setup the rest of the I-cache info */
current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
current_cpu_data.icache.linesz;
/* Boot CPU sets the cache shape */
detect_cache_shape();
}
fpu_init();
dsp_init();
/* * Initialize the per-CPU ASID cache very early, since the * TLB flushing routines depend on this being setup.
*/
current_cpu_data.asid_cache = NO_CONTEXT;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.