📄 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_ALLstatic 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_INVALIDATEstatic 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_LOCKstatic 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_LOCKstatic 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 voidcyg_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_MSGexternC voidcyg_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 + -