Mercurial > nand-ecoscentric
diff packages/redboot/current/src/flash.c @ 1740:0031b615f51c
Add support for reverse endianess of fis and config data
| author | msalter |
|---|---|
| date | Wed, 01 Sep 2004 21:21:30 +0000 |
| parents | 9091309eb665 |
| children | ecd76f498508 |
line wrap: on
line diff
--- a/packages/redboot/current/src/flash.c +++ b/packages/redboot/current/src/flash.c @@ -8,7 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. // Copyright (C) 2003, 2004 Gary Thomas // // eCos is free software; you can redistribute it and/or modify it under @@ -61,6 +61,7 @@ #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG // Note horrid intertwining of functions, to save precious FLASH +extern void conf_endian_fixup(void *p); #endif // Round a quantity up @@ -191,14 +192,45 @@ static void } #ifdef CYGOPT_REDBOOT_FIS + +// fis_endian_fixup() is used to swap endianess if required. +// +static inline void fis_endian_fixup(void *addr) +{ +#ifdef REDBOOT_FLASH_REVERSE_BYTEORDER + struct fis_image_desc *p = addr; + int cnt = fisdir_size / sizeof(struct fis_image_desc); + + while (cnt-- > 0) { + p->flash_base = CYG_SWAP32(p->flash_base); + p->mem_base = CYG_SWAP32(p->mem_base); + p->size = CYG_SWAP32(p->size); + p->entry_point = CYG_SWAP32(p->entry_point); + p->data_length = CYG_SWAP32(p->data_length); + p->desc_cksum = CYG_SWAP32(p->desc_cksum); + p->file_cksum = CYG_SWAP32(p->file_cksum); + p++; + } +#endif +} + +void +fis_read_directory(void) +{ + void *err_addr; + + FLASH_READ(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_endian_fixup(fis_work_block); +} + struct fis_image_desc * fis_lookup(char *name, int *num) { int i; struct fis_image_desc *img; - void *err_addr; - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_read_directory(); + img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && @@ -216,8 +248,10 @@ fis_update_directory(void) int stat; void *err_addr; + fis_endian_fixup(fis_work_block); #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG memcpy((char *)fis_work_block+fisdir_size, config, cfg_size); + conf_endian_fixup((char *)fis_work_block+fisdir_size); #endif #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Ensure [quietly] that the directory is unlocked before trying to update @@ -226,8 +260,8 @@ fis_update_directory(void) if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) { diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); } else { - if ((stat = flash_program(fis_addr, fis_work_block, flash_block_size, - (void **)&err_addr)) != 0) { + if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block, + flash_block_size, (void **)&err_addr)) != 0) { diag_printf("Error writing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -236,6 +270,7 @@ fis_update_directory(void) // Ensure [quietly] that the directory is locked after the update flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); #endif + fis_endian_fixup(fis_work_block); } static void @@ -450,7 +485,6 @@ fis_list(int argc, char *argv[]) bool show_cksums = false; bool show_datalen = false; struct option_info opts[2]; - void *err_addr; unsigned long last_addr, lowest_addr; bool image_found; @@ -473,7 +507,8 @@ fis_list(int argc, char *argv[]) if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { return; } - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_read_directory(); + // Let diag_printf do the formatting in both cases, rather than counting // cols by hand.... diag_printf("%-16s %-10s %-10s %-10s %-s\n", @@ -523,7 +558,6 @@ static int find_free(struct free_chunk *chunks) { CYG_ADDRESS *fis_ptr, *fis_end; - void *err_addr; struct fis_image_desc *img; int i, idx; int num_chunks = 1; @@ -535,7 +569,7 @@ find_free(struct free_chunk *chunks) fis_end = (CYG_ADDRESS *)flash_end; chunks[num_chunks-1].start = (CYG_ADDRESS)fis_ptr; chunks[num_chunks-1].end = (CYG_ADDRESS)fis_end; - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_read_directory(); img = (struct fis_image_desc *) fis_work_block; for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { if (img->name[0] != (unsigned char)0xFF) { @@ -728,7 +762,7 @@ fis_create(int argc, char *argv[]) return; } - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_read_directory(); defaults_assumed = false; if (name) { // Search existing files to acquire defaults for params not specified: @@ -888,7 +922,7 @@ fis_create(int argc, char *argv[]) } if (prog_ok) { // Now program it - if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { + if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } @@ -1056,8 +1090,8 @@ fis_load(int argc, char *argv[]) load_address = mem_addr; load_address_end = (unsigned long)p->out_buf; - // Reload fis directory - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + // Reload fis directory + fis_read_directory(); } else // dangling block #endif { @@ -1156,7 +1190,7 @@ fis_write(int argc, char *argv[]) } if (prog_ok) { // Now program it - if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { + if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } @@ -1227,7 +1261,7 @@ fis_lock(int argc, char *argv[]) (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, (void *)&length, (bool *)&length_set, "length"); - if (!scan_opts(argc, argv, 2, opts, 2, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) + if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; @@ -1274,7 +1308,7 @@ fis_unlock(int argc, char *argv[]) (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, (void *)&length, (bool *)&length_set, "length"); - if (!scan_opts(argc, argv, 2, opts, 2, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) + if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; @@ -1321,7 +1355,6 @@ bool do_flash_init(void) { int stat; - void *err_addr; if (!__flash_init) { __flash_init = 1; @@ -1357,7 +1390,7 @@ do_flash_init(void) diag_printf("FIS directory doesn't fit\n"); return false; } - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_read_directory(); #endif } return true;
