changeset 2194:b1a65d90ce72

Virtual vector interface for FIS operations - from Alexander Neundorf
author gthomas
date Tue, 09 May 2006 15:51:39 +0000
parents 72aa9ecbdad9
children 5c5e93c863ac
files packages/hal/common/current/ChangeLog packages/hal/common/current/include/hal_if.h packages/hal/common/current/src/hal_if.c
diffstat 3 files changed, 126 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -3,6 +3,11 @@ 2006-05-09  Andrew Lunn  <andrew.lunn@as
 	* src/hal_if.c (cyg_hal_diag_mangler_gdb_flush): Fix compiler
 	warning about signed/unsigned.
 
+2006-04-19  Alexander Neundorf <alexander.neundorf@jenoptik.com
+
+	* include/hal_if.h, src/hal_if.c: add a VV call for modifying
+        the FIS table from eCos applications
+
 2005-06-27  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* include/hal_tables.h (CYG_HAL_TABLE_{QUALIFIED_}ENTRY): added
--- a/packages/hal/common/current/include/hal_if.h
+++ b/packages/hal/common/current/include/hal_if.h
@@ -367,8 +367,9 @@ static __inline__ _rt_                  
 #define CYGNUM_CALL_IF_FLASH_CFG_OP               20
 #define CYGNUM_CALL_IF_MONITOR_RETURN             21
 #define CYGNUM_CALL_IF_FLASH_FIS_OP               22
+#define CYGNUM_CALL_IF_FLASH_FIS_OP2              23
 
-#define CYGNUM_CALL_IF_LAST_ENTRY                 CYGNUM_CALL_IF_FLASH_FIS_OP
+#define CYGNUM_CALL_IF_LAST_ENTRY                 CYGNUM_CALL_IF_FLASH_FIS_OP2
 
 #define CYGNUM_CALL_IF_INSTALL_BPT_FN             35
 
@@ -426,6 +427,22 @@ typedef void (__call_if_install_bpt_fn_t
 typedef char *__call_if_monitor_version_t;
 typedef void (__call_if_monitor_return_t)(int status);
 typedef cyg_bool (__call_if_flash_fis_op_fn_t)(int __oper, char *__name, void *__val);
+
+//
+// This structure is used to pass parameters to/from the fis routines
+//
+struct fis_table_entry {
+   unsigned char name[16];
+   CYG_ADDRESS   flash_base;
+   CYG_ADDRESS   mem_base;
+   unsigned long size;
+   CYG_ADDRESS   entry_point;
+   unsigned long data_length;
+   unsigned long desc_cksum;
+   unsigned long file_cksum;
+};
+
+typedef int (__call_if_flash_fis_op2_fn_t)(int __oper, unsigned int index, struct fis_table_entry *__fis_entry);
 //
 // This structure is used to pass parameters to/from the fconfig routines.
 // This allows a single virtual vector interface, with widely varying functionality
@@ -690,6 +707,20 @@ static __inline__ cyg_bool
 #define CYGNUM_CALL_IF_FLASH_FIS_GET_DESC_CKSUM  (5)
 #define CYGNUM_CALL_IF_FLASH_FIS_GET_FILE_CKSUM  (6)
 
+#define CYGACC_CALL_IF_FLASH_FIS_OP2(_o_,_k_,_d_) \
+ CYGACC_CALL_VV3(__call_if_flash_fis_op2_fn_t*, CYGNUM_CALL_IF_FLASH_FIS_OP2, (_o_),(_k_),(_d_))
+__call_VV3(CYGNUM_CALL_IF_FLASH_FIS_OP2, __call_if_flash_fis_op2_fn_t, int, int, unsigned int, struct fis_table_entry *)
+#define CYGACC_CALL_IF_FLASH_FIS_OP2_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_FLASH_FIS_OP2]=(CYG_ADDRWORD)(_x_)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_VERSION     (0)
+#define CYGNUM_CALL_IF_FLASH_FIS_INIT            (1)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY_COUNT (2)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY       (3)
+#define CYGNUM_CALL_IF_FLASH_FIS_START_UPDATE    (4)
+#define CYGNUM_CALL_IF_FLASH_FIS_FINISH_UPDATE   (5)
+#define CYGNUM_CALL_IF_FLASH_FIS_MODIFY_ENTRY    (6)
+
+
 
 // These need to be kept uptodate with the (unadorned) masters
 // in RedBoot's flash_config.h:
--- a/packages/hal/common/current/src/hal_if.c
+++ b/packages/hal/common/current/src/hal_if.c
@@ -174,6 +174,94 @@ flash_fis_op( int op, char *name, void *
     CYGARC_HAL_RESTORE_GP();
     return res;
 }
+
+#include <cyg/io/flash.h>
+
+extern int __flash_init;
+extern int fisdir_size;
+extern int flash_block_size;
+extern void* fis_addr;
+#ifdef CYGOPT_REDBOOT_REDUNDANT_FIS
+extern void* redundant_fis_addr;
+#endif
+extern void* fis_work_block;
+extern int do_flash_init(void);
+extern int fis_start_update_directory(int autolock);
+extern int fis_update_directory(int autolock, int error);
+
+static __call_if_flash_fis_op2_fn_t flash_fis_op2;
+
+static int
+flash_fis_op2( int op, unsigned int index, struct fis_table_entry *entry)
+{
+   int res=0;
+   CYGARC_HAL_SAVE_GP();
+   switch ( op ) {
+      case CYGNUM_CALL_IF_FLASH_FIS_GET_VERSION:
+         res=CYG_REDBOOT_FIS_VERSION;
+         break;
+      case CYGNUM_CALL_IF_FLASH_FIS_INIT:
+         __flash_init=0;  //force reinitialization
+         res=do_flash_init();
+         break;
+      case CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY_COUNT:
+         res=fisdir_size / sizeof(struct fis_image_desc);
+         break;
+      case CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY:
+         {
+            struct fis_image_desc* img = (struct fis_image_desc *)fis_work_block;
+            CYG_ASSERT(entry!=0, "fis_table_entry == 0 !");
+            memcpy(entry->name, img[index].u.name, 16);
+            entry->flash_base=img[index].flash_base;
+            entry->mem_base=img[index].mem_base;
+            entry->size=img[index].size;
+            entry->entry_point=img[index].entry_point;
+            entry->data_length=img[index].data_length;
+            entry->desc_cksum=img[index].desc_cksum;
+            entry->file_cksum=img[index].file_cksum;
+            res=0;
+         }
+         break;
+      case CYGNUM_CALL_IF_FLASH_FIS_START_UPDATE:
+         fis_start_update_directory(1);
+         break;
+      case CYGNUM_CALL_IF_FLASH_FIS_FINISH_UPDATE:
+         fis_update_directory(1, index);
+         break;
+      case CYGNUM_CALL_IF_FLASH_FIS_MODIFY_ENTRY:
+         {
+            res=0;
+            if (entry->name[0]!=0xff)
+            {
+               if ((entry->size==0)
+                   || ((entry->size % flash_block_size) !=0)
+                   || (flash_verify_addr((void*)entry->flash_base)!=0)
+                   || (flash_verify_addr((void*)(entry->flash_base+entry->size-1))!=0)
+                   || (entry->size < entry->data_length))
+                  res=-1;
+            }
+
+            if (res==0)
+            {
+               struct fis_image_desc* img = (struct fis_image_desc *)fis_work_block;
+               memcpy(img[index].u.name, entry->name, 16);
+               img[index].flash_base=entry->flash_base;
+               img[index].mem_base=entry->mem_base;
+               img[index].size=entry->size;
+               img[index].entry_point=entry->entry_point;
+               img[index].data_length=entry->data_length;
+               img[index].desc_cksum=entry->desc_cksum;
+               img[index].file_cksum=entry->file_cksum;
+            }
+         }
+         break;
+      default:
+         break;
+   }
+   CYGARC_HAL_RESTORE_GP();
+   return res;
+}
+
 #endif
 
 //----------------------------
@@ -978,6 +1066,7 @@ hal_if_init(void)
 
 #ifdef CYGOPT_REDBOOT_FIS
     CYGACC_CALL_IF_FLASH_FIS_OP_SET(flash_fis_op);
+    CYGACC_CALL_IF_FLASH_FIS_OP2_SET(flash_fis_op2);
 #endif
 
     // Data entries not currently supported in eCos