From 9de9d39b630ad85d97cb8355109360301998239f Mon Sep 17 00:00:00 2001 From: lothar Date: Fri, 17 Jul 2009 13:57:50 +0000 Subject: [PATCH] Starterkit 5 Release 1.6 --- .../devs/flash/arm/mxc/v2_0/src/mxc_nfc.c | 120 +++++++++++------- .../karo/v1_0/include/hal_platform_setup.h | 8 +- packages/redboot/v2_0/src/flash.c | 42 +++--- 3 files changed, 99 insertions(+), 71 deletions(-) diff --git a/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c b/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c index f7890f5b..4bcf0060 100644 --- a/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c +++ b/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c @@ -322,7 +322,7 @@ static int flash_enable; static flash_addr_t nfc_l_to_p(flash_addr_t addr) { if (g_block_offset == 0) { - return addr; + return addr & MXC_NAND_ADDR_MASK; } else { flash_addr_t ra; u32 block = (addr & MXC_NAND_ADDR_MASK) / NF_BLK_SZ; @@ -340,11 +340,16 @@ static flash_addr_t nfc_l_to_p(flash_addr_t addr) static int flash_addr_valid(flash_addr_t addr) { + if (!flash_enable) { + nfc_printf(NFC_DEBUG_MIN, "No flash area enabled\n"); + return 1; + } if (addr < flash_region_start || addr >= flash_region_end) { diag_printf("Flash address 0x%08llx is outside valid region 0x%08llx..0x%08llx\n", (u64)addr, (u64)flash_region_start, (u64)flash_region_end); + return 0; } - return addr >= flash_region_start && addr < flash_region_end; + return 1; } /* FIXME: we should pass flash_addr_t as arguments */ @@ -739,7 +744,7 @@ static int nfc_is_badblock(u32 block, u8 *buf) res = (buf[off] >> sft) & 0x3; if (res) { addr = BLOCK_TO_OFFSET(block); - diag_printf1("Block %u at %08llx is marked %s (%d) in BBT@%p[%02x] mask %02x\n", + diag_printf1("Block %u at 0x%08llx is marked %s (%d) in BBT@%p[%02x] mask %02x\n", block, (u64)addr, res == BLK_RESERVED ? "reserved" : res == BLK_BAD_FACTORY ? "factory bad" : "runtime bad", res, buf, off, 3 << sft); @@ -1073,9 +1078,12 @@ int nfc_erase_region(flash_addr_t addr, u32 len, bool skip_bad, bool verbose) diag_printf("Error: invalid length %u (must be > 0 and block aligned)\n", len); return FLASH_ERR_INVALID; } - addr = nfc_l_to_p(addr); + addr &= MXC_NAND_ADDR_MASK; // now addr has to be block aligned for (sz = 0; sz < len; addr += NF_BLK_SZ, j++, sz += NF_BLK_SZ) { + if (!flash_addr_valid(addr)) { + return 0; + } blk = OFFSET_TO_BLOCK(addr); if (skip_bad && nfc_is_badblock(blk, g_bbt)) { diag_printf("\nSkipping bad block %u at addr 0x%08llx\n", @@ -1731,7 +1739,7 @@ local_cmd_entry("info", local_cmd_entry("show", "Show a page main/spare areas or spare area only (-s)", - "-f [-s]", + "-f | -b [-s]", nand_show, NAND_cmds ); @@ -1816,24 +1824,33 @@ static void nand_usage(char *why) static u32 curr_addr; static void nand_show(int argc, char *argv[]) { - u32 ra; + u32 ra, block; bool flash_addr_set = false; + bool block_set = false; bool spar_only = false; - struct option_info opts[2]; + struct option_info opts[3]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, &ra, &flash_addr_set, "NAND FLASH memory byte address"); - init_opts(&opts[1], 's', false, OPTION_ARG_TYPE_FLG, + init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM, + &block, &block_set, "NAND FLASH memory block number"); + init_opts(&opts[2], 's', false, OPTION_ARG_TYPE_FLG, &spar_only, NULL, "Spare only"); - if (!scan_opts(argc, argv, 2, opts, 2, 0, 0, 0)) { + if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) { return; } - if (!flash_addr_set) { + if (flash_addr_set && block_set) { + nand_usage("options -f and -b are mutually exclusive"); + return; + } else if (flash_addr_set) { + curr_addr = ra; + } else if (block_set) { + ra = BLOCK_TO_OFFSET(block) + (unsigned long)flash_info.start; + curr_addr = ra; + } else { ra = curr_addr; curr_addr += NF_PG_SZ; - } else { - curr_addr = ra; } if (ra % NF_PG_SZ) { @@ -1873,7 +1890,7 @@ static void nand_read(int argc, char *argv[]) init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_NUM, &col, &col_set, "column addr"); - if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) { + if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) { nand_usage("invalid arguments"); return; } @@ -1916,6 +1933,12 @@ static void nand_read(int argc, char *argv[]) diag_printf("\n** Error: flash address: 0x%08x out of range\n", ra); return; } + if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) { + diag_printf("\nSkipping bad block %u at addr=0x%08llx\n", + OFFSET_TO_BLOCK(ra), (u64)ra); + ra = (OFFSET_TO_BLOCK(ra) + 1) * NF_BLK_SZ; + continue; + } pg_no = ra / NF_PG_SZ; pg_off = ra % NF_PG_SZ; for (i = 0; i < num_of_nand_chips; i++) { @@ -1958,7 +1981,7 @@ static void nand_write(int argc, char *argv[]) &len, &length_set, "image length [in FLASH]"); init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_NUM, &col, &col_set, "column addr"); - if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) { + if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) { nand_usage("invalid arguments"); return; } @@ -1969,8 +1992,9 @@ static void nand_write(int argc, char *argv[]) } if ((mem_addr < (CYG_ADDRESS)ram_start) || - ((mem_addr+len) >= (CYG_ADDRESS)ram_end)) { - diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); + ((mem_addr + len) >= (CYG_ADDRESS)ram_end)) { + diag_printf("** WARNING: RAM address range: %p..%p may be invalid\n", + (void *)mem_addr, (void *)(mem_addr + len)); diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } @@ -1995,9 +2019,11 @@ static void nand_write(int argc, char *argv[]) mem_addr_st = mem_addr; len_st = len; ra &= MXC_NAND_ADDR_MASK; + + mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ); do { if (OFFSET_TO_BLOCK(ra) > (NF_BLK_CNT - 1)) { - diag_printf("\nOut of range: addr=0x%08x\n", ra); + diag_printf("\nFlash address 0x%08x out of range\n", ra); return; } if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) { @@ -2017,7 +2043,7 @@ static void nand_write(int argc, char *argv[]) } mark_blk_bad(OFFSET_TO_BLOCK(ra), g_bbt, BLK_BAD_RUNTIME); ra = (OFFSET_TO_BLOCK(ra) + 1) * NF_BLK_SZ; //make sure block size aligned - mem_addr = mem_addr_st; // rewind to blocl boundary + mem_addr = mem_addr_st; // rewind to block boundary len = len_st; continue; } @@ -2105,7 +2131,7 @@ static void nand_erase(int argc, char *argv[]) init_opts(&opts[2], 'o', false, OPTION_ARG_TYPE_FLG, &force_erase_set, &force_erase_set, "force erases block"); - if (!scan_opts(argc, argv, 2, opts, 4, 0, 0, 0)) { + if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) { nand_usage("invalid arguments"); return; } @@ -2114,19 +2140,26 @@ static void nand_erase(int argc, char *argv[]) nand_usage("missing argument"); return; } - if ((ra % NF_BLK_SZ) != 0 || - (len % NF_BLK_SZ) != 0 || len == 0) { - diag_printf("Address or length is not block aligned or length is zero!\n"); + if ((ra % NF_BLK_SZ) != 0) { + diag_printf("Address must be block aligned!\n"); + diag_printf("Block size is 0x%x\n", NF_BLK_SZ); + return; + } + if ((len % NF_BLK_SZ) != 0) { + diag_printf("length must be block aligned!\n"); diag_printf("Block size is 0x%x\n", NF_BLK_SZ); return; } + if (len == 0) { + diag_printf("length must be > 0!\n"); + return; + } - if (!verify_action("About to erase 0x%x bytes from nand offset 0x%x\n", len, ra)) { + if (!verify_action("About to erase 0x%08x bytes from nand offset 0x%08x", len, ra)) { diag_printf("** Aborted\n"); return; } - // now ra is block aligned if (force_erase_set == true) { diag_printf("Force erase ..."); nfc_erase_region(ra, len, 0, 1); @@ -2150,7 +2183,7 @@ static void nand_scan(int argc, char *argv[]) init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG, &force_rescan, NULL, "force low level re-scan"); - if (!scan_opts(argc, argv, 2, opts, 2, 0, 0, 0)) { + if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) { nand_usage("invalid arguments"); return; } @@ -2353,29 +2386,24 @@ static void print_page(u32 addr, bool spare_only) diag_printf("Non page-aligned read not supported here: 0x%x\n", addr); return; } - if (spare_only) { - diag_printf("Error %d: Not supported\n", __LINE__); - return; - } else { - pg_no = addr / NF_PG_SZ; - pg_off = addr % NF_PG_SZ; - for (i = 0; i < num_of_nand_chips; i++) { - if (nfc_read_page(i, pg_no, pg_off) != 0) { - diag_printf("Error %d: uncorrectable. But still printing ...\n", __LINE__); - } - pg_off = 0; - diag_printf("\n============ Printing block(%d) page(%d) ==============\n", - blk_num, pg_num); - - diag_printf("<<<<<<<<< spare area >>>>>>>>>\n"); - print_pkt_16((u16*)NAND_SPAR_BUF0, NF_SPARE_SZ); + pg_no = addr / NF_PG_SZ; + pg_off = addr % NF_PG_SZ; + for (i = 0; i < num_of_nand_chips; i++) { + if (nfc_read_page(i, pg_no, pg_off) != 0) { + diag_printf("Error %d: uncorrectable. But still printing ...\n", __LINE__); + } + pg_off = 0; + diag_printf("\n============ Printing block(%d) page(%d) ==============\n", + blk_num, pg_num); - if (!spare_only) { - diag_printf("<<<<<<<<< main area >>>>>>>>>\n"); - print_pkt_16((u16*)NAND_MAIN_BUF0, NF_PG_SZ / num_of_nand_chips); - } + diag_printf("<<<<<<<<< spare area >>>>>>>>>\n"); + print_pkt_16((u16*)NAND_SPAR_BUF0, NF_SPARE_SZ); - diag_printf("\n"); + if (!spare_only) { + diag_printf("<<<<<<<<< main area >>>>>>>>>\n"); + print_pkt_16((u16*)NAND_MAIN_BUF0, NF_PG_SZ / num_of_nand_chips); } + + diag_printf("\n"); } } diff --git a/packages/hal/arm/mx25/karo/v1_0/include/hal_platform_setup.h b/packages/hal/arm/mx25/karo/v1_0/include/hal_platform_setup.h index f8f99314..2d687592 100644 --- a/packages/hal/arm/mx25/karo/v1_0/include/hal_platform_setup.h +++ b/packages/hal/arm/mx25/karo/v1_0/include/hal_platform_setup.h @@ -278,24 +278,24 @@ NAND_Copy_Main: ldr r7, CCM_BASE_ADDR_W ldr r1, [r7, #CLKCTL_RCSR] /* BUS WIDTH setting */ - tst r1, #(1 << 24)// Freescale: 0x20000000 + tst r1, #(1 << 24) orrne r1, r1, #(1 << 14) biceq r1, r1, #(1 << 14) /* 4K PAGE */ - tst r1, #(1 << 27)// Freescale: 0x10000000 + tst r1, #(1 << 27) orrne r1, r1, #(1 << 9) bne 1f /* 2K PAGE */ bic r1, r1, #(1 << 9) - tst r1, #(1 << 26)// Freescale: 0x08000000 + tst r1, #(1 << 26) orrne r1, r1, #(1 << 8) /* 2KB page size */ biceq r1, r1, #(1 << 8) /* 512B page size */ movne r2, #(64 >> 1) /* 64 bytes */ moveq r2, #8 /* 16 bytes */ b NAND_setup 1: - tst r1, #(1 << 26)// Freescale: 0x08000000 + tst r1, #(1 << 26) bicne r3, r3, #1 /* Enable 8bit ECC mode */ movne r2, #109 /* 218 bytes */ moveq r2, #(128 >> 1) /* 128 bytes */ diff --git a/packages/redboot/v2_0/src/flash.c b/packages/redboot/v2_0/src/flash.c index 86557d4e..ac2dcf1b 100644 --- a/packages/redboot/v2_0/src/flash.c +++ b/packages/redboot/v2_0/src/flash.c @@ -723,33 +723,33 @@ fis_list(int argc, char *argv[]) last_addr = 0; image_indx = 0; do { - image_found = false; - lowest_addr = 0xFFFFFFFF; - img = fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { - if (img->u.name[0] != 0xFF) { - if ((img->flash_base >= last_addr) && (img->flash_base < lowest_addr)) { - lowest_addr = img->flash_base; - image_found = true; - image_indx = i; + image_found = false; + lowest_addr = 0xFFFFFFFF; + img = fis_work_block; + for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { + if (img->u.name[0] != 0xFF) { + if ((img->flash_base >= last_addr) && (img->flash_base < lowest_addr)) { + lowest_addr = img->flash_base; + image_found = true; + image_indx = i; + } + } } - } - } - if (image_found) { - img = fis_work_block; - img += image_indx; - diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->u.name, - (unsigned long)img->flash_base, + if (image_found) { + img = fis_work_block; + img += image_indx; + diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->u.name, + (unsigned long)img->flash_base, #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - show_cksums ? img->file_cksum : img->mem_base, + show_cksums ? img->file_cksum : (unsigned long)img->mem_base, show_datalen ? img->data_length : img->size, #else - img->mem_base, + (unsigned long)img->mem_base, img->size, #endif - (unsigned long)img->entry_point); - } - last_addr = lowest_addr + 1; + (unsigned long)img->entry_point); + } + last_addr = lowest_addr + 1; } while (image_found == true); } -- 2.39.2