/* * Inlineable function to Generic Reset the Chip */ static __inline void fl_reset(struct fl_map *map) { switch(map->fl_map_bus) { case FL_BUS_8: if(!map->fl_type)fl_mydetect(map); #if NMOD_FLASH_SST if(map->fl_type==TYPE_SST) { outb((map->fl_map_base), 0xf0); break; } #endif #if NMOD_FLASH_AMD if(map->fl_type==TYPE_AMD) { outb((map->fl_map_base), 0x90); outb((map->fl_map_base), 0x00); break; } #endif #if NMOD_FLASH_ST if(map->fl_type==TYPE_ST) { outb(map->fl_map_base, 0xf0); break; } #endif break; case FL_BUS_16: SETWIDE(FL_RESET); outw(map->fl_map_base, widedata); break; case FL_BUS_32: SETWIDE(FL_RESET); outl(map->fl_map_base, widedata); break; case FL_BUS_64: case FL_BUS_8_ON_64: SETWIDE(FL_RESET); movequad((void *)map->fl_map_base, &widedata); break; } }
/* * Verify flash contents to ram contents. */ int fl_verify_device(void *fl_base, void *data_base, int data_size, int verbose) { struct fl_map *map; struct fl_device *dev; void *fl_last; int ok; int i; dev = fl_devident(fl_base, &map); if(dev == NULL) { return(-3); /* No flash device found at address */ } if(data_size == -1 || (int)data_base == -1) { return(-4); /* Bad parameters */ } if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) { return(-4); /* Size larger than device array */ } if(verbose) { printf("Verifying FLASH. "); } for(i = 0; i < data_size; i += map->fl_map_width) { fl_last = fl_base; switch(map->fl_map_bus) { case FL_BUS_8: ok = (*((u_char *)fl_base) == *((u_char *)data_base)); fl_base++; data_base++; break; case FL_BUS_16: ok = (*((u_short *)fl_base) == *((u_short *)data_base)); fl_base += 2; data_base += 2; break; case FL_BUS_32: ok = (*((u_int *)fl_base) == *((u_int *)data_base)); fl_base += 4; data_base += 4; break; case FL_BUS_64: movequad(&widedata, fl_base); ok = (bcmp(data_base, (void *)&widedata, 8) == 0); data_base += 8; fl_base += 8; break; case FL_BUS_8_ON_64: ok = (*((u_char *)map->fl_map_base + (((int)fl_base - map->fl_map_base) << 3)) == *(u_char *)data_base++); fl_base++; break; } if(verbose & !ok) { printf(" error offset %p\n", fl_last); { char str[100]; int timeout; printf("erase all chip(y/N)?"); gets(str); if(str[0]=='y'||str[0]=='Y') { tgt_flashwrite_enable(); fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */ printf("Erasing all FLASH blocks. "); (*dev->functions->erase_chip)(map, dev); delay(1000); for(timeout = 0 ; ((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff,0, TRUE)) == 1) && (timeout < PFLASH_MAX_TIMEOUT); timeout++) { delay(1000); if(verbose) { dotik(256, 0); } } delay(1000); if(!(timeout < PFLASH_MAX_TIMEOUT)) { (*dev->functions->erase_suspend)(map, dev); } (*dev->functions->reset)(map, dev); tgt_flashwrite_disable(); fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */ } } break; } else if(verbose) { dotik(32, 0); } } if(verbose && ok) { printf("\b No Errors found.\n"); } return(ok); }
static __inline void fl_autoselect(struct fl_map *map) { switch(map->fl_map_bus) { case FL_BUS_8: if((map->fl_type>>16)!=0x5a5a)fl_mydetect(map); #if NMOD_FLASH_SST || NMOD_FLASH_WINBOND if(map->fl_type==TYPE_SST) //SST or WINBOND { outb((map->fl_map_base + SST_CMDOFFS1), 0xAA); outb((map->fl_map_base + SST_CMDOFFS2), 0x55); outb((map->fl_map_base + SST_CMDOFFS1), FL_AUTOSEL); break; } #endif #if NMOD_FLASH_AMD if(map->fl_type==TYPE_AMD) { outb((map->fl_map_base + AMD_CMDOFFS1), 0xAA); outb((map->fl_map_base + AMD_CMDOFFS2), 0x55); outb((map->fl_map_base + AMD_CMDOFFS1), FL_AUTOSEL); break; } #endif #if NMOD_FLASH_ST if(map->fl_type==TYPE_ST) { outb((map->fl_map_base + ConvAddr1(0x555)), 0xAA); outb((map->fl_map_base + ConvAddr1(0x2aa)), 0x55); outb((map->fl_map_base + ConvAddr1(0x555)), FL_AUTOSEL); break; } #endif break; case FL_BUS_16: #if 0 SETWIDE(0xaa); outw(map->fl_map_base + (0x5555 << 2), widedata); SETWIDE(0x55); outw(map->fl_map_base + (0xaaaa << 2), widedata); SETWIDE(FL_AUTOSEL); outw(map->fl_map_base + (0x5555 << 2), widedata); #else SETWIDE(0xaa); outw(map->fl_map_base + ConvAddr2(0x00555), widedata); SETWIDE(0x55); outw(map->fl_map_base + ConvAddr2(0x002AA), widedata); SETWIDE(FL_AUTOSEL); outw(map->fl_map_base + ConvAddr2(0x00555), widedata); #endif break; case FL_BUS_32: SETWIDE(0xaa); outl(map->fl_map_base + (0x5555 << 4), widedata); SETWIDE(0x55); outl(map->fl_map_base + (0xaaaa << 4), widedata); SETWIDE(FL_AUTOSEL); outl(map->fl_map_base + (0x5555 << 4), widedata); break; case FL_BUS_64: case FL_BUS_8_ON_64: SETWIDE(0xAA); movequad((void *)map->fl_map_base + (0x5555 << 3), &widedata); SETWIDE(0x55); movequad((void *)map->fl_map_base + (0x2AAA << 3), &widedata); SETWIDE(FL_AUTOSEL); movequad((void *)map->fl_map_base + (0x5555 << 3), &widedata); break; } }
/* * Verify flash contents to ram contents. */ int fl_verify_device(void *fl_base, void *data_base, int data_size, int verbose) { struct fl_map *map; struct fl_device *dev; void *fl_last; int ok; int i; dev = fl_devident(fl_base, &map); if(dev == NULL) { return(-3); /* No flash device found at address */ } if(data_size == -1 || (int)data_base == -1) { return(-4); /* Bad parameters */ } if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) { return(-4); /* Size larger than device array */ } if(verbose) { printf("Verifying FLASH. "); } for(i = 0; i < data_size; i += map->fl_map_width) { fl_last = fl_base; switch(map->fl_map_bus) { case FL_BUS_8: ok = (*((u_char *)fl_base) == *((u_char *)data_base)); fl_base += 1; data_base += 1; break; case FL_BUS_16: ok = (*(u_short *)fl_base == *((u_short *)data_base)); fl_base += 2; data_base += 2; break; case FL_BUS_32: ok = (*(u_int *)fl_base == *(u_int *)data_base); fl_base += 4; data_base += 4; break; case FL_BUS_64: movequad(&widedata, fl_base); ok = (bcmp(data_base, (void *)&widedata, 8) == 0); data_base += 8; fl_base += 8; break; case FL_BUS_8_ON_64: ok = (*((u_char *)map->fl_map_base + (((int)fl_base - map->fl_map_base) << 3)) == *(u_char *)data_base++); fl_base++; break; } if(verbose & !ok) { printf(" error offset %p\n", fl_last); { char str[100]; int timeout; printf("erase all chip(y/N)?"); gets(str); if(str[0]=='y'||str[0]=='Y') { tgt_flashwrite_enable(); printf("Erasing all FLASH blocks. "); fl_erase_device(map->fl_map_base,map->fl_map_size,FALSE); tgt_flashwrite_disable(); } } break; } else if(verbose) { dotik(32, 0); } } if(verbose && ok) { printf("\b No Errors found.\n"); } return(ok); }
static __inline void fl_autoselect(struct fl_map *map) { switch(map->fl_map_bus) { case FL_BUS_8: if((map->fl_type>>16)!=0x5a5a)fl_mydetect(map); #if NMOD_FLASH_SST || NMOD_FLASH_WINBOND if(map->fl_type==TYPE_SST) //SST or WINBOND { outb((map->fl_map_base + SST_CMDOFFS1), 0xAA); outb((map->fl_map_base + SST_CMDOFFS2), 0x55); outb((map->fl_map_base + SST_CMDOFFS1), FL_AUTOSEL); break; } #endif #if NMOD_FLASH_AMD if(map->fl_type==TYPE_AMD) { outb((map->fl_map_base + AMD_CMDOFFS1), 0xAA); outb((map->fl_map_base + AMD_CMDOFFS2), 0x55); outb((map->fl_map_base + AMD_CMDOFFS1), FL_AUTOSEL); break; } #endif #if NMOD_FLASH_ST if(map->fl_type==TYPE_ST) { outb((map->fl_map_base + ConvAddr1(0x555)), 0xAA); outb((map->fl_map_base + ConvAddr1(0x2aa)), 0x55); outb((map->fl_map_base + ConvAddr1(0x555)), FL_AUTOSEL); break; } #endif break; case FL_BUS_16: { short oldc=inw(map->fl_map_base); outw((map->fl_map_base + ConvAddr2(SST_CMDOFFS1)), 0xAA); outw((map->fl_map_base + ConvAddr2(SST_CMDOFFS2)), 0x55); outw((map->fl_map_base + ConvAddr2(SST_CMDOFFS1)), FL_AUTOSEL); if(inw(map->fl_map_base)!=oldc){map->fl_type=TYPE_SST;return;} outw((map->fl_map_base + ConvAddr2(AMD_CMDOFFS1)), 0xAA); outw((map->fl_map_base + ConvAddr2(AMD_CMDOFFS2)), 0x55); outw((map->fl_map_base + ConvAddr2(AMD_CMDOFFS1)), FL_AUTOSEL); if(inw(map->fl_map_base)!=oldc){map->fl_type=TYPE_AMD;return;} else {map->fl_type=0;printf("unknow flash type\n"); } } break; case FL_BUS_32: SETWIDE(0xaa); outl(map->fl_map_base + (0x5555 << 4), widedata); SETWIDE(0x55); outl(map->fl_map_base + (0xaaaa << 4), widedata); SETWIDE(FL_AUTOSEL); outl(map->fl_map_base + (0x5555 << 4), widedata); break; case FL_BUS_64: case FL_BUS_8_ON_64: SETWIDE(0xAA); movequad((void *)map->fl_map_base + (0x5555 << 3), &widedata); SETWIDE(0x55); movequad((void *)map->fl_map_base + (0x2AAA << 3), &widedata); SETWIDE(FL_AUTOSEL); movequad((void *)map->fl_map_base + (0x5555 << 3), &widedata); break; } }