diff packages/kernel/current/tests/kcache2.c @ 143:6b5f480c6929 ecos-sw-2000-12-08

Merge from eCos master repository on 2000-12-08-02:09:36-GMT
author jlarmour
date Fri, 08 Dec 2000 03:30:06 +0000
parents bf00f99aec69
children 678094f34118
line wrap: on
line diff
--- a/packages/kernel/current/tests/kcache2.c
+++ b/packages/kernel/current/tests/kcache2.c
@@ -234,8 +234,10 @@ static void test_dread_hint(void)
 #endif
 
 // -------------------------------------------------------------------------
-// Test of data cache line store.
-// Just check that the macro compiles.
+// Test of data cache line store
+//  o No semantic requirement.
+//  o Check that flushed data is written to memory.
+//  o Simple invocation check of macro.
 #ifdef HAL_DCACHE_STORE
 static void test_dstore(void)
 {
@@ -260,13 +262,86 @@ static void test_dstore(void)
         (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
          & ~(HAL_DCACHE_LINE_SIZE-1));
 
-    aligned_p[0] = 42;
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
 
     HAL_DCACHE_STORE(aligned_p, HAL_DCACHE_LINE_SIZE);
+
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data");
+
+    HAL_DCACHE_INVALIDATE_ALL(); // Discard...
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data after invalidate all");
 }
 #endif
 
 // -------------------------------------------------------------------------
+// Test of data cache total flush (sync).
+//  o No semantic requirement.
+//  o Check that flushed data is written to memory.
+//  o Simple invocation check of macro.
+#ifdef HAL_DCACHE_LINE_SIZE // So we can find our way around memory
+static void test_dsync(void)
+{
+    volatile cyg_uint8* aligned_p;
+    cyg_int32 i;
+    register CYG_INTERRUPT_STATE oldints;
+
+    CYG_TEST_INFO("Data cache sync 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();
+    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] = 42 + aligned_p[1]; // Load causes cache to be used!
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 43 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+    HAL_DCACHE_SYNC();
+
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data");
+    CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
+                   "memory didn't contain flushed data next block");
+
+    HAL_DCACHE_INVALIDATE_ALL();
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data after invalidate");
+    CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
+                   "memory didn't contain flushed data next block after invalidate");
+
+    HAL_DCACHE_DISABLE();
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data after disable");
+    CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
+                   "memory didn't contain flushed data next block after disable");
+
+    HAL_DCACHE_ENABLE();
+}
+#endif // HAL_DCACHE_LINE_SIZE
+
+// -------------------------------------------------------------------------
 // Test of data cache line flush.
 //  o Requires write-back cache.
 //  o Check that flushed data is written to memory.
@@ -295,29 +370,135 @@ static void test_dflush(void)
         (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
          & ~(HAL_DCACHE_LINE_SIZE-1));
 
-    aligned_p[0] = 42;
-    aligned_p[HAL_DCACHE_LINE_SIZE] = 43;
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 43 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
 
     HAL_DCACHE_FLUSH(aligned_p, HAL_DCACHE_LINE_SIZE);
 
     HAL_DCACHE_DISABLE();
 
+    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
 
 // -------------------------------------------------------------------------
+// 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();
+    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_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)
 {
@@ -342,20 +523,36 @@ static void test_dinvalidate(void)
         (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
          & ~(HAL_DCACHE_LINE_SIZE-1));
 
-    aligned_p[0] = 43;
+    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] = 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.
@@ -541,26 +738,30 @@ static void time_dlock(void)
 // -------------------------------------------------------------------------
 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();
+    time_dlock(); numtests++;
 #endif
 #ifdef HAL_ICACHE_LOCK
-    time_ilock();
+    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();
+    test_dstore(); numtests++;
 #endif
 #ifdef HAL_DCACHE_READ_HINT
-    test_dread_hint();
+    test_dread_hint(); numtests++;
 #endif
 #ifdef HAL_DCACHE_WRITE_HINT
-    test_dwrite_hint();
+    test_dwrite_hint(); numtests++;
 #endif
 #ifdef HAL_DCACHE_ZERO
-    test_dzero();
+    test_dzero(); numtests++;
 #endif
 
     // The below tests only work on a copy-back cache.
@@ -568,16 +769,24 @@ static void entry0( cyg_addrword_t data 
     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();
+        test_dflush(); numtests++;
 #endif
 #ifdef HAL_DCACHE_INVALIDATE
-        test_dinvalidate();
+        test_dinvalidate(); numtests++;
 #endif
     }
 #endif // def HAL_DCACHE_QUERY_WRITE_MODE
-
-    CYG_TEST_PASS_FINISH("End of test");
+    if ( numtests ) {
+        CYG_TEST_PASS_FINISH("End of test");
+    }
+    else {
+        CYG_TEST_NA( "No applicable cache tests" );
+    }
 }
 
 // -------------------------------------------------------------------------