/*********************************************************************** * * Function: flash_image_save * * Purpose: Moves image in memory to FLASH application load region * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE. * * Notes: None * **********************************************************************/ BOOL_32 flash_image_save(void) { UNS_32 fblock, ffblock; INT_32 sector, numsecs, nblks; FLASH_SAVE_T flashsavdat; /* Set first block pat boot loader */ ffblock = fblock = sysinfo.sysrtcfg.bl_num_blks; /* Save programmed FLASH data */ flashsavdat.block_first = fblock; flashsavdat.num_bytes = sysinfo.lfile.num_bytes; flashsavdat.loadaddr = sysinfo.lfile.loadaddr; flashsavdat.startaddr = (UNS_32) sysinfo.lfile.startaddr; flashsavdat.valid = TRUE; /* Get starting sector and number of sectors to program */ numsecs = sysinfo.lfile.num_bytes / sysinfo.nandgeom->data_bytes_per_page; if ((numsecs * sysinfo.nandgeom->data_bytes_per_page) < sysinfo.lfile.num_bytes) { numsecs++; } flashsavdat.secs_used = numsecs; nblks = numsecs / sysinfo.nandgeom->pages_per_block; if ((nblks * sysinfo.nandgeom->pages_per_block) < numsecs) { nblks++; } flashsavdat.blocks_used = nblks; /* Erase necessary blocks first */ while (nblks > 0) { if (flash_is_bad_block(ffblock) == FALSE) { flash_erase_block(ffblock); nblks--; } ffblock++; } /* Burn image into FLASH */ sector = conv_to_sector(fblock, 0); if (mem_to_nand(sector, (UNS_8 *) sysinfo.lfile.loadaddr, (numsecs * sysinfo.nandgeom->data_bytes_per_page)) == FALSE) { term_dat_out_crlf(nsaeerr_msg); } else { /* Update saved NAND configuration */ syscfg.fsave = flashsavdat; cfg_save(&syscfg); } return TRUE; }
void flash_erase_block_lazy(target_context_t *tc, mem_region_t *mr) { assert(mr); if (mr->flags & MRF_ERASED) return; flash_erase_block(tc, mr); }
void flash_copy() { uint32 *ptr; int i; ptr = (uint32 *)0x00040000; flash_erase_block(0); for (i = 0; i < 0x10000; i++) { flash_write(i * 4, ptr[i]); if (!(i % 1000)) { MCF5282_WTM_WSR = 0x5555; MCF5282_WTM_WSR = 0xAAAA; } } /* Software reset */ MCF5282_RESET_RCR = MCF5282_RESET_RCR_SOFTRST; }
BOOL flash_module(WORD page, WORD numpages, char *fn, char *name, BYTE flags) { int i; static WORD bytes_read; static WORD b, last_b = 0; static long addr; static WORD pages; pages = numpages; if(flags & 0x01) { prog_fres = f_open(&prog_file, fn, FA_READ); if(prog_fres == FR_OK) { printf("Flashing %s...", name); i = page; do { MAPPER_MAP1 = 0; FillPage(0xff, 0); prog_fres = f_read(&prog_file, (void *)0x4000, 8192, &bytes_read); addr = (((long)(i & 0x7FF)) << 13); b = flash_addr2block(addr); if(b != last_b) { if(!(flags & 0x04)) { flash_erase_block(b); } last_b = b; } flash_page(0, i); i++; pages--; } while((bytes_read == 8192)&&(pages)); f_close(&prog_file); printf(" OK!\n"); } else { printf("\nCouldn't open %s:\n-> Not flashed!\n", fn); return FALSE; } } pages = numpages; if(flags & 0x02) { prog_fres = f_open(&prog_file, fn, FA_READ); if(prog_fres == FR_OK) { printf("Verifying %s...", name); i = page; do { MAPPER_MAP1 = 0; FillPage(0xff, 0); prog_fres = f_read(&prog_file, (void *)0x4000, 8192, &bytes_read); // if(bytes_read != 0x2000) { // printf("Can't read 8192 bytes from file, but %d (error %d)\n", bytes_read, prog_fres); // } if(b=verify_page(0, i)) { // return 0 on good, address when wrong printf(" ERROR!\n",b); dump_hex((void*)(b&0xFFF0), 16); b ^= 0x2000; dump_hex((void*)(b&0xFFF0), 16); return FALSE; } i++; pages--; } while((bytes_read == 8192)&&(pages)); f_close(&prog_file); printf(" OK!\n"); } else { printf("\nCouldn't open %s:\n-> Not verified!\n", fn); return FALSE; } } return TRUE; }
/*f command_flash_erase */ static int command_flash_erase( int argc, unsigned int *args ) { if (argc<1) return 1; return !flash_erase_block( args[0]<<17 ); }
/*********************************************************************** * * Function: cfg_save * * Purpose: Save a S1L configuration * * Processing: * See function. * * Parameters: * pCfg : Pointer to config structure to save * * Outputs: None * * Returns: Always returns FALSE * * Notes: None * **********************************************************************/ BOOL_32 cfg_save(S1L_CFG_T *pCfg) { UNS_32 sector, blk = adjusted_num_blocks - 1; const UNS_32 cfg_check_data = CHECK_KEY; UNS_32 pg_sz = sysConfig.nandgeom->data_bytes_per_page; if (cfg_size_check() == FALSE) return FALSE; while (blk < adjusted_num_blocks) { /* This won't erase bad blocks */ if (flash_erase_block(blk) == TRUE) { INT_32 offset = 0, page = 0; INT_32 sz_bcfg = sizeof(s1l_board_cfg); INT_32 sz_cfg = sizeof(*pCfg); UNS_8 *ptr_cfg = (UNS_8 *)pCfg; UNS_8 *ptr_bcfg = (UNS_8 *)&s1l_board_cfg; memcpy(secdat, &cfg_check_data, sizeof(cfg_check_data)); offset += sizeof(cfg_check_data); /* Copy structure by structure */ while (sz_bcfg > 0 || sz_cfg > 0) { /* Copy S1l Configuration structure */ if (sz_cfg > 0) { UNS_32 tmp = sz_cfg > (pg_sz - offset) ? pg_sz - offset : sz_cfg; memcpy((UNS_8 *)secdat + offset, ptr_cfg, tmp); sz_cfg -= tmp; offset += tmp; ptr_cfg += tmp; } /* Copy Board configuration structure */ if (sz_bcfg > 0 && offset < pg_sz) { UNS_32 tmp = sz_bcfg > (pg_sz - offset) ? pg_sz - offset : sz_bcfg; memcpy((UNS_8 *)secdat + offset, ptr_bcfg, tmp); sz_bcfg -= tmp; offset += tmp; ptr_bcfg += tmp; } if (offset >= pg_sz || (sz_bcfg <= 0 && sz_cfg <= 0)) { sector = conv_to_sector(blk, page); if(flash_write_sector(sector, secdat, NULL) < 0) return FALSE; page ++; offset = 0; } } return TRUE; } else { adjusted_num_blocks ++; // sysinfo.sysrtcfg.bl_num_blks = adjusted_num_blocks; } blk ++; } return FALSE; }
int main(int argc, char *argv[]) { int in_fd = STDIN_FILENO, i=0, got, offset, extra; int buf[256]; int fw = 1, fv = 1, fr = 0, verbose = 0; char *name = NULL; int block = 0; if ( argc > 2 ) { if ( '-' == argv[1][0] && 'b' == argv[1][1] && 0 == argv[1][3] ) { char c = argv[1][2]; if ( '0' <= c && c <= '9') block = c - '0'; else if ( 'a' <= c && c <= 'f') block = c - 'a' + 10; else if ( 'A' <= c && c <= 'F') block = c - 'A' + 10; else argc = 1; /* get usage message below */ argv++, argc--; } } switch (argc) { case 1: in_fd = STDIN_FILENO; fv = 0; /* Cannot rewind stdin, so do not verify */ break; case 2: if ( '-' == argv[1][0] ) { if ( 'r' != argv[1][1] || 0 != argv[1][2]) goto usage; fr = 1; fw = fv = 0; break; } name = argv[1]; in_fd = open(argv[1], O_RDONLY); if (in_fd < 0) { fprintf(stderr, "Can't open %s", argv[1]); perror(": "); exit(1); } break; case 3: if ( '-' != argv[1][0] || 0 != argv[1][2]) goto usage; if ( 'v' == argv[1][1] ) fw = 0; else if ( 'V' == argv[1][1] ) fw = 0, verbose = 1; else if ( 'w' == argv[1][1] ) fv = 0; else goto usage; name = argv[2]; in_fd = open(argv[2], O_RDONLY); if (in_fd < 0) { fprintf(stderr, "Can't open %s", argv[2]); perror(": "); exit(1); } break; default: usage: fprintf(stderr, "Usage: sa_flash [filename]\n"); fprintf(stderr, "Block number: sa_flash -bN [filename]\n"); fprintf(stderr, "Write only: sa_flash [-bN] -w filename\n"); fprintf(stderr, "Verify only: sa_flash [-bN] -v|-V filename\n"); fprintf(stderr, "Read to stdout: sa_flash [-bN] -r\n"); exit(1); } driver_fd = open("/dev/safl", O_RDWR); if (driver_fd < 0) { perror("Can't open device: "); exit (1); } flash_base = mmap(NULL, FLASH_SZ, PROT_READ|PROT_WRITE, MAP_SHARED, driver_fd, 0); if (flash_base == NULL) { perror("mmap failed: "); close(driver_fd); return 0; } if (!flash_verify()) { fprintf(stderr, "Couldn't find flash.\n"); exit(1); } if ( fw ) { if ( ! flash_erase_block(block) ) { fprintf(stderr,"Erase error block %x\n", block); exit(1); } extra = 0; offset = block * FLASH_BLOCK_SZ; while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) { got += extra; extra = got & 3; got /= 4; for (i = 0; i < got; ++i, offset += 4) if ( ! flash_write_dword(offset, buf[i]) ) fprintf(stderr,"Write error offset %06x\n",offset); if (extra) buf[0] = buf[i]; printf("*"); fflush(stdout); } if (extra) if ( ! flash_write_dword(offset, buf[i]) ) fprintf(stderr,"Write error offset %06x\n",offset); printf("\n"); } flash_normal_mode(); if ( fv ) { int badwords = 0; int skipping = 0; close( in_fd ); in_fd = open(name, O_RDONLY); if (in_fd < 0) { fprintf(stderr, "Can't re-open %s", argv[2]); perror(": "); exit(1); } extra = 0; offset = block * FLASH_BLOCK_SZ; while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) { got += extra; extra = got & 3; got /= 4; for (i = 0; i < got; ++i, offset += 4) { int data = flash_read_dword(offset); if ( data != buf[i] ) { badwords++; if ( !skipping ) { fprintf(stderr, "Bad data at offset %06x: %08x read %08x wanted\n", offset, data, buf[i] ); if ( !verbose && badwords > 15 ) { skipping = 1; fprintf(stderr, "(Too many errors, skipping...)\n"); } } } } if (extra) buf[0] = buf[i]; printf("+"); fflush(stdout); } if (extra) { int data = flash_read_dword(offset); if ( data != buf[0] ) { fprintf(stderr, "End data at offset %06x: %08x read %08x wanted\n", offset, data, buf[0] ); } } printf("\n"); if ( badwords ) fprintf(stderr, "Bad data: %d bad words out of %d (end offset %06x)\n", badwords, offset/4, offset ); } flash_normal_mode(); if ( fr ) { for ( offset = block * FLASH_BLOCK_SZ; offset < (block+1) * FLASH_BLOCK_SZ; offset += 4 ) { for ( i = 0; i < (sizeof(buf)/sizeof(int)); ++i, offset += 4 ) { buf[i] = flash_read_dword(offset); } if ( sizeof(buf) != write( STDOUT_FILENO, buf, sizeof(buf) ) ) { perror("Stdout write failed: "); exit(1); } fprintf(stderr,"r"); fflush(stderr); } fprintf(stderr,"\n"); } munmap((void *)flash_base, FLASH_SZ); close(driver_fd); return 0; }