⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kcache2.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -