#include "startup.h" #define timer_start() get_spr(PPC_SPR_TBL) #define timer_diff(s) (get_spr(PPC_SPR_TBL) - (s)) static void run_loop() { volatile unsigned i; for(i = 0; i < 100; ++i) { // nothing to do } } void timing_test() { unsigned save_dccr; unsigned save_iccr; unsigned i; unsigned lsize; unsigned cache_time; unsigned none_time; unsigned start; char dummy; kprintf("About to check cache timings\n"); // heat up the cache run_loop(); // run the loop with the cache on start = timer_start(); run_loop(); cache_time = timer_diff(start); // mark data cache as write through set_spr(PPC400_SPR_DCWR, ~0); ppc_sync(); // touch enough memory to force all the data cache lines out lsize = 1 << ppcv->cache_lsize; for(i = 0; i < ppcv->dcache_lines*2; ++i) { dummy = ((volatile char *)0)[i << lsize]; } save_dccr = get_spr(PPC400_SPR_DCCR); save_iccr = get_spr(PPC400_SPR_ICCR); // invalidate data and instruction caches for(i = 0; i < ppcv->dcache_lines; ++i) { asm volatile( ".cpu 405; dccci 0,%0" :: "r" (i << lsize)); } for(i = 0; i < ppcv->icache_lines; ++i) { asm volatile( ".cpu 405; iccci 0,%0" :: "r" (i << lsize)); } ppc_sync(); // Disable data and instruction caches set_spr(PPC400_SPR_ICCR, 0); set_spr(PPC400_SPR_DCCR, 0); ppc_isync(); // run the loop again with the caches off start = timer_start(); run_loop(); none_time = timer_diff(start); // Turn the caches back on set_spr(PPC400_SPR_ICCR, save_iccr); set_spr(PPC400_SPR_DCCR, save_dccr); set_spr(PPC400_SPR_DCWR, 0); ppc_isync(); kprintf("loop time with caches on/off=%d/%d\n", cache_time, none_time); }