static int flash_wait_status(Environ *e, Self *s, int offset, uByte *mask, uByte *data) { int w = s->width; int i; int j; /* toss away the first read since the chip state may be in flux */ if (!FLASH_READ(s, offset, &s->buf[w])) return 0; for (i = 0; i < WAIT_ITERATIONS; i++) { if (!FLASH_READ(s, offset, s->buf)) return 0; for (j = 0; j < w; j++) if ((s->buf[j] & mask[j]) != (data[j] & mask[j])) break; if (j >= w) break; } if (i >= WAIT_ITERATIONS) DPRINTF(("wait_status: %d: buf %02X %02X, mask %02X %02X, data %02X %02X\n", i, s->buf[0], s->buf[1], mask[0], mask[1], data[0], data[1])); return i < WAIT_ITERATIONS; }
LOCAL int flashEraseDevices(volatile UINT8 *sectorBasePtr) { int i; unsigned int status = 0; if (flashVerbose) { printf("Erasing Sector @ 0x%08x\n",(UINT32)sectorBasePtr); } FLASH_WRITE(FLASH_BASE_ADDRESS, 0x0, INTEL_FLASH_READ_MODE); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x0, INTEL_FLASH_CLR_SR); FLASH_WRITE(sectorBasePtr, 0x000, INTEL_FLASH_ERASE_BLOCK); FLASH_WRITE(sectorBasePtr, 0x000, INTEL_FLASH_ERASE_CONFIRM); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x0, INTEL_FLASH_RD_SR); for (i = 0; i < FLASH_ERASE_TIMEOUT_COUNT; i++) { taskDelay(FLASH_ERASE_TIMEOUT_TICKS); status = FLASH_READ(FLASH_BASE_ADDRESS, 0x0); if ((status & 0x80) == 0x80) { break; } } flashReadReset(); if ((status & 0xa0) != 0x80) { printf("flashEraseDevices(): addr 0x%08x erase failed\n", (int)sectorBasePtr); return (ERROR); } return (OK); }
LOCAL int flashProgramDevices(volatile UINT8 *addr, UINT8 val) { int polls; unsigned char status; FLASH_WRITE(FLASH_BASE_ADDRESS, 0x000, INTEL_FLASH_CLR_SR); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x000, INTEL_FLASH_READ_MODE); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x000, INTEL_FLASH_PROGRAM); *addr = val; /* FLASH_WRITE(addr, 0x0, val);*/ FLASH_WRITE(FLASH_BASE_ADDRESS, 0x000, INTEL_FLASH_RD_SR); for (polls = 0; polls < FLASH_PROGRAM_TIMEOUT_POLLS; polls++) { status = FLASH_READ(FLASH_BASE_ADDRESS, 0x0); if ((status & 0x80) == 0x80) { break; } taskDelay(FLASH_PROGRAM_TIMEOUT_TICKS); } flashReadReset(); if ((status & 0x90) != 0x80) { printf("flashProgramDevices(): Address 0x%08x program failed\n", (int)addr); return (ERROR); } else { return (OK); } }
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); }
LOCAL void flashAutoSelect(FLASH_TYPES *dev, FLASH_VENDORS *vendor) { flashReadReset(); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x000, 0x90); *vendor = FLASH_READ(FLASH_BASE_ADDRESS, 0); *dev = FLASH_READ(FLASH_BASE_ADDRESS, 2); if (flashVerbose) { printf("\nflashAutoSelect(): dev = 0x%x, vendor = 0x%x\n", (int)*dev, (int)*vendor); } flashReadReset(); if (((*dev != FLASH_2F320) && (*dev != FLASH_2F128)) || (*vendor != INTEL)) { *vendor = *dev = 0xFF; } }
LOCAL void flashAutoSelect(FLASH_TYPES *dev, FLASH_VENDORS *vendor) { flashReadReset(); FLASH_WRITE(FLASH_BASE_ADDRESS, 0xaaa, 0xaa); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x555, 0x55); FLASH_WRITE(FLASH_BASE_ADDRESS, 0xaaa, 0x90); *vendor = FLASH_READ(FLASH_BASE_ADDRESS, 0); *dev = FLASH_READ(FLASH_BASE_ADDRESS, 2); if (flashVerbose) printf("flashAutoSelect(): dev = 0x%x, vendor = 0x%x\n", (int)*dev, (int)*vendor); flashReadReset(); if ((*dev != FLASH_2L160) || ((*vendor != AMD) && (*vendor != ALLIANCE))) { *vendor = *dev = 0xFF; } }
LOCAL int flashProgramBlock(volatile UINT8 *addr, UINT8 *val) { int polls; int i; unsigned char status; FLASH_WRITE(addr, 0x000, INTEL_FLASH_WB); /* * XSR7 transitions to a 1, the buffer is ready for loading. */ while (((status = FLASH_READ(FLASH_BASE_ADDRESS, 0x0)) & 0x80) == 0) { taskDelay(FLASH_PROGRAM_TIMEOUT_TICKS); } FLASH_WRITE(addr, 0x000, INTEL_FLASH_WBSIZE - 1); for(i = 0; i < INTEL_FLASH_WBSIZE; i++) { FLASH_WRITE(addr, i, val[i ^ xor_val]); } FLASH_WRITE(addr, 0x000, INTEL_FLASH_WB_CONFIRM); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x000, INTEL_FLASH_RD_SR); for (polls = 0; polls < FLASH_PROGRAM_TIMEOUT_POLLS; polls++) { status = FLASH_READ(FLASH_BASE_ADDRESS, 0x0); if ((status & 0x80) == 0x80) { break; } taskDelay(FLASH_PROGRAM_TIMEOUT_TICKS); } if ((status & 0x90) != 0x80) { printf("flashProgramDevices(): Address 0x%08x program failed\n", (int)addr); return (ERROR); } else { return (OK); } }
LOCAL int flashEraseDevices(volatile unsigned char *sectorBasePtr) { int i; unsigned int tmp; if (flashVerbose) { printf("Erasing Sector @ 0x%08x\n",(unsigned int)sectorBasePtr); } FLASH_WRITE(FLASH_BASE_ADDRESS, 0xaaa, 0xaa); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x555, 0x55); FLASH_WRITE(FLASH_BASE_ADDRESS, 0xaaa, 0x80); FLASH_WRITE(FLASH_BASE_ADDRESS, 0xaaa, 0xaa); FLASH_WRITE(FLASH_BASE_ADDRESS, 0x555, 0x55); FLASH_WRITE(sectorBasePtr, 0x0, 0x30); for (i = 0; i < FLASH_ERASE_TIMEOUT_COUNT; i++) { taskDelay(FLASH_ERASE_TIMEOUT_TICKS); tmp = FLASH_READ(sectorBasePtr, 0x0); if ((tmp & 0x80) == 0x80) { if (flashVerbose > 1) printf("flashEraseDevices(): all devices erased\n"); return (OK); } } if ((tmp & 0x20) == 0x20) { printf("flashEraseDevices(): addr 0x%08x erase failed\n", (int)sectorBasePtr); } else { printf("flashEraseDevices(): addr 0x%08x erase timed out\n", (int)sectorBasePtr); } flashReadReset(); return (ERROR); }
// // Attempt to get configuration information from the FLASH. // If available (i.e. good checksum, etc), initialize "known" // values for later use. // static void load_flash_config(void) { bool use_boot_script; unsigned char *cfg_temp = (unsigned char *)workspace_end; #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH void *err_addr; #endif config_ok = false; script = (unsigned char *)0; cfg_temp -= sizeof(struct _config); // Space for primary config data config = (struct _config *)cfg_temp; cfg_temp -= sizeof(struct _config); // Space for backup config data backup_config = (struct _config *)cfg_temp; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK cfg_temp -= sizeof(struct _config); // Space for readonly copy of config data readonly_config = (struct _config *)cfg_temp; #endif workspace_end = cfg_temp; #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH if (!do_flash_init()) return; #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG cfg_size = _rup(sizeof(struct _config), sizeof(struct fis_image_desc)); if ((fisdir_size-cfg_size) < (CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE)) { // Too bad this can't be checked at compile/build time diag_printf("Sorry, FLASH config exceeds available space in FIS directory\n"); return; } cfg_base = (void *)(((CYG_ADDRESS)fis_addr + fisdir_size) - cfg_size); fisdir_size -= cfg_size; #else cfg_size = (flash_block_size > sizeof(struct _config)) ? sizeof(struct _config) : _rup(sizeof(struct _config), flash_block_size); if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 - _rup(_rup((-CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size)); } else { cfg_base = (void *)((CYG_ADDRESS)flash_start + _rup(_rup((CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size)); } #endif FLASH_READ(cfg_base, config, sizeof(struct _config), &err_addr); conf_endian_fixup(config); #else read_eeprom(config, sizeof(struct _config)); // into 'config' #endif #ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK memcpy(readonly_config, config, sizeof(struct _config)); #endif if ((flash_crc(config) != config->cksum) || (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) { diag_printf("**Warning** FLASH configuration checksum error or invalid key\n"); diag_printf("Use 'fconfig -i' to [re]initialize database\n"); config_init(); return; } config_ok = true; flash_get_config("boot_script", &use_boot_script, CONFIG_BOOL); if (use_boot_script) { flash_get_config("boot_script_data", &script, CONFIG_SCRIPT); flash_get_config("boot_script_timeout", &script_timeout, CONFIG_INT); } #ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE if (flash_get_config("console_baud_rate", &console_baud_rate, CONFIG_INT)) { extern int set_console_baud_rate(int); set_console_baud_rate(console_baud_rate); } #endif }
unsigned int flash_read(unsigned short addr) { return FLASH_READ(addr); }
static int run_sequence(Environ *e, Self *s, const Sequence *seq, int offset, uByte *data) { uInt off; int w = s->width; uByte *t = &s->buf[w]; if (offset < 0 || offset >= s->meths->size) return 0; for (; seq->type; seq++) { #ifdef DEBUG2 DPRINTF(("run_seq: seq %p, type %d\n", seq, seq->type)); #endif if (seq->offset < 0) off = offset; else { off = seq->offset * s->partswide; if (!FLASH_MAP_ADDR(s, &off)) return 0; } switch (seq->type) { case FLASH_SEQ_WRITE: /* fill buf with data */ fill_buffer(e, s, t, seq->data); /* map data in buf */ if (!(FLASH_MAP_DATA(s, t))) return 0; /* write data */ if (!FLASH_WRITE(s, off, t)) return 0; break; case FLASH_SEQ_WRITE_DATA: if (!FLASH_WRITE(s, off, data)) return 0; break; case FLASH_SEQ_READ_MANUF: case FLASH_SEQ_READ_DATA: if (!FLASH_READ(s, off, data)) return 0; break; case FLASH_SEQ_READ_DEVID: if (!FLASH_READ(s, off, &data[s->width])) return 0; break; case FLASH_SEQ_WAIT_STATUS: case FLASH_SEQ_WAIT_TOGGLE: case FLASH_SEQ_WAIT_INVERT: { uByte *mask = &s->buf[2 * w]; uByte *opdata = &s->buf[3 * w]; fill_buffer(e, s, mask, seq->mask); fill_buffer(e, s, opdata, seq->data); if (!FLASH_MAP_DATA(s, mask)) return 0; if (!FLASH_MAP_DATA(s, opdata)) return 0; if (seq->type == FLASH_SEQ_WAIT_STATUS) { if (!flash_wait_status(e, s, off, mask, opdata)) return 0; } else if (seq->type == FLASH_SEQ_WAIT_TOGGLE) { if (!flash_wait_toggle(e, s, off, mask, opdata)) return 0; } else { if (!flash_wait_invert(e, s, off, mask, data)) return 0; } } break; case FLASH_SEQ_DELAY: u_sleep(seq->data); break; default: return 0; } } return 1; }