diff packages/io/flash/current/include/flash.h @ 141:450e4e1f1e80 ecos-sw-2000-11-27

Merge from eCos master repository on 2000-11-27-23:09:27-GMT
author jlarmour
date Tue, 28 Nov 2000 00:03:34 +0000
parents a9ac27ec7abc
children 6b5f480c6929
line wrap: on
line diff
--- a/packages/io/flash/current/include/flash.h
+++ b/packages/io/flash/current/include/flash.h
@@ -45,21 +45,24 @@
 #define _IO_FLASH_H_
 
 #include <pkgconf/io_flash.h>
+#include <cyg/hal/hal_cache.h>
 
 #define FLASH_MIN_WORKSPACE 0x10000  // Space used by FLASH code
 
-extern int flash_init(void *work_space, int work_space_length);
-extern int flash_erase(void *base, int len, void **err_address);
-extern int flash_program(void *flash_base, void *ram_base, int len, void **err_address);
+externC int flash_init(void *work_space, int work_space_length);
+externC int flash_erase(void *base, int len, void **err_address);
+externC int flash_program(void *flash_base, void *ram_base, int len, void **err_address);
 #if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING // This is an *interface*
-extern int flash_lock(void *base, int len, void **err_address);
-extern int flash_unlock(void *base, int len, void **err_address);
+externC int flash_lock(void *base, int len, void **err_address);
+externC int flash_unlock(void *base, int len, void **err_address);
 #endif
-extern int flash_verify_addr(void *base);
-extern int flash_get_limits(void *base, void **start, void **end);
-extern int flash_get_block_info(int *block_size, int *blocks);
-extern bool flash_code_overlaps(void *start, void *end);
-extern char *flash_errmsg(int err);
+externC int flash_verify_addr(void *base);
+externC int flash_get_limits(void *base, void **start, void **end);
+externC int flash_get_block_info(int *block_size, int *blocks);
+externC bool flash_code_overlaps(void *start, void *end);
+externC char *flash_errmsg(int err);
+
+externC int printf(char* fmt, ...);
 
 #define FLASH_ERR_OK              0x00  // No error - operation complete
 #define FLASH_ERR_INVALID         0x01  // Invalid FLASH address
@@ -89,6 +92,93 @@ extern struct flash_info flash_info;
 extern int  flash_hwr_init(void);
 extern int  flash_hwr_map_error(int err);
 
-#endif
+
+//---------------------------------------------------------------------------
+//Execution of relocated code must be done inside a
+//HAL_FLASH_CACHES_OFF/HAL_FLASH_CACHES_ON region - disabling the
+//cache on unified cache systems is necessary to prevent burst access
+//to the flash area being programmed. With Harvard style caches, only
+//the data cache needs to be disabled, but the instruction cache must
+//still be invalidated to ensure the relocated code is properly
+//fetched from memory.
+
+// Targets may provide alternative implementations for these macros in
+// the hal_cache.h (or var/plf) files.
+
+// The first part below is the optimal implementation, but it does not
+// always work. The second part is a more safe implementation that has
+// been tested to work on some targets - it may not be suitable for
+// targets that would do burst access to the flash (data cache needs
+// disabling as well).
+
+// NOTE: Do _not_ change any of the below macros without checking that
+//       the changed code still works on _all_ platforms that rely on these
+//       macros. There is no such thing as logical and correct when dealing
+//       with different cache and IO models, so _do not_ mess with this code
+//       unless you test it properly afterwards.
+
+#ifndef HAL_FLASH_CACHES_OFF
+
+#ifdef HAL_FLASH_CACHES_WANT_OPTIMAL // Optimal implementation
+
+#ifdef HAL_CACHE_UNIFIED
+
+// Note: the ucache code has not been tested yet on any target.
+#define HAL_FLASH_CACHES_OFF(_d_, _i_)          \
+    CYG_MACRO_START                             \
+    _i_ = 0; /* avoids warning */               \
+    HAL_UCACHE_IS_ENABLED(_d_);                 \
+    HAL_UCACHE_SYNC();                          \
+    HAL_UCACHE_INVALIDATE_ALL();                \
+    HAL_UCACHE_DISABLE();                       \
+    CYG_MACRO_END
+
+#define HAL_FLASH_CACHES_ON(_d_, _i_)           \
+    CYG_MACRO_START                             \
+    if (_d_) HAL_UCACHE_ENABLE();               \
+    CYG_MACRO_END
+
+#else  // HAL_CACHE_UNIFIED
+
+#define HAL_FLASH_CACHES_OFF(_d_, _i_)          \
+    CYG_MACRO_START                             \
+    _i_ = 0; /* avoids warning */               \
+    HAL_DCACHE_IS_ENABLED(_d_);                 \
+    HAL_DCACHE_SYNC();                          \
+    HAL_DCACHE_INVALIDATE_ALL();                \
+    HAL_DCACHE_DISABLE();                       \
+    HAL_ICACHE_INVALIDATE_ALL();                \
+    CYG_MACRO_END
+
+#define HAL_FLASH_CACHES_ON(_d_, _i_)           \
+    CYG_MACRO_START                             \
+    if (_d_) HAL_DCACHE_ENABLE();               \
+    CYG_MACRO_END
+
+#endif // HAL_CACHE_UNIFIED
+
+#else  // HAL_FLASH_CACHES_WANT_OPTIMAL
+
+// Note: This implementation is broken as it will always enable the i-cache
+//       even if it was not enabled before. It also doesn't work if the
+//       target uses burst access to flash since the d-cache is left enabled.
+//       However, this does not mean you can change this code! Leave it as
+//       is - if you want a different implementation, provide it in the
+//       arch/var/platform cache header file.
+
+#define HAL_FLASH_CACHES_OFF(_d_, _i_)          \
+    _d_ = 0; /* avoids warning */               \
+    _i_ = 0; /* avoids warning */               \
+    HAL_DCACHE_SYNC();                          \
+    HAL_ICACHE_DISABLE();
+
+#define HAL_FLASH_CACHES_ON(_d_, _i_)           \
+    HAL_ICACHE_ENABLE();
+
+#endif  // HAL_FLASH_CACHES_WANT_OPTIMAL
+
+#endif  // HAL_FLASH_CACHES_OFF
+
+#endif  // _FLASH_PRIVATE_
 
 #endif  // _IO_FLASH_H_