📄 kcache2.c
字号:
HAL_RESTORE_INTERRUPTS(oldints);
CYG_TEST_CHECK(42 == aligned_p[0],
"memory didn't contain flushed data");
CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
"flushed beyond region");
HAL_DCACHE_ENABLE();
}
#endif
#endif
// -------------------------------------------------------------------------
// Test of data cache disable (which does NOT force contents out to RAM)
// o Requires write-back cache [so NOT invoked unconditionally]
// o Check that dirty data is not written to memory and is invalidated
// in the cache.
// o Simple invocation check of macro.
#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
static void test_ddisable(void)
{
volatile cyg_uint8* aligned_p;
cyg_int32 i;
register CYG_INTERRUPT_STATE oldints;
CYG_TEST_INFO("Data cache gross disable");
for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
m[i] = 0;
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_ENABLE();
HAL_RESTORE_INTERRUPTS(oldints);
aligned_p = (volatile cyg_uint8*)
(((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
& ~(HAL_DCACHE_LINE_SIZE-1));
HAL_DISABLE_INTERRUPTS(oldints);
aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
HAL_DCACHE_DISABLE();
HAL_RESTORE_INTERRUPTS(oldints);
CYG_TEST_CHECK(0 == aligned_p[0] &&
0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
"cache/memory contained invalidated data");
CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
"next block contained invalidated data");
HAL_DCACHE_ENABLE();
}
#endif // def HAL_DCACHE_QUERY_WRITE_MODE
// -------------------------------------------------------------------------
// Test of data cache total invalidate.
// o Requires write-back cache.
// o Check that invalidated data is not written to memory and is invalidated
// in the cache.
// o Simple invocation check of macro.
#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
#ifdef HAL_DCACHE_INVALIDATE_ALL
static void test_dinvalidate_all(void)
{
volatile cyg_uint8* aligned_p;
cyg_int32 i;
register CYG_INTERRUPT_STATE oldints;
CYG_TEST_INFO("Data cache invalidate all");
for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
m[i] = 0;
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_ENABLE();
aligned_p = (volatile cyg_uint8*)
(((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
& ~(HAL_DCACHE_LINE_SIZE-1));
aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
HAL_DCACHE_INVALIDATE_ALL();
HAL_RESTORE_INTERRUPTS(oldints);
CYG_TEST_CHECK(0 == aligned_p[0] &&
0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
"cache/memory contained invalidated data");
CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
"next block contained invalidated data");
}
#endif
#endif // def HAL_DCACHE_QUERY_WRITE_MODE
// -------------------------------------------------------------------------
// Test of data cache line invalidate.
// o Requires write-back cache.
// o Check that invalidated data is not written to memory and is invalidated
// in the cache.
// o Simple range check of macro.
#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
#ifdef HAL_DCACHE_INVALIDATE
static void test_dinvalidate(void)
{
volatile cyg_uint8* aligned_p;
cyg_int32 i;
register CYG_INTERRUPT_STATE oldints;
CYG_TEST_INFO("Data cache invalidate region");
for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
m[i] = 0;
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_ENABLE();
HAL_RESTORE_INTERRUPTS(oldints);
aligned_p = (volatile cyg_uint8*)
(((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
& ~(HAL_DCACHE_LINE_SIZE-1));
HAL_DISABLE_INTERRUPTS(oldints);
aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
HAL_DCACHE_INVALIDATE(aligned_p, HAL_DCACHE_LINE_SIZE);
HAL_RESTORE_INTERRUPTS(oldints);
CYG_TEST_CHECK(0 == aligned_p[0] &&
0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
"cache/memory contained invalidated data");
CYG_TEST_CHECK(42 == aligned_p[HAL_DCACHE_LINE_SIZE],
"invalidated beyond range");
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
CYG_TEST_CHECK(0 == aligned_p[0] &&
0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
"cache/memory contained invalidated data after SYNC/DIS");
CYG_TEST_CHECK(42 == aligned_p[HAL_DCACHE_LINE_SIZE],
"invalidated beyond range after SYNC/DIS");
HAL_DCACHE_ENABLE();
}
#endif
#endif // def HAL_DCACHE_QUERY_WRITE_MODE
// -------------------------------------------------------------------------
// Test of instruction cache locking.
// o Time difference between repeatedly executing a bunch of instructions
// with and without locking.
#ifdef HAL_ICACHE_LOCK
static void iloop(unsigned long* start, unsigned long* end, int dummy)
{
// dummy is just used to fool the compiler to not move the labels
// around. All callers should call with dummy=0;
register char c;
register CYG_INTERRUPT_STATE oldints;
if (1 == dummy) goto label_end;
label_start:
// Invalidating shouldn't affect locked lines.
HAL_DISABLE_INTERRUPTS(oldints);
HAL_ICACHE_DISABLE();
HAL_ICACHE_INVALIDATE_ALL();
HAL_ICACHE_ENABLE();
HAL_RESTORE_INTERRUPTS(oldints);
c = m[HAL_DCACHE_LINE_SIZE*0];
c = m[HAL_DCACHE_LINE_SIZE*1];
c = m[HAL_DCACHE_LINE_SIZE*2];
c = m[HAL_DCACHE_LINE_SIZE*3];
c = m[HAL_DCACHE_LINE_SIZE*4];
c = m[HAL_DCACHE_LINE_SIZE*5];
c = m[HAL_DCACHE_LINE_SIZE*6];
c = m[HAL_DCACHE_LINE_SIZE*7];
c = m[HAL_DCACHE_LINE_SIZE*8];
c = m[HAL_DCACHE_LINE_SIZE*9];
c = m[HAL_DCACHE_LINE_SIZE*10];
c = m[HAL_DCACHE_LINE_SIZE*11];
c = m[HAL_DCACHE_LINE_SIZE*12];
c = m[HAL_DCACHE_LINE_SIZE*13];
c = m[HAL_DCACHE_LINE_SIZE*14];
c = m[HAL_DCACHE_LINE_SIZE*15];
c = m[HAL_DCACHE_LINE_SIZE*16];
c = m[HAL_DCACHE_LINE_SIZE*17];
c = m[HAL_DCACHE_LINE_SIZE*18];
c = m[HAL_DCACHE_LINE_SIZE*19];
c = m[HAL_DCACHE_LINE_SIZE*20];
c = m[HAL_DCACHE_LINE_SIZE*21];
c = m[HAL_DCACHE_LINE_SIZE*22];
c = m[HAL_DCACHE_LINE_SIZE*23];
c = m[HAL_DCACHE_LINE_SIZE*24];
c = m[HAL_DCACHE_LINE_SIZE*25];
c = m[HAL_DCACHE_LINE_SIZE*26];
c = m[HAL_DCACHE_LINE_SIZE*27];
c = m[HAL_DCACHE_LINE_SIZE*28];
c = m[HAL_DCACHE_LINE_SIZE*29];
c = m[HAL_DCACHE_LINE_SIZE*30];
c = m[HAL_DCACHE_LINE_SIZE*31];
c = m[HAL_DCACHE_LINE_SIZE*32];
c = m[HAL_DCACHE_LINE_SIZE*33];
c = m[HAL_DCACHE_LINE_SIZE*34];
c = m[HAL_DCACHE_LINE_SIZE*35];
c = m[HAL_DCACHE_LINE_SIZE*36];
c = m[HAL_DCACHE_LINE_SIZE*37];
c = m[HAL_DCACHE_LINE_SIZE*38];
c = m[HAL_DCACHE_LINE_SIZE*39];
c = m[HAL_DCACHE_LINE_SIZE*40];
c = m[HAL_DCACHE_LINE_SIZE*41];
c = m[HAL_DCACHE_LINE_SIZE*42];
c = m[HAL_DCACHE_LINE_SIZE*43];
c = m[HAL_DCACHE_LINE_SIZE*44];
c = m[HAL_DCACHE_LINE_SIZE*45];
c = m[HAL_DCACHE_LINE_SIZE*46];
c = m[HAL_DCACHE_LINE_SIZE*47];
c = m[HAL_DCACHE_LINE_SIZE*48];
c = m[HAL_DCACHE_LINE_SIZE*49];
c = m[HAL_DCACHE_LINE_SIZE*50];
c = m[HAL_DCACHE_LINE_SIZE*51];
c = m[HAL_DCACHE_LINE_SIZE*52];
c = m[HAL_DCACHE_LINE_SIZE*53];
c = m[HAL_DCACHE_LINE_SIZE*54];
c = m[HAL_DCACHE_LINE_SIZE*55];
c = m[HAL_DCACHE_LINE_SIZE*56];
c = m[HAL_DCACHE_LINE_SIZE*57];
c = m[HAL_DCACHE_LINE_SIZE*58];
c = m[HAL_DCACHE_LINE_SIZE*59];
c = m[HAL_DCACHE_LINE_SIZE*60];
c = m[HAL_DCACHE_LINE_SIZE*61];
c = m[HAL_DCACHE_LINE_SIZE*62];
c = m[HAL_DCACHE_LINE_SIZE*63];
label_end:
*start = (unsigned long) &&label_start;
*end = (unsigned long) &&label_end;
if (1 == dummy) goto label_start;
}
static void time_ilock(void)
{
register cyg_ucount32 k;
cyg_tick_count_t count0, count1;
cyg_ucount32 t;
unsigned long start, end;
register cyg_ucount32 time_ilock_loops = TIME_ILOCK_LOOPS;
CYG_TEST_INFO("Instruction cache lock");
if (cyg_test_is_simulator)
time_ilock_loops = 10;
count0 = cyg_current_time();
for (k = 0; k < time_ilock_loops; k++) {
iloop(&start, &end, 0);
}
count1 = cyg_current_time();
t = count1 - count0;
diag_printf("time without lock: %d\n", t);
HAL_ICACHE_LOCK(start, end-start);
count0 = cyg_current_time();
for (k = 0; k < time_ilock_loops; k++) {
iloop(&start, &end, 0);
}
count1 = cyg_current_time();
t = count1 - count0;
diag_printf("time with lock: %d\n", t);
HAL_ICACHE_UNLOCK(start, end-start);
}
#endif // ifdef HAL_ICACHE_LOCK
// -------------------------------------------------------------------------
// Test of data cache locking.
// o Time difference between repeatedly accessing a memory region
// with and without locking.
#ifdef HAL_DCACHE_LOCK
static void dloop(void)
{
register cyg_uint32 j;
register char c;
register CYG_INTERRUPT_STATE oldints;
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_ENABLE();
HAL_RESTORE_INTERRUPTS(oldints);
for (j = 0; j < HAL_DCACHE_SETS; j++) {
c = m[HAL_DCACHE_LINE_SIZE*j];
}
}
static void time_dlock(void)
{
register cyg_ucount32 k;
cyg_tick_count_t count0, count1;
cyg_ucount32 t;
register cyg_ucount32 time_dlock_loops = TIME_DLOCK_LOOPS;
CYG_TEST_INFO("Data cache lock");
if (cyg_test_is_simulator)
time_dlock_loops = 10;
count0 = cyg_current_time();
for (k = 0; k < time_dlock_loops; k++) {
dloop();
}
count1 = cyg_current_time();
t = count1 - count0;
diag_printf("time without lock: %d\n", t);
HAL_DCACHE_LOCK(&m[0], HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE);
count0 = cyg_current_time();
for (k = 0; k < time_dlock_loops; k++) {
dloop();
}
count1 = cyg_current_time();
t = count1 - count0;
diag_printf("time with lock: %d\n", t);
HAL_DCACHE_UNLOCK(&m[0], HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE);
}
#endif // ifdef HAL_DCACHE_LOCK
// -------------------------------------------------------------------------
static void entry0( cyg_addrword_t data )
{
int numtests = 0;
#ifdef HAL_DCACHE_QUERY_WRITE_MODE
int wmode;
#endif
#ifdef HAL_DCACHE_LOCK
time_dlock(); numtests++;
#endif
#ifdef HAL_ICACHE_LOCK
time_ilock(); numtests++;
#endif
#ifdef HAL_DCACHE_LINE_SIZE // So we can find our way around memory
test_dsync(); numtests++;
#endif
#ifdef HAL_DCACHE_STORE
test_dstore(); numtests++;
#endif
#ifdef _TEST_DCACHE_OPERATION
test_dcache_operation(); numtests++;
#endif
#ifdef HAL_DCACHE_READ_HINT
test_dread_hint(); numtests++;
#endif
#ifdef HAL_DCACHE_WRITE_HINT
test_dwrite_hint(); numtests++;
#endif
#ifdef HAL_DCACHE_ZERO
test_dzero(); numtests++;
#endif
// The below tests only work on a copy-back cache.
#ifdef HAL_DCACHE_QUERY_WRITE_MODE
HAL_DCACHE_QUERY_WRITE_MODE( wmode );
if ( HAL_DCACHE_WRITEBACK_MODE == wmode ) {
test_ddisable(); numtests++;
#ifdef HAL_DCACHE_INVALIDATE
test_dinvalidate_all(); numtests++;
#endif
#ifdef HAL_DCACHE_FLUSH
test_dflush(); numtests++;
#endif
#ifdef HAL_DCACHE_INVALIDATE
test_dinvalidate(); numtests++;
#endif
}
#endif // def HAL_DCACHE_QUERY_WRITE_MODE
if ( numtests ) {
CYG_TEST_PASS_FINISH("End of test");
}
else {
CYG_TEST_NA( "No applicable cache tests" );
}
}
// -------------------------------------------------------------------------
void kcache2_main( void )
{
CYG_TEST_INIT();
cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kcache2",
(void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
cyg_thread_resume(thread[0]);
cyg_scheduler_start();
}
// -------------------------------------------------------------------------
externC void
cyg_start( void )
{
kcache2_main();
}
// -------------------------------------------------------------------------
#else // def CYGFUN_KERNEL_API_C
#define N_A_MSG "Kernel C API layer disabled"
#endif // def CYGFUN_KERNEL_API_C
#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
#define N_A_MSG "Kernel real-time clock disabled"
#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
#ifdef N_A_MSG
externC void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG );
}
#endif // N_A_MSG
// -------------------------------------------------------------------------
/* EOF kcache2.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -