diff packages/hal/mips/arch/current/include/hal_cache.h @ 6:d376b777e2ce ecos-sw-1999-05-14

Merge from eCos master repository on 1999-05-14-19:27:43-BST
author jlarmour
date Fri, 14 May 1999 12:20:00 +0000
parents 443894e2e912
children d3fbcdfa1b2f
line wrap: on
line diff
--- a/packages/hal/mips/arch/current/include/hal_cache.h
+++ b/packages/hal/mips/arch/current/include/hal_cache.h
@@ -50,13 +50,19 @@
 #include <pkgconf/hal.h>
 #include <cyg/infra/cyg_type.h>
 
+#include <cyg/hal/var_cache.h>
+
 //=============================================================================
-// MIPS simulator
-
-#ifdef CYG_HAL_MIPS_SIM
+// Default Implementation. This uses the standard MIPS CP0 registers and
+// cache instructions. Note that not all variants will have all of the
+// functionality defined here. 
 
 //-----------------------------------------------------------------------------
-// Cache dimensions
+// Cache dimensions.
+// These really should be defined in var_cache.h. If they are not, then provide
+// a set of numbers that are typical of many variants.
+
+#ifndef HAL_DCACHE_SIZE
 
 // Data cache
 #define HAL_DCACHE_SIZE                 4096    // Size of data cache in bytes
@@ -71,20 +77,46 @@
 #define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
 #define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
 
+#endif
+
 //-----------------------------------------------------------------------------
 // Global control of data cache
 
 // Enable the data cache
+// There is no default mechanism for enabling or disabling the caches.
+#ifndef HAL_DCACHE_ENABLE_DEFINED
 #define HAL_DCACHE_ENABLE()
+#endif
 
 // Disable the data cache
+#ifndef HAL_DCACHE_DISABLE_DEFINED
 #define HAL_DCACHE_DISABLE()
+#endif
 
 // Invalidate the entire cache
-#define HAL_DCACHE_INVALIDATE_ALL()
+// We simply use HAL_DCACHE_SYNC() to do this. For writeback caches this
+// is not quite what we want, but there is no index-invalidate operation
+// available.
+#ifndef HAL_DCACHE_INVALIDATE_ALL_DEFINED
+#define HAL_DCACHE_INVALIDATE_ALL() HAL_DCACHE_SYNC()
+#endif
 
 // Synchronize the contents of the cache with memory.
-#define HAL_DCACHE_SYNC()
+// This uses the index-writeback-invalidate operation.
+#ifndef HAL_DCACHE_SYNC_DEFINED
+#define HAL_DCACHE_SYNC()                                               \
+{                                                                       \
+    register CYG_ADDRESS _baddr_ = 0x80000000;                          \
+    register CYG_ADDRESS _addr_ = 0x80000000;                           \
+    register CYG_WORD _size_ = HAL_DCACHE_SIZE;                         \
+    HAL_DCACHE_DISABLE();                                               \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
+    {                                                                   \
+        asm volatile ("cache 0x01,0(%0)" : : "r"(_addr_) );             \
+    }                                                                   \
+    HAL_DCACHE_ENABLE();                                                \
+}
+#endif
 
 // Set the data cache refill burst size
 //#define HAL_DCACHE_BURST_SIZE(_size_)
@@ -97,13 +129,34 @@
 
 // Load the contents of the given address range into the data cache
 // and then lock the cache so that it stays there.
-//#define HAL_DCACHE_LOCK(_base_, _size_)
+// This uses the fetch-and-lock cache operation.
+#ifndef HAL_DCACHE_LOCK_DEFINED
+#define HAL_DCACHE_LOCK(_base_, _asize_)                                \
+CYG_MACRO_START                                                         \
+    register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_);               \
+    register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
+    register CYG_WORD _size_ = (_asize_);                               \
+    HAL_DCACHE_DISABLE();                                               \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
+    {                                                                   \
+        asm volatile ("cache 0x1d,0(%0)" : : "r"(_addr_) );             \
+    }                                                                   \
+    HAL_DCACHE_ENABLE();                                                \
+CYG_MACRO_END
+#endif
 
-// Undo a previous lock operation
-//#define HAL_DCACHE_UNLOCK(_base_, _size_)
+// Undo a previous lock operation.
+// Do this by flushing the cache, which is defined to clear the lock bit.
+#ifndef HAL_DCACHE_UNLOCK_DEFINED
+#define HAL_DCACHE_UNLOCK(_base_, _size_) \
+        HAL_DCACHE_FLUSH( _base_, _size_ )
+#endif
 
 // Unlock entire cache
-//#define HAL_DCACHE_UNLOCK_ALL()
+#ifndef HAL_DCACHE_UNLOCK_ALL_DEFINED
+#define HAL_DCACHE_UNLOCK_ALL() \
+        HAL_DCACHE_INVALIDATE_ALL()
+#endif
 
 //-----------------------------------------------------------------------------
 // Data cache line control
@@ -114,13 +167,55 @@
 
 // Write dirty cache lines to memory and invalidate the cache entries
 // for the given address range.
-//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+// This uses the hit-writeback-invalidate cache operation.
+#ifndef HAL_DCACHE_FLUSH_DEFINED
+#define HAL_DCACHE_FLUSH( _base_ , _asize_ )                            \
+{                                                                       \
+    register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_);               \
+    register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
+    register CYG_WORD _size_ = (_asize_);                               \
+    HAL_DCACHE_DISABLE();                                               \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
+    {                                                                   \
+        asm volatile ("cache 0x15,0(%0)" : : "r"(_addr_) );             \
+    }                                                                   \
+    HAL_DCACHE_ENABLE();                                                \
+}
+#endif
 
 // Invalidate cache lines in the given range without writing to memory.
-//#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
+// This uses the hit-invalidate cache operation.
+#ifndef HAL_DCACHE_INVALIDATE_DEFINED
+#define HAL_DCACHE_INVALIDATE( _base_ , _asize_ )                       \
+{                                                                       \
+    register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_);               \
+    register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
+    register CYG_WORD _size_ = (_asize_);                               \
+    HAL_DCACHE_DISABLE();                                               \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
+    {                                                                   \
+        asm volatile ("cache 0x11,0(%0)" : : "r"(_addr_) );             \
+    }                                                                   \
+    HAL_DCACHE_ENABLE();                                                \
+}
+#endif
 
 // Write dirty cache lines to memory for the given address range.
-//#define HAL_DCACHE_STORE( _base_ , _size_ )
+// This uses the hit-writeback cache operation.
+#ifndef HAL_DCACHE_STORE_DEFINED
+#define HAL_DCACHE_STORE( _base_ , _asize_ )                            \
+{                                                                       \
+    register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_);               \
+    register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
+    register CYG_WORD _size_ = (_asize_);                               \
+    HAL_DCACHE_DISABLE();                                               \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
+    {                                                                   \
+        asm volatile ("cache 0x19,0(%0)" : : "r"(_addr_) );             \
+    }                                                                   \
+    HAL_DCACHE_ENABLE();                                                \
+}
+#endif
 
 // Preread the given range into the cache with the intention of reading
 // from it later.
@@ -137,26 +232,65 @@
 // Global control of Instruction cache
 
 // Enable the instruction cache
+// There is no default mechanism for enabling or disabling the caches.
+#ifndef HAL_ICACHE_ENABLE_DEFINED
 #define HAL_ICACHE_ENABLE()
+#endif
 
 // Disable the instruction cache
+#ifndef HAL_ICACHE_DISABLE_DEFINED
 #define HAL_ICACHE_DISABLE()
+#endif
 
 // Invalidate the entire cache
-#define HAL_ICACHE_INVALIDATE_ALL()
+// This uses the index-invalidate cache operation.
+#ifndef HAL_ICACHE_INVALIDATE_ALL_DEFINED
+#define HAL_ICACHE_INVALIDATE_ALL()                                             \
+{                                                                               \
+    register CYG_ADDRESS _baddr_ = 0x80000000;                                  \
+    register CYG_ADDRESS _addr_ = 0x80000000;                                   \
+    HAL_ICACHE_DISABLE();                                                       \
+    for( ; _addr_ < _baddr_+HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE )   \
+    {                                                                           \
+        asm volatile ("cache 0x00,0(%0)" : : "r"(_addr_) );                     \
+    }                                                                           \
+    HAL_ICACHE_ENABLE();                                                        \
+}
+#endif
 
 // Synchronize the contents of the cache with memory.
-#define HAL_ICACHE_SYNC()
+// Simply force the cache to reload.
+#ifndef HAL_ICACHE_SYNC_DEFINED
+#define HAL_ICACHE_SYNC() HAL_ICACHE_INVALIDATE_ALL()
+#endif
 
 // Set the instruction cache refill burst size
 //#define HAL_ICACHE_BURST_SIZE(_size_)
 
 // Load the contents of the given address range into the instruction cache
 // and then lock the cache so that it stays there.
-//#define HAL_ICACHE_LOCK(_base_, _size_)
+// This uses the fetch-and-lock cache operation.
+#ifndef HAL_ICACHE_LOCK_DEFINED
+#define HAL_ICACHE_LOCK(_base_, _asize_)                                \
+CYG_MACRO_START                                                         \
+    register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_);               \
+    register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
+    register CYG_WORD _size_ = (_asize_);                               \
+    HAL_DCACHE_DISABLE();                                               \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
+    {                                                                   \
+        asm volatile ("cache 0x1c,0(%0)" : : "r"(_addr_) );             \
+    }                                                                   \
+    HAL_DCACHE_ENABLE();                                                \
+CYG_MACRO_END
+#endif
 
-// Undo a previous lock operation
-//#define HAL_ICACHE_UNLOCK(_base_, _size_)
+// Undo a previous lock operation.
+// Do this by invalidating the cache, which is defined to clear the lock bit.
+#ifndef HAL_ICACHE_UNLOCK_DEFINED
+#define HAL_ICACHE_UNLOCK(_base_, _size_) \
+        HAL_ICACHE_INVALIDATE( _base_, _size_ )
+#endif
 
 // Unlock entire cache
 //#define HAL_ICACHE_UNLOCK_ALL()
@@ -165,252 +299,20 @@
 // Instruction cache line control
 
 // Invalidate cache lines in the given range without writing to memory.
-//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
-
-#endif
-
-
-//=============================================================================
-// Toshiba TX3904
-
-#ifdef CYG_HAL_MIPS_TX3904
-
-//-----------------------------------------------------------------------------
-// Cache dimensions
-
-// Data cache
-#define HAL_DCACHE_SIZE                 1024    // Size of data cache in bytes
-#define HAL_DCACHE_LINE_SIZE            4       // Size of a data cache line
-#define HAL_DCACHE_WAYS                 2       // Associativity of the cache
-
-// Instruction cache
-#define HAL_ICACHE_SIZE                 4096    // Size of cache in bytes
-#define HAL_ICACHE_LINE_SIZE            16      // Size of a cache line
-#define HAL_ICACHE_WAYS                 1       // Associativity of the cache
-
-#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
-#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
-
-//-----------------------------------------------------------------------------
-// Global control of data cache
-
-// Enable the data cache
-#define HAL_DCACHE_ENABLE()                     \
-{                                               \
-    asm volatile ("mfc0 $2,$3;"                 \
-                  "ori  $2,$2,0x0010;"          \
-                  "mtc0 $2,$3;"                 \
-                  :                             \
-                  :                             \
-                  : "$2"                        \
-                 );                             \
-                                                \
-}
-
-// Disable the data cache
-#define HAL_DCACHE_DISABLE()                    \
-{                                               \
-    asm volatile ("mfc0 $2,$3;"                 \
-                  "la   $3,0xFFFFFFEF;"         \
-                  "and  $2,$2,$3;"              \
-                  "mtc0 $2,$3;"                 \
-                  :                             \
-                  :                             \
-                  : "$2", "$3"                  \
-                 );                             \
-                                                \
-}
-
-// Invalidate the entire cache
-// The TX39 only has hit-invalidate on the DCACHE, not
-// index-invalidate, so we cannot just empty the cache out without
-// knowing what is in it. This is annoying. So, the best we can do is
-// fill the cache with data that is unlikely to be there
-// otherwise. Hence we read bytes from the ROM space since this is
-// most likely to be code, and will not get out of sync even if it is not.
-#define HAL_DCACHE_INVALIDATE_ALL()                                             \
-{                                                                               \
-    CYG_BYTE volatile *addr = (CYG_BYTE *)(0x9fc00000);                         \
-    CYG_BYTE volatile tmp = 0;                                                  \
-    int i;                                                                      \
-    for( i = 0; i < (HAL_DCACHE_SIZE*2); i += HAL_DCACHE_LINE_SIZE )            \
-    {                                                                           \
-        tmp = addr[i];                                                          \
-    }                                                                           \
-}
-
-// Synchronize the contents of the cache with memory.
-#define HAL_DCACHE_SYNC() HAL_DCACHE_INVALIDATE_ALL()
-
-// Set the data cache refill burst size
-//#define HAL_DCACHE_BURST_SIZE(_size_)
-
-// Set the data cache write mode
-//#define HAL_DCACHE_WRITE_MODE( _mode_ )
-
-//#define HAL_DCACHE_WRITETHRU_MODE       0
-//#define HAL_DCACHE_WRITEBACK_MODE       1
-
-// Load the contents of the given address range into the data cache
-// and then lock the cache so that it stays there.
-#define HAL_DCACHE_LOCK(_base_, _size_)         \
-{                                               \
-    asm volatile ("mfc0 $2,$7;"                 \
-                  "ori  $2,$2,0x0100;"          \
-                  "mtc0 $2,$7;"                 \
-                  :                             \
-                  :                             \
-                  : "$2"                        \
-                 );                             \
-}
-
-// Undo a previous lock operation
-#define HAL_DCACHE_UNLOCK(_base_, _size_)       \
-{                                               \
-    asm volatile ("mfc0 $2,$7;"                 \
-                  "la   $3,0xFFFFFEFF;"         \
-                  "and  $2,$2,$3;"              \
-                  "mtc0 $2,$7;"                 \
-                  :                             \
-                  :                             \
-                  : "$2", "$3"                  \
-                 );                             \
-}
-
-// Unlock entire cache
-#define HAL_DCACHE_UNLOCK_ALL()
-
-//-----------------------------------------------------------------------------
-// Data cache line control
-
-// Allocate cache lines for the given address range without reading its
-// contents from memory.
-//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
-
-// Write dirty cache lines to memory and invalidate the cache entries
-// for the given address range.
-//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
-
-// Invalidate cache lines in the given range without writing to memory.
-#define HAL_DCACHE_INVALIDATE( _base_ , _asize_ )                       \
+// This uses the hit-invalidate cache operation.
+#ifndef HAL_ICACHE_INVALIDATE_DEFINED
+#define HAL_ICACHE_INVALIDATE( _base_ , _asize_ )                       \
 {                                                                       \
+    register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_);               \
     register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
     register CYG_WORD _size_ = (_asize_);                               \
     HAL_DCACHE_DISABLE();                                               \
-    for( ; _addr_ <= _addr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )    \
+    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
     {                                                                   \
-        asm volatile ("cache 17,0(%0)" : : "r"(_addr_) );               \
+        asm volatile ("cache 0x10,0(%0)" : : "r"(_addr_) );             \
     }                                                                   \
     HAL_DCACHE_ENABLE();                                                \
 }
-
-// Write dirty cache lines to memory for the given address range.
-//#define HAL_DCACHE_STORE( _base_ , _size_ )
-
-// Preread the given range into the cache with the intention of reading
-// from it later.
-//#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
-
-// Preread the given range into the cache with the intention of writing
-// to it later.
-//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
-
-// Allocate and zero the cache lines associated with the given range.
-//#define HAL_DCACHE_ZERO( _base_ , _size_ )
-
-//-----------------------------------------------------------------------------
-// Global control of Instruction cache
-
-// Enable the instruction cache
-#define HAL_ICACHE_ENABLE()                     \
-{                                               \
-    asm volatile ("mfc0 $2,$3;"                 \
-                  "ori  $2,$2,0x0020;"          \
-                  "mtc0 $2,$3;"                 \
-                  :                             \
-                  :                             \
-                  : "$2"                        \
-                 );                             \
-                                                \
-}
-
-// Disable the instruction cache
-#define HAL_ICACHE_DISABLE()                    \
-{                                               \
-    asm volatile ("mfc0 $2,$3;"                 \
-                  "la   $3,0xFFFFFFDF;"         \
-                  "and  $2,$2,$3;"              \
-                  "mtc0 $2,$3;"                 \
-                  :                             \
-                  :                             \
-                  : "$2", "$3"                  \
-                 );                             \
-                                                \
-}
-
-// Invalidate the entire cache
-#define HAL_ICACHE_INVALIDATE_ALL()                                             \
-{                                                                               \
-    register CYG_ADDRESS _addr_;                                                \
-    HAL_ICACHE_DISABLE();                                                       \
-    for( _addr_ = 0; _addr_ < HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \
-    {                                                                           \
-        asm volatile ("cache 0,0(%0)" : : "r"(_addr_) );                        \
-    }                                                                           \
-    HAL_ICACHE_ENABLE();                                                        \
-}
-
-// Synchronize the contents of the cache with memory.
-#define HAL_ICACHE_SYNC() HAL_ICACHE_INVALIDATE_ALL()
-
-// Set the instruction cache refill burst size
-//#define HAL_ICACHE_BURST_SIZE(_size_)
-
-// Load the contents of the given address range into the instruction cache
-// and then lock the cache so that it stays there.
-#define HAL_ICACHE_LOCK(_base_, _size_)         \
-{                                               \
-    asm volatile ("mfc0 $2,$7;"                 \
-                  "ori  $2,$2,0x0200;"          \
-                  "mtc0 $2,$7;"                 \
-                  :                             \
-                  :                             \
-                  : "$2"                        \
-                 );                             \
-}
-
-// Undo a previous lock operation
-#define HAL_ICACHE_UNLOCK(_base_, _size_)       \
-{                                               \
-    asm volatile ("mfc0 $2,$7;"                 \
-                  "la   $3,0xFFFFFDFF;"         \
-                  "and  $2,$2,$3;"              \
-                  "mtc0 $2,$7;"                 \
-                  :                             \
-                  :                             \
-                  : "$2", "$3"                  \
-                 );                             \
-}
-
-// Unlock entire cache
-#define HAL_ICACHE_UNLOCK_ALL()
-
-//-----------------------------------------------------------------------------
-// Instruction cache line control
-
-// Invalidate cache lines in the given range without writing to memory.
-#define HAL_ICACHE_INVALIDATE( _base_ , _asize_ )                       \
-{                                                                       \
-    register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
-    register CYG_WORD _size_ = (_asize_);                               \
-    HAL_ICACHE_DISABLE();                                               \
-    for( ; _addr_ <= _addr_+_size_; _addr_ += HAL_ICACHE_LINE_SIZE )    \
-    {                                                                   \
-        asm volatile ("cache 0,0(%0)" : : "r"(_addr_) );                \
-    }                                                                   \
-    HAL_ICACHE_ENABLE();                                                \
-}
-
 #endif
 
 //-----------------------------------------------------------------------------