Mercurial > flash_v2
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 //-----------------------------------------------------------------------------
