int do_write_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i, ret; char mac_string[256]; struct spi_flash *spi; unsigned char *buf; if (argc != 5) { buf = malloc(256); if (!buf) { printf("%s: malloc error.\n", __func__); return 1; } get_sh_eth_mac_raw(buf, 256); /* print current MAC address */ for (i = 0; i < 4; i++) { get_sh_eth_mac(i, mac_string, buf); if (i < 2) printf(" ETHERC ch%d = %s\n", i, mac_string); else printf("GETHERC ch%d = %s\n", i-2, mac_string); } free(buf); return 0; } /* new setting */ memset(mac_string, 0xff, sizeof(mac_string)); sprintf(mac_string, "%s\t%s\t%s\t%s", argv[1], argv[2], argv[3], argv[4]); /* write MAC data to SPI rom */ spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3); if (!spi) { printf("%s: spi_flash probe error.\n", __func__); return 1; } ret = spi_flash_erase(spi, SH7757LCR_ETHERNET_MAC_BASE_SPI, SH7757LCR_SPI_SECTOR_SIZE); if (ret) { printf("%s: spi_flash erase error.\n", __func__); return 1; } ret = spi_flash_write(spi, SH7757LCR_ETHERNET_MAC_BASE_SPI, sizeof(mac_string), mac_string); if (ret) { printf("%s: spi_flash write error.\n", __func__); spi_flash_free(spi); return 1; } spi_flash_free(spi); puts("The writing of the MAC address to SPI ROM was completed.\n"); return 0; }
int saveenv(void) { u32 sector = 1; if (!env_flash) { puts("Environment SPI flash not initialized\n"); return 1; } if (CFG_ENV_SIZE > CFG_ENV_SECT_SIZE) { sector = CFG_ENV_SIZE / CFG_ENV_SECT_SIZE; if (CFG_ENV_SIZE % CFG_ENV_SECT_SIZE) sector++; } puts("Erasing SPI flash..."); if (spi_flash_erase(env_flash, CFG_ENV_OFFSET, sector * CFG_ENV_SECT_SIZE)) return 1; puts("Writing to SPI flash..."); if (spi_flash_write(env_flash, CFG_ENV_OFFSET, CFG_ENV_SIZE, env_ptr)) return 1; puts("done\n"); return 0; }
static int env_sf_save(void) { u32 saved_size, saved_offset, sector; char *saved_buffer = NULL; int ret = 1; env_t env_new; ret = setup_flash_device(); if (ret) return ret; /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) goto done; ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = env_export(&env_new); if (ret) goto done; sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE); puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = 0; puts("done\n"); done: if (saved_buffer) free(saved_buffer); return ret; }
int saveenv(void) { u32 saved_size, saved_offset; char *saved_buffer = NULL; u32 sector = 1; int ret; if (!env_flash) { puts("Environment SPI flash not initialized\n"); return 1; } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) { ret = 1; goto done; } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = 0; puts("done\n"); done: if (saved_buffer) free(saved_buffer); return ret; }
/** * Erase physical flash. * * Offset and size must be a multiple of CONFIG_FLASH_ERASE_SIZE. * * @param offset Flash offset to erase. * @param size Number of bytes to erase. */ int flash_physical_erase(int offset, int size) { int ret; if (entire_flash_locked) return EC_ERROR_ACCESS_DENIED; ret = spi_flash_erase(offset, size); return ret; }
/** * Erase physical flash. * * Offset and size must be a multiple of CONFIG_FLASH_ERASE_SIZE. * * @param offset Flash offset to erase. * @param size Number of bytes to erase. */ int flash_physical_erase(int offset, int size) { int ret; if (entire_flash_locked) return EC_ERROR_ACCESS_DENIED; offset += CONFIG_FLASH_BASE_SPI; ret = spi_flash_erase(offset, size); return ret; }
static ssize_t spi_eraseat(const struct region_device *rd, size_t offset, size_t size) { struct spi_flash *sf = car_get_var(sfg); if (sf == NULL) return -1; if (spi_flash_erase(sf, offset, size)) return -1; return size; }
static void erase_environment(void) { struct spi_flash *flash; printf("Erasing environment..\n"); flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3); if (!flash) { printf("Erasing flash failed\n"); return; } spi_flash_erase(flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE); spi_flash_free(flash); do_reset(NULL, 0, 0, NULL); }
static int writeImageToSerialFlash(PartitionInfo_S *psPartitionInfo, void *pvBuf, int nBufLength) { int nRet; unsigned int nBus = 0; unsigned int nCS = 0; unsigned int nSpeed = 1000000; unsigned int nMode = SPI_MODE_3; ImageInfo_S *psImageInfo = &psPartitionInfo->m_sImageInfo; struct spi_flash *psFlash; int nOffset = psPartitionInfo->m_nBeginAddr; int nLength = psPartitionInfo->m_nEndAddr-psPartitionInfo->m_nBeginAddr; psFlash = spi_flash_probe(nBus, nCS, nSpeed, nMode); if (!psFlash) { printf("Failed to initialize SPI flash at %u:%u\n", nBus, nCS); return FALSE; } if (nOffset + nLength > psFlash->size) { printf("ERROR: attempting past flash size (%#x)\n", psFlash->size); return FALSE; } nRet = spi_flash_erase(psFlash, nOffset&(~(psFlash->sector_size-1)), nLength&(~(psFlash->sector_size-1))); if (nRet) { printf("SPI flash erase failed\n"); return FALSE; } nLength = psImageInfo->m_nImageSize; if (psImageInfo->m_eImageType==EM_IMAGE_TYPE_BOOTSTRAP) { *(int *)(pvBuf+psImageInfo->m_nImageOffset+0x14) = nLength; } nRet = spi_flash_write(psFlash, nOffset, nLength, pvBuf+psImageInfo->m_nImageOffset); if (nRet) { printf("SPI flash write failed\n"); return FALSE; } spi_flash_free(psFlash); return TRUE; }
int main(int argc, char *argv[]) { uint16_t i, t; uint8_t buf[260]; const uint8_t testdata[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}; hal_disable_ints(); // In case we got here via jmp 0x0 // spi_init(); hal_uart_init(); // clocks_init(); //set up AD9510, enable FPGA clock @ 1x divisor puts("SPI Flash test\n"); puts("Initializing SPI\n"); spif_init(); delay(800000); puts("Erasing sector 1\n"); spi_flash_erase(0x00010000, 256); delay(800000); puts("Reading back data\n"); spi_flash_read(0x00010000, 256, buf); delay(800000); t=1; for(i=4; i<250; i++) { if(buf[i] != 0xFF) t=0; } if(!t) puts("Data was not initialized to 0xFF. Unsuccessful erase or read\n"); else puts("Data initialized to 0xFF, erase confirmed\n"); puts("Writing test buffer\n"); spi_flash_program(0x00010000, 16, testdata); //memset(buf, 0, 256); delay(800000); puts("Wrote data, reading back\n"); spi_flash_read(0x00010000, 16, buf); if(memcmp(testdata, buf, 16)) puts("Data is not the same between read and write. Unsuccessful write or read\n"); else puts("Successful write! Flash write correct\n"); return 0; }
static int spi_burn_image(size_t image_size) { int ret; struct spi_flash *flash; u32 erase_bytes; /* Probe the SPI bus to get the flash device */ flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!flash) { printf("Failed to probe SPI Flash\n"); return -ENOMEDIUM; } #ifdef CONFIG_SPI_FLASH_PROTECTION spi_flash_protect(flash, 0); #endif erase_bytes = image_size + (flash->erase_size - image_size % flash->erase_size); printf("Erasing %d bytes (%d blocks) at offset 0 ...", erase_bytes, erase_bytes / flash->erase_size); ret = spi_flash_erase(flash, 0, erase_bytes); if (ret) printf("Error!\n"); else printf("Done!\n"); printf("Writing %d bytes from 0x%lx to offset 0 ...", (int)image_size, get_load_addr()); ret = spi_flash_write(flash, 0, image_size, (void *)get_load_addr()); if (ret) printf("Error!\n"); else printf("Done!\n"); #ifdef CONFIG_SPI_FLASH_PROTECTION spi_flash_protect(flash, 1); #endif return ret; }
void spi_flash_program(void *from, unsigned int addr, unsigned int len) { unsigned int i, j; j = addr + len; putstr("Erasing: "); for (i = addr; (i < j); i += FLASH_SECTORSIZE) { spi_flash_erase(i); putch('.'); } putch('\n'); putstr("Programming: "); for (i = addr; (i < j); i += FLASH_PAGESIZE) { spi_flash_write_page(from, i); from += FLASH_PAGESIZE; putch('.'); } putch('\n'); }
void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) { struct spi_flash *flash; spi_init(); flash = spi_flash_probe(0, 0); if (!flash) { printk(BIOS_DEBUG, "Could not find SPI device\n"); /* Dont make flow stop. */ return; } spi_flash_volatile_group_begin(flash); spi_flash_erase(flash, pos, size); spi_flash_write(flash, pos, sizeof(len), &len); spi_flash_write(flash, pos + sizeof(len), len, buf); spi_flash_volatile_group_end(flash); return; }
static int sf_saveenv(void) { u32 saved_size, saved_offset; char *saved_buffer = NULL; u32 sector = 1; int ret; u_int32_t erase_length; struct mtd_info_ex *spiflash_info = get_spiflash_info(); if (!env_flash) { puts("Environment SPI flash not initialized\n"); return 1; } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) { ret = 1; goto done; } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } erase_length = (sector * CONFIG_ENV_SECT_SIZE); if (erase_length < spiflash_info->erasesize) { printf("Warning: Erase size 0x%08x smaller than one " \ "erase block 0x%08x\n", erase_length, spiflash_info->erasesize); printf(" Erasing 0x%08x instead\n", spiflash_info->erasesize); erase_length = spiflash_info->erasesize; } printf("Erasing SPI flash, offset 0x%08x size %s ...", CONFIG_ENV_OFFSET, ultohstr(erase_length)); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, erase_length); if (ret) goto done; printf("done\nWriting to SPI flash, offset 0x%08x size %s ...", CONFIG_ENV_OFFSET, ultohstr(CONFIG_ENV_SIZE)); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = 0; puts("done\n"); done: if (saved_buffer) free(saved_buffer); return ret; }
void uart_flash_loader(void) { char buf[256]; //input data buffer uint8_t ihx[32]; //ihex data buffer uint32_t slot_offset = PROD_FW_IMAGE_LOCATION_ADDR; //initial slot offset to program to. uint32_t extended_addr = 0x00000000; //extended Intel hex segment address size_t sector_size = spi_flash_log2_sector_size(); ihex_record_t ihex_record; ihex_record.data = ihx; int i; //not gonna win a turing prize for my C text parsing while(1) { gets(buf); if(!strncmp(buf, "!SECTORSIZE", 7)) { //return the sector size in log format putstr("OK "); puthex8((uint32_t) sector_size); //err, this should probably be decimal for human readability. we do have itoa now... putstr("\n"); } else if(!strncmp(buf, "!SETADDR", 7)) { //set start address for programming slot_offset = atol(&buf[8]); puts("OK"); // puthex32(slot_offset); // putstr("\n"); } else if(!strncmp(buf, "!ERASE", 6)) { //erase a sector uint32_t sector = atol(&buf[6]); uint32_t size = 2 << (sector_size-1); uint32_t addr = sector << sector_size; spi_flash_erase(addr, size); //we DO NOT implement write protection here. it is up to the HOST PROGRAM to not issue an ERASE unless it means it. //unfortunately the Flash cannot write-protect the segments that really matter, so we only use global write-protect //as a means of avoiding accidental writes from runaway code / garbage on the SPI bus. puts("OK"); } //can't exactly run firmware if you're already executing out of main RAM /* else if(!strncmp(buf, "!RUNSFW", 7)) { if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) { puts("OK"); spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE); start_program(RAM_BASE); } else { puts("NOK"); } } else if(!strncmp(buf, "!RUNPFW", 7)) { if(is_valid_fw_image(PROD_FW_IMAGE_LOCATION_ADDR)) { puts("OK"); spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES-1, (void *)RAM_BASE); start_program(RAM_BASE); } else { puts("NOK"); } } */ else if(!strncmp(buf, "!RUNPFPGA", 8)) { if(is_valid_fpga_image(PROD_FPGA_IMAGE_LOCATION_ADDR)) { puts("OK"); //icap_reload_fpga(PROD_FPGA_IMAGE_LOCATION_ADDR); } else { puts("NOK"); } } else if(!strncmp(buf, "!RUNSFPGA", 8)) { if(is_valid_fpga_image(SAFE_FPGA_IMAGE_LOCATION_ADDR)) { puts("OK"); //icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR); } else { puts("NOK"); } } else if(!strncmp(buf, "!READ", 5)) { uint32_t addr = atol(&buf[5]); spi_flash_read(addr, 16, ihx); for(i=0; i < 16; i++) { puthex8(ihx[i]); } putstr("\n"); } else if(!ihex_parse(buf, &ihex_record)) { //last, try to see if the input was a valid IHEX line switch (ihex_record.type) { case 0: spi_flash_program(ihex_record.addr + slot_offset + extended_addr, ihex_record.length, ihex_record.data); puts("OK"); break; case 1: //here we would expect a CRC checking or something else to take place. for now we do nothing. //well, we set the extended segment addr back to 0 extended_addr = 0; puts("DONE"); break; case 4: //set the upper 16 bits of the address extended_addr = ((ihex_record.data[0] << 8) + ihex_record.data[1]) << 16; puts("OK"); break; default: puts("NOK"); } } else puts("NOK"); } //while(1) }
/******************************************************************************* Reset environment variables. ********************************************************************************/ int resetenv_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #if defined(CONFIG_ENV_IS_IN_FLASH ) ulong stop_addr; ulong start_addr; #endif #if defined(CONFIG_ENV_IS_IN_NAND) size_t offset = 0; nand_info_t *nand = &nand_info[0]; int sum = 0; #if defined(CONFIG_SKIP_BAD_BLOCK) int i = 0; size_t blocksize; blocksize = nand_info[0].erasesize; while(i * blocksize < nand_info[0].size) { if (!nand_block_isbad(&nand_info[0], (i * blocksize))) sum += blocksize; else { sum = 0; offset = (i + 1) * blocksize; } if (sum >= CONFIG_UBOOT_SIZE) break; i++; } #else offset = CONFIG_ENV_OFFSET; #endif printf("Erasing 0x%x - 0x%x:",CONFIG_UBOOT_SIZE + offset, CONFIG_ENV_RANGE_NAND); nand_erase(nand, CONFIG_UBOOT_SIZE + offset, CONFIG_ENV_RANGE_NAND); puts ("[Done]\n"); #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) u32 sector = 1; if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } #ifdef CONFIG_SPI_FLASH_PROTECTION printf("Unprotecting flash:"); spi_flash_protect(flash, 0); printf("\t\t[Done]\n"); #endif printf("Erasing 0x%x - 0x%x:",CONFIG_ENV_OFFSET, CONFIG_ENV_OFFSET + sector * CONFIG_ENV_SECT_SIZE); if(!flash) { flash = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!flash) { printf("Failed to probe SPI Flash\n"); set_default_env("!spi_flash_probe() failed"); return 0; } } if (spi_flash_erase(flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE)) return 1; puts("\t[Done]\n"); #ifdef CONFIG_SPI_FLASH_PROTECTION printf("Protecting flash:"); spi_flash_protect(flash, 1); printf("\t\t[Done]\n"); #endif #elif defined(CONFIG_ENV_IS_IN_FLASH ) start_addr = CONFIG_ENV_ADDR; stop_addr = start_addr + CONFIG_ENV_SIZE - 1; printf("Erasing sector 0x%x:",CONFIG_ENV_OFFSET); flash_sect_protect (0, start_addr, stop_addr); flash_sect_erase (start_addr, stop_addr); flash_sect_protect (1, start_addr, stop_addr); printf("\t[Done]\n"); #endif printf("Warning: Default Environment Variables will take effect Only after RESET\n"); return 0; }
T_U32 Sflash_BurnWritePage(T_U8* buf, T_U32 startPage, T_U32 PageCnt) { #if 0 T_U32 i; T_U32 write_block_index; write_block_index = (startPage + PageCnt) / gSPIFlash_base.erase_size; if (m_download_sflash.EraseBlocks <= write_block_index) { for (i=m_download_sflash.EraseBlocks; i<=write_block_index; i++) { gpf.fDriver.Printf("PR_S erase:%d\r\n", i); if (!spi_flash_erase(i * (gSPIFlash_base.erase_size / gSPIFlash_base.page_size))) { gpf.fDriver.Printf("PR_S erase fail at block:%d\r\n", i); return AK_FALSE; } } m_download_sflash.EraseBlocks = write_block_index + 1; } if(!spi_flash_write(startPage, buf, PageCnt)) { gpf.fDriver.Printf("PR_S write fail at page:%d\r\n", startPage); return AK_FALSE; } return AK_TRUE; #endif T_U32 i; T_U32 write_block_index; write_block_index = (startPage + PageCnt) * gSPIFlash_base.page_size / gSPIFlash_base.erase_size; if (m_download_sflash.EraseBlocks <= write_block_index) { for (i=m_download_sflash.EraseBlocks; i<=write_block_index; i++) { gpf.fDriver.Printf("PR_S erase:%d\r\n", i); if (!Fwl_spiflash_erase(i)) { gpf.fDriver.Printf("PR_S erase fail at block:%d\r\n", i); return AK_FALSE; } } m_download_sflash.EraseBlocks = write_block_index + 1; } if(!Fwl_spiflash_write(startPage, buf, PageCnt)) { gpf.fDriver.Printf("PR_S write fail at page:%d\r\n", startPage); return AK_FALSE; } return AK_TRUE; }
void test_spi_flash(void) { struct spi_slave spi; struct spi_flash flash; unsigned int addr, i; int ret; /* We use a 512 byte buf for verifications below because of limited RAM */ uint8_t buf[512]; ptest(); /* Enable PIO0.2 for CS */ LPC_GPIO0->DIR |= (1<<2); /* Configure SPI */ spi.master = &SPI0; spi.speed = 24000000; spi.mode = 0; spi.cs_pin = 2; spi.cs_active_high = false; debug_printf(STR_TAB "Press enter to start SPI flash test...\n"); uart_getc(); uart_putc('\n'); /* Probe for the flash */ debug_printf(STR_TAB "Probing for SPI flash chip...\n"); passert(spi_flash_probe(&flash, &spi) == 0); pokay("Found SPI flash!"); pokay(" JEDEC ID: 0x%08x", flash.params->jedec_id); pokay(" Name: %s", flash.params->name); pokay(" Sector Size: %d", flash.params->sector_size); pokay(" Capacity: %d", flash.params->capacity); pokay(" Flags: %04x", flash.params->flags); debug_printf(STR_TAB "Testing invalid argument checks of SPI flash functions\n"); /* Make sure not sector size mod address and length fail */ passert(spi_flash_erase(&flash, 0x5, 4096) == SPI_FLASH_ERROR_ARGS); passert(spi_flash_erase(&flash, 0, 4095) == SPI_FLASH_ERROR_ARGS); /* Make sure program out of bounds fails */ passert(spi_flash_write(&flash, 0x3, NULL, flash.params->capacity) == SPI_FLASH_ERROR_ARGS); /* Erase two sectors */ debug_printf(STR_TAB "Erasing lower two sectors...\n"); passert(spi_flash_erase(&flash, 0x0, 4096*2) == 0); /* Verify they are all 0xff */ debug_printf(STR_TAB "Verifying lower two sectors are blank...\n"); for (addr = 0; addr < 4096*2; addr += sizeof(buf)) { if ((ret = spi_flash_read(&flash, addr, buf, sizeof(buf))) != 0) { pfail("Error with spi_flash_read(): %d", ret); passert(false); } for (i = 0; i < sizeof(buf); i++) { if (buf[i] != 0xff) { pfail("Memory is not blank at address 0x%06x! got 0x%02x", addr+i, buf[i]); passert(false); } } } pokay("Lower two sectors are blank"); debug_printf(STR_TAB "Starting write/read/verify test vector tests...\n"); /* Write test vector 1 to 0x003 - 0x04e inclusive (75 bytes) */ passert(spi_flash_write(&flash, 0x03, test_sf_vector1, sizeof(test_sf_vector1)) == 0); pokay("Wrote test vector 1 to 0x003-0x04e"); /* Verify test vector 1 data from 0x000 - 0x0ff */ passert(spi_flash_read(&flash, 0x0, buf, sizeof(buf)) == 0); passert(memcmp(buf, test_sf_vector_blank, 3) == 0); passert(memcmp(buf+3, test_sf_vector1, sizeof(test_sf_vector1)) == 0); passert(memcmp(buf+3+sizeof(test_sf_vector1), test_sf_vector_blank, 0x100-3-sizeof(test_sf_vector1)) == 0); pokay("Read test vector 1 verified 0x000-0x0ff"); /* Write test vector 2 to 0x100 - 0x1ff inclusive (1 page == 256 bytes) */ passert(spi_flash_write(&flash, 0x100, test_sf_vector2, sizeof(test_sf_vector2)) == 0); pokay("Wrote test vector 2 to 0x100-0x1ff"); /* Verify test vector 1 again */ debug_printf(STR_TAB "Verifying test vector 1 again\n"); passert(spi_flash_read(&flash, 0x0, buf, sizeof(buf)) == 0); passert(memcmp(buf, test_sf_vector_blank, 3) == 0); passert(memcmp(buf+3, test_sf_vector1, sizeof(test_sf_vector1)) == 0); passert(memcmp(buf+3+sizeof(test_sf_vector1), test_sf_vector_blank, 0x100-3-sizeof(test_sf_vector1)) == 0); pokay("Read test vector 1 verified 0x000-0x0ff"); /* Verify test vector 2 */ passert(spi_flash_read(&flash, 0x100, buf, sizeof(buf)) == 0); passert(memcmp(buf, test_sf_vector2, sizeof(test_sf_vector2)) == 0); pokay("Read test vector 2 verified 0x100-0x1ff"); /* Write test vector 3 to 0x200 - 0x301 inclusive (1 page, 1 byte == 257 bytes) */ passert(spi_flash_write(&flash, 0x200, test_sf_vector3, sizeof(test_sf_vector3)) == 0); pokay("Wrote test vector 3 to 0x200-0x301"); /* Verify test vector 3 */ passert(spi_flash_read(&flash, 0x200, buf, sizeof(buf)) == 0); passert(memcmp(buf, test_sf_vector3, sizeof(test_sf_vector3)) == 0); passert(memcmp(buf+sizeof(test_sf_vector3), test_sf_vector_blank, 0x100-1) == 0); pokay("Read test vector 3 verified 0x200-0x3ff"); /* Write test vector 4 to 0x37f - 0x5ff inclusive (2.5 pages == 640 bytes) */ passert(spi_flash_write(&flash, 0x37f, test_sf_vector4, sizeof(test_sf_vector4)) == 0); pokay("Wrote test vector 4 to 0x37f-0x5ff"); /* Verify test vector 4 */ /* First 512 bytes */ passert(spi_flash_read(&flash, 0x37f, buf, sizeof(buf)) == 0); passert(memcmp(buf, test_sf_vector4, 512) == 0); /* Last 128 bytes (and 384 blank bytes) */ passert(spi_flash_read(&flash, 0x37f+512, buf, sizeof(buf)) == 0); passert(memcmp(buf, test_sf_vector4+512, 128) == 0); passert(memcmp(buf+128, test_sf_vector_blank, 384) == 0); pokay("Read test vector 4 verified 0x37f-0x5ff"); debug_printf(STR_TAB "Erasing entire chip... Press enter to continue."); uart_getc(); uart_putc('\n'); /* Erase chip */ passert(spi_flash_erase(&flash, 0x0, flash.params->capacity) == 0); /* Verify lower 256kB is blank */ debug_printf(STR_TAB "Verifying lower 256kB is blank...\n"); for (addr = 0; addr < 256*1024; addr += sizeof(buf)) { if ((ret = spi_flash_read(&flash, addr, buf, sizeof(buf))) != 0) { pfail("Error with spi_flash_read(): %d", ret); passert(false); } for (i = 0; i < sizeof(buf); i++) { if (buf[i] != 0xff) { pfail("Memory is not blank at address 0x%06x! got 0x%02x", addr+i, buf[i]); passert(false); } } } pokay("Lower 256kB is blank"); debug_printf(STR_TAB "Starting pseudorandom data test... Press enter to continue."); uart_getc(); uart_putc('\n'); /* Write 256kB pseudorandom data */ debug_printf(STR_TAB "Writing 256kB pseudorandom data\n"); srand(0xdeadbeef); for (addr = 0; addr < 256*1024; addr += sizeof(buf)) { for (i = 0; i < sizeof(buf); i++) buf[i] = rand(); if (spi_flash_write(&flash, addr, buf, sizeof(buf)) != 0) { pfail("Error with spi_flash_write(): %d", ret); passert(false); } } pokay("Wrote 256kB pseudorandom data"); /* Verify 256kB pseudorandom data */ debug_printf(STR_TAB "Verifying 256kB pseudorandom data\n"); srand(0xdeadbeef); for (addr = 0; addr < 256*1024; addr += sizeof(buf)) { if ((ret = spi_flash_read(&flash, addr, buf, sizeof(buf))) != 0) { pfail("Error with spi_flash_read(): %d", ret); passert(false); } for (i = 0; i < sizeof(buf); i++) { uint8_t x = rand(); if (buf[i] != x) { pfail("Pseudorandom data mismatch at address 0x%06x! expected 0x%02x, got 0x%02x", addr+i, x, buf[i]); passert(false); } } } pokay("Pseudorandom data matches!"); }
int saveenv(void) { u32 saved_size, saved_offset, sector = 1; char *saved_buffer = NULL; int ret = 1; env_t env_new; #ifdef CONFIG_DM_SPI_FLASH struct udevice *new; /* speed and mode will be read from DT */ ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, 0, 0, &new); if (ret) { set_default_env("!spi_flash_probe_bus_cs() failed"); return 1; } env_flash = dev_get_uclass_priv(new); #else if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } #endif /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) goto done; ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } ret = env_export(&env_new); if (ret) goto done; puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = 0; puts("done\n"); done: if (saved_buffer) free(saved_buffer); return ret; }
void save_flash(int flash_address, char buffer[MAX_DEVICES][MAX_LENGTH], u8 max_lines, u8 spi_wp_toggle) { int i = 0; int k = 0; int j, ret; char cbfs_formatted_list[MAX_DEVICES * MAX_LENGTH]; u32 nvram_pos; // compact the table into the expected packed list for (j = 0; j < max_lines; j++) { for (k = 0; k < MAX_LENGTH; k++) { cbfs_formatted_list[i++] = buffer[j][k]; if (buffer[j][k] == NEWLINE ) break; } } cbfs_formatted_list[i++] = NUL; // try to unlock the flash if it is locked if (spi_flash_is_locked(flash_device)) { spi_flash_unlock(flash_device); if (spi_flash_is_locked(flash_device)) { printf("Flash is write protected. Exiting...\n"); return; } } printf("Erasing Flash size 0x%x @ 0x%x\n", FLASH_SIZE_CHUNK, flash_address); ret = spi_flash_erase(flash_device, flash_address, FLASH_SIZE_CHUNK); if (ret) { printf("Erase failed, ret: %d\n", ret); return; } printf("Writing %d bytes @ 0x%x\n", i, flash_address); // write first 512 bytes for (nvram_pos = 0; nvram_pos < (i & 0xFFFC); nvram_pos += 4) { ret = spi_flash_write(flash_device, nvram_pos + flash_address, sizeof(u32), (u32 *)(cbfs_formatted_list + nvram_pos)); if (ret) { printf("Write failed, ret: %d\n", ret); return; } } // write remaining filler characters in one run ret = spi_flash_write(flash_device, nvram_pos + flash_address, sizeof(i % 4), (u32 *)(cbfs_formatted_list + nvram_pos)); if (ret) { printf("Write failed, ret: %d\n", ret); return; } if (spi_wp_toggle) { printf("Enabling flash write protect...\n"); spi_flash_lock(flash_device); } spi_wp_toggle = spi_flash_is_locked(flash_device); printf("Done\n"); }
/* * Warn: Do NOT modify the printf string, it may be used by pc tools. * offset should be alignment with spi flash block size * length should be alignment with spi flash block size */ long long spiflash_logic_erase(spiflash_logic_t *spiflash_logic, unsigned long long offset, unsigned long long length) { unsigned long blocksize, eraseoffset, eraselen; unsigned long long totalerase = 0; unsigned long long request_length = length; if (!length) { printf("Attempt to erase 0 Bytes!\n"); return -1; } /* Reject write, which are not block aligned */ if ((offset & (spiflash_logic->erasesize - 1)) || (length & (spiflash_logic->erasesize - 1))) { printf("Attempt to erase non block aligned, " "spi flash blocksize: 0x%08llx, offset: 0x%08llx," " length: 0x%08llx\n", spiflash_logic->erasesize, offset, length); return -1; } if (offset > spiflash_logic->length) { printf("Attempt to erase from outside the flash handle area, " "flash handle size: 0x%08llx, offset: 0x%08llx\n", spiflash_logic->length, offset); return -1; } if ((offset + length) > spiflash_logic->length) { length = spiflash_logic->length - offset; printf("Erase length is too large, " "paratition size: 0x%08llx, erase offset: 0x%08llx\n" "Try to erase 0x%08llx instead!\n", spiflash_logic->length, offset, length); } blocksize = spiflash_logic->erasesize; eraselen = length; eraseoffset = spiflash_logic->address + offset; /* eraselen MUST align with blocksize here */ while (eraselen > 0) { int ret; printf("\rErasing at 0x%lx\n", eraseoffset); ret = spi_flash_erase(spiflash_logic->spiflash, eraseoffset, blocksize); if (ret) { printf("\nSPI Flash Erasing at 0x%lx failed\n", eraseoffset); return -1; } eraselen -= blocksize; eraseoffset += blocksize; totalerase += blocksize; } if (totalerase < request_length) printf("request to erase 0x%08llx, and erase 0x%08llx" " successfully!\n", request_length, totalerase); return (long long)totalerase; }
int saveenv(void) { env_t env_new; char *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; int ret; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } ret = env_export(&env_new); if (ret) return ret; env_new.flags = ACTIVE_FLAG; if (gd->env_valid == 1) { env_new_offset = CONFIG_ENV_OFFSET_REDUND; env_offset = CONFIG_ENV_OFFSET; } else { env_new_offset = CONFIG_ENV_OFFSET; env_offset = CONFIG_ENV_OFFSET_REDUND; } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = env_new_offset + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) { ret = 1; goto done; } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } printf("Erasing %d bytes on SPI flash at %08x\n", sector * CONFIG_ENV_SECT_SIZE, env_new_offset); ret = spi_flash_erase(env_flash, env_new_offset, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_new_offset, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags), sizeof(env_new.flags), &flag); if (ret) goto done; puts("done\n"); gd->env_valid = gd->env_valid == 2 ? 1 : 2; printf("Valid environment: %d\n", (int)gd->env_valid); done: if (saved_buffer) free(saved_buffer); return ret; }
int saveenv(void) { u32 saved_size, saved_offset, sector = 1; char *saved_buffer = NULL; int ret = 1; env_t env_new; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) goto done; ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } ret = env_export(&env_new); if (ret) goto done; printf("Erasing %d bytes on SPI flash at %08x\n", sector * CONFIG_ENV_SECT_SIZE, CONFIG_ENV_OFFSET); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = 0; puts("done\n"); done: if (saved_buffer) free(saved_buffer); return ret; }
int saveenv(void) { u32 saved_size, saved_offset, sector = 1; char *res, *saved_buffer = NULL; int ret = 1; env_t env_new; ssize_t len; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) goto done; ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); goto done; } env_new.crc = crc32(0, env_new.data, ENV_SIZE); puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = 0; puts("done\n"); done: if (saved_buffer) free(saved_buffer); return ret; }
int saveenv(void) { env_t env_new; ssize_t len; char *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; int ret; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } env_new.crc = crc32(0, env_new.data, ENV_SIZE); env_new.flags = ACTIVE_FLAG; if (gd->env_valid == 1) { env_new_offset = CONFIG_ENV_OFFSET_REDUND; env_offset = CONFIG_ENV_OFFSET; } else { env_new_offset = CONFIG_ENV_OFFSET; env_offset = CONFIG_ENV_OFFSET_REDUND; } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = env_new_offset + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); if (!saved_buffer) { ret = 1; goto done; } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, env_new_offset, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_new_offset, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags), sizeof(env_new.flags), &flag); if (ret) goto done; puts("done\n"); gd->env_valid = gd->env_valid == 2 ? 1 : 2; printf("Valid environment: %d\n", (int)gd->env_valid); done: if (saved_buffer) free(saved_buffer); return ret; }
void set_env_funcptrs(void) { #ifdef CONFIG_SOC_HAYDN env_init = serialflash_env_init ; saveenv = serialflash_saveenv ; env_get_char_spec = serialflash_env_get_char_spec ; env_relocate_spec = serialflash_env_relocate_spec ; #elif (defined(CONFIG_SOC_MOZART) || defined(CONFIG_SOC_BEETHOVEN)) unsigned long val = inl(BOOTING_DEVICE_INFO); int sdbootSucess = 0 ; #ifdef CONFIG_CMD_MMC if(val == SYSCTRL_DATA_IN_SD && SD_Card_Detect(0)) { printf( " Boot Storage : SD Card\n" ) ; gd->env_valid = 0 ;//We always use default envs when booting from SD. env_init = sd_env_init ; saveenv = sd_saveenv ; env_get_char_spec = sd_env_get_char_spec ; env_relocate_spec = sd_env_relocate_spec ; //check if real sd boot if(SD_Read(MAGIC_SD_ADDR, MAGIC_DATA_SIZE, MAGIC_DRAM_ADDR) != 0) { printf("[ERR] SD-Read fails!\n") ; sdbootSucess = 0 ; goto SDBOOT_FAIL; } if((v_inl(MAGIC_DRAM_ADDR) != MAGIC_NUM0) || (v_inl(MAGIC_DRAM_ADDR+4) != MAGIC_NUM1)) { printf(" !! MAGIC# of SD Card is wrong\n") ; printf(" !! Find other Boot Storage..\n\n") ; sdbootSucess = 0 ; goto SDBOOT_FAIL ; } printf(" SD Card has correct Magic#.\n") ; printf(" SD Boot Sucessfully.\n\n") ; update_default_envs_ifsdboot() ; sdbootSucess = 1 ; #ifdef SDAUTOBURN_FLOW_FROMSD printf(" ****** Auto Burn Flow ******\n") ; printf(" Step 1. Copy data(size 0x%08x) from 0x%08x of SD to 0x%08x of DRAM\n", AUTOBURN_DATASIZE, AUTOBURN_SDADDR, AUTOBURN_DRAMADDR) ; SD_Read(AUTOBURN_SDADDR, AUTOBURN_DATASIZE, AUTOBURN_DRAMADDR) ; if(AUTOBURN_FLASHTYPE == AUTOBURN_SPIFLASH) { printf(" Step 2. Write data from 0x%08x of DRAM to 0x%08x of SPI FLASH\n", AUTOBURN_DRAMADDR, AUTOBURN_FLASHADDR) ; autoburn_sf = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, CONFIG_DEFAULT_SPI_MODE); spi_flash_erase(autoburn_sf, AUTOBURN_FLASHADDR, AUTOBURN_DATASIZE, 0) ; spi_flash_write(autoburn_sf, AUTOBURN_FLASHADDR, AUTOBURN_DATASIZE, AUTOBURN_DRAMADDR, 0) ; printf(" Done\n") ; outl(0xFFF, 0x49000004); } else if(AUTOBURN_FLASHTYPE == AUTOBURN_NANDFLASH) { printf(" Step 3. Write data from 0x%08x of DRAM to 0x%08x of NAND FLASH\n", AUTOBURN_DRAMADDR, AUTOBURN_FLASHADDR) ; nand_info_t *mtd ; mtd = &nand_info[0] ; nand_erase_options_t opts; memset(&opts, 0, sizeof(opts)); opts.offset = AUTOBURN_FLASHADDR; opts.length = AUTOBURN_DATASIZE; //opts.jffs2 = clean; opts.jffs2 = 0;//[patch] we do not allow jffs2 in our u-boot opts.quiet = 0; opts.all = 1 ; unsigned long datasize = AUTOBURN_DATASIZE ; nand_erase_opts(mtd, &opts) ; //printf("chipsize=%d, blocksize=%d, block#=%d\n", mtd->totalsize, mtd->erasesize, (mtd->totalsize / mtd->erasesize)) ; nand_write_skip_bad(mtd, AUTOBURN_FLASHADDR, &datasize, AUTOBURN_DRAMADDR) ;//100 temporary } #endif //SDAUTOBURN_FLOW_FROMSD } if(sdbootSucess) return ; #endif //CONFIG_CMD_SD SDBOOT_FAIL: if ( val == SYSCTRL_DATA_IN_SERIALFLASH) { printf( " Boot Storage : Serial Flash\n" ) ; env_init = serialflash_env_init ; saveenv = serialflash_saveenv ; env_get_char_spec = serialflash_env_get_char_spec ; env_relocate_spec = serialflash_env_relocate_spec ; } #if defined(CONFIG_CMD_NAND) else if ( val == SYSCTRL_DATA_IN_NANDFLASH) { update_default_envs_ifnfboot() ; printf( " Boot Storage : Nand Flash\n" ) ; env_init = nand_env_init ; saveenv = nand_saveenv ; env_get_char_spec = nand_env_get_char_spec ; env_relocate_spec = nand_env_relocate_spec ; } #endif #endif //CONFIG_SOC_MOZART }
int saveenv(void) { env_t env_new; char *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; int ret; #ifdef CONFIG_DM_SPI_FLASH struct udevice *new; /* speed and mode will be read from DT */ ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, 0, 0, &new); if (ret) { set_default_env("!spi_flash_probe_bus_cs() failed"); return 1; } env_flash = dev_get_uclass_priv(new); #else if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } #endif ret = env_export(&env_new); if (ret) return ret; env_new.flags = ACTIVE_FLAG; if (gd->env_valid == 1) { env_new_offset = CONFIG_ENV_OFFSET_REDUND; env_offset = CONFIG_ENV_OFFSET; } else { env_new_offset = CONFIG_ENV_OFFSET; env_offset = CONFIG_ENV_OFFSET_REDUND; } /* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = env_new_offset + CONFIG_ENV_SIZE; saved_buffer = memalign(ARCH_DMA_MINALIGN, saved_size); if (!saved_buffer) { ret = 1; goto done; } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, env_new_offset, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_new_offset, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags), sizeof(env_new.flags), &flag); if (ret) goto done; puts("done\n"); gd->env_valid = gd->env_valid == 2 ? 1 : 2; printf("Valid environment: %d\n", (int)gd->env_valid); done: if (saved_buffer) free(saved_buffer); return ret; }
/** * Update a SPI bootloader * * @param image_addr Address bootloader image is located in RAM * @param image_size Size of image, required for stage 1 bootloader * @param failsafe True if image is failsafe stage 3 bootloader * @param stage1 True if image is stage 1 bootloader * * @return 0 on success * 1 on failure */ int do_bootloader_update_spi(uint32_t image_addr, size_t image_size, bool failsafe, bool stage1) { struct bootloader_header search_header; struct bootloader_map image_map[10]; int images[4] = {-1, -1, -1, -1}; /* 2 stage 2 and 2 stage 3 */ const struct bootloader_header *header; uint8_t *buffer; struct spi_flash *sf = NULL; uint32_t offset = stage1 ? 0 : CONFIG_OCTEON_SPI_STAGE2_START; uint32_t erase_size; uint32_t size; uint32_t start = -1, end = -1; int rc; int image_index = 0; int num_images = 0; int num_stage2 = 0; int i; bool is_stage2 = false; bool update_index = false; memset(image_map, 0, sizeof(image_map)); if (!image_addr) image_addr = getenv_ulong("fileaddr", 16, 0); if (!image_addr) image_addr = getenv_ulong("loadaddr", 16, load_addr); sf = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, SPI_MODE_0); if (!sf) { puts("SPI flash not found\n"); goto error; } debug("size: %u bytes, erase block size: %u bytes\n", sf->size, sf->erase_size); if (sf->size < CONFIG_OCTEON_SPI_BOOT_END) { printf("Error: Bootloader section end offset 0x%x is greater than the size of the SPI flash (0x%x)\n", CONFIG_OCTEON_SPI_BOOT_END, sf->size); goto error; } erase_size = (image_size + sf->erase_size - 1) & ~(sf->erase_size - 1); buffer = CASTPTR(uint8_t, image_addr); if (stage1) { debug("Updating stage 1 bootloader\n"); rc = spi_flash_erase(sf, 0, erase_size); if (rc) { puts("Error erasing SPI flash\n"); goto error; } puts("Writing stage 1 SPI bootloader to offset 0.\n"); rc = spi_flash_write(sf, 0, image_size, buffer); if (rc) { puts("Error writing stage 1 bootloader to SPI flash\n"); goto error; } printf("Successfully wrote %zu bytes.\n", image_size); return 0; } header = CASTPTR(struct bootloader_header, image_addr); is_stage2 = header->image_type == BL_HEADER_IMAGE_STAGE2; printf("%s %u byte bootloader found at address 0x%x\n", is_stage2 ? "Stage 2" : "Final stage", image_size, image_addr); /* Search for U-Boot image */ do { /* debug("Looking for bootloader at offset 0x%x\n", offset);*/ rc = spi_flash_read(sf, offset, sizeof(search_header), &search_header); if (rc) { printf("Error reading offset %u of SPI flash\n", offset); goto error; } if (!validate_header(&search_header)) { debug("Found valid %u byte stage %d header at offset 0x%x\n", search_header.hlen + search_header.dlen, search_header.image_type == BL_HEADER_IMAGE_STAGE2 ? 2 : 3, offset); if (update_index) image_index++; update_index = false; size = search_header.hlen + search_header.dlen; debug("Validating bootloader at 0x%x, size: %zu\n", offset, size); if (size > (2 << 20)) { rc = 1; puts("Invalid bootloader image size exceeds 2MB\n"); } else { rc = validate_spi_bootloader(sf, offset, size); } if (rc < 0) { debug("Error reading bootloader from SPI\n"); goto error; } else if (rc == 0) { debug("Found valid bootloader\n"); image_map[image_index].size = (size + erase_size - 1) & ~erase_size; image_map[image_index].free_space = false; image_map[image_index].type = search_header.image_type; } else { debug("Found invalid bootloader\n"); /* Calculate free size based on invalid * bootloader size. */ image_map[image_index].image_size = size; /* Including padding for erase block size */ image_map[image_index].size = (size + sf->erase_size - 1) & ~(sf->erase_size - 1); image_map[image_index].free_space = true; image_map[image_index].type = BL_HEADER_IMAGE_UNKNOWN; } image_map[image_index].offset = offset; offset += size + sf->erase_size - 1; offset &= ~(sf->erase_size - 1); image_index++; } else { update_index = true; /* debug("No header at offset 0x%x\n", offset); */ if (!image_map[image_index].size) { image_map[image_index].offset = offset; image_map[image_index].free_space = true; } image_map[image_index].size += sf->erase_size; offset += sf->erase_size; } } while (offset < CONFIG_OCTEON_SPI_BOOT_END && image_index < 10); if (update_index) image_index++; for (i = 0, num_images = 0; i < image_index && num_images < 4; i++) if (!image_map[i].free_space) { images[num_images++] = i; if (image_map[i].type == BL_HEADER_IMAGE_STAGE2) num_stage2++; } #ifdef DEBUG debug("Image map:\n"); for (i = 0; i < image_index; i++) printf("%d: offset: 0x%x, image size: %#x, size: 0x%x, type: %d, free: %s\n", i, image_map[i].offset, image_map[i].image_size, image_map[i].size, image_map[i].type, image_map[i].free_space ? "yes" : "no"); #endif if (is_stage2) { #ifdef CONFIG_OCTEON_NO_FAILSAFE /* If there's no failsafe then we just overwrite the * first bootloader by pretending it is a failsafe. */ failsafe = 1; #endif if (failsafe || num_images == 0 || num_stage2 < 2) { i = images[0]; if (i < 0) i = 0; if (image_map[i].type != BL_HEADER_IMAGE_STAGE2 && image_map[i].type != BL_HEADER_IMAGE_UNKNOWN && !image_map[i].free_space) { puts("Warning: no stage 2 bootloader found,\n" "overwriting existing non-stage 2 bootloader image.\n"); } if (i > 0 && image_map[i - 1].free_space) start = image_map[i - 1].offset; else start = image_map[i].offset; if ((i + 1) < image_index && image_map[i + 1].free_space) end = image_map[i + 1].offset + image_map[i + 1].size; else end = image_map[i].offset + image_map[i].size; size = end - start; if (image_size > size) puts("Warning: new failsafe stage 2 image overwrites old non-failsafe stage 2 image.\n" "Please update non-failsafe stage 2 bootloader next.\n"); } else { if (num_stage2 > 0) { i = images[1]; if (i < 0) i = 1; } else { i = images[0]; } start = image_map[i].offset; end = start + image_map[i].size; debug("New stage 2 image map %d start: 0x%x, end: 0x%x\n", i, start, end); } } else { debug("Non-stage 2 bootloader\n"); i = num_stage2; if (!failsafe && num_images > num_stage2) i++; if (images[i] < 0) i = images[i - 1] + 1; else if (image_map[i].size < erase_size && !image_map[i + 1].free_space) printf("Warning: overwriting image following this image at offset 0x%x\n", image_map[i + 1].offset); start = image_map[i].offset; end = start + image_map[i].size; debug("New final stage bootloader image map %d start: 0x%x, end: 0x%x\n", i, start, end); } if (end < 0 || start < 0) { printf("Error detected, start or end is negative\n"); goto error; } if (end - start < erase_size) { printf("Not enough space available, need %u bytes but only %u are available\n", image_size, end - start); } printf("Erasing %u bytes starting at offset 0x%x, please wait...\n", erase_size, start); rc = spi_flash_erase(sf, start, erase_size); if (rc) { printf("Error erasing %u bytes starting at offset 0x%x\n", erase_size, start); goto error; } printf("Writing %u bytes...\n", image_size); rc = spi_flash_write(sf, start, image_size, header); if (rc) { printf("Error writing %u bytes starting at offset 0x%x\n", image_size, start); goto error; } printf("Done.\n%u bytes were written starting at offset 0x%x\n", image_size, start); if (sf) free(sf); return 0; error: if (sf) free(sf); return 1; }
/******************************************************************************* Reset environment variables. ********************************************************************************/ int resetenv_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #if defined(CONFIG_ENV_IS_IN_FLASH ) ulong stop_addr; ulong start_addr; #elif defined(CONFIG_ENV_IS_IN_MMC) lbaint_t start_lba; lbaint_t blk_count; ulong blk_erased; ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); struct mmc *mmc; int err; #endif #if defined(CONFIG_ENV_IS_IN_NAND) size_t env_offset = CONFIG_ENV_OFFSET; nand_info_t *nand = &nand_info[0]; printf("Erasing 0x%x - 0x%x:",env_offset, env_offset + CONFIG_ENV_RANGE); nand_erase(nand, env_offset, CONFIG_ENV_RANGE); puts ("[Done]\n"); #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) u32 sector = 1; if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } #ifdef CONFIG_SPI_FLASH_PROTECTION printf("Unprotecting flash:"); spi_flash_protect(flash, 0); printf("\t\t[Done]\n"); #endif printf("Erasing 0x%x - 0x%x:",CONFIG_ENV_OFFSET, CONFIG_ENV_OFFSET + sector * CONFIG_ENV_SECT_SIZE); if(!flash) { flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!flash) { printf("Failed to probe SPI Flash\n"); set_default_env("!spi_flash_probe() failed"); return 0; } } if (spi_flash_erase(flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE)) return 1; puts("\t[Done]\n"); #ifdef CONFIG_SPI_FLASH_PROTECTION printf("Protecting flash:"); spi_flash_protect(flash, 1); printf("\t\t[Done]\n"); #endif #elif defined(CONFIG_ENV_IS_IN_FLASH ) start_addr = CONFIG_ENV_ADDR; stop_addr = start_addr + CONFIG_ENV_SIZE - 1; printf("Erasing sector 0x%x:",CONFIG_ENV_OFFSET); flash_sect_protect (0, start_addr, stop_addr); flash_sect_erase (start_addr, stop_addr); flash_sect_protect (1, start_addr, stop_addr); printf("\t[Done]\n"); #elif defined(CONFIG_ENV_IS_IN_MMC) start_lba = CONFIG_ENV_ADDR / CONFIG_ENV_SECT_SIZE; blk_count = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); if (!mmc) { printf("No MMC card found\n"); return 1; } if (mmc_init(mmc)) { printf("MMC(%d) init failed\n", CONFIG_SYS_MMC_ENV_DEV); return 1; } #ifdef CONFIG_SYS_MMC_ENV_PART /* Valid for MMC/eMMC only - switch to ENV partition */ if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) { if (mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, CONFIG_SYS_MMC_ENV_PART)) { printf("MMC partition switch failed\n"); return 1; } } #endif printf("Erasing 0x"LBAF" blocks starting at sector 0x"LBAF" :", blk_count, start_lba); /* For some unknown reason the mmc_berase() fails with timeout if called before any futher write to MMC/SD (for instance, right after u-boot bring up). However the mmc_bwrite() always succeds. Writing zeroes into SD/MMC blocks is similar operation as doing so to IDE/SATA disk and therefore can be used for erasing the imformation stored on the media. blk_erased = mmc_berase(CONFIG_SYS_MMC_ENV_DEV, start_lba, blk_count); */ memset(buf, 0, CONFIG_ENV_SIZE); blk_erased = mmc_bwrite(CONFIG_SYS_MMC_ENV_DEV, start_lba, blk_count, buf); if (blk_erased != blk_count) { printf("\t[FAIL] - erased %#lx blocks\n", blk_erased); err = 1; } else { printf("\t[Done]\n"); err = 0; } #ifdef CONFIG_SYS_MMC_ENV_PART /* Valid for MMC/eMMC only - restore current partition */ if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, mmc->part_num); #endif if (err) return err; #endif printf("Warning: Default Environment Variables will take effect Only after RESET\n"); return 0; }
int saveenv(void) { env_t env_new; ulong env_offset_1, env_offset_2; ssize_t len; char *res; u32 sector = 1; int ret; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { set_default_env("!spi_flash_probe() failed"); return 1; } } res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } env_new.crc = crc32(0, env_new.data, ENV_SIZE); if (gd->env_valid == 2) { env_offset_1 = CONFIG_ENV_OFFSET_REDUND; env_offset_2 = CONFIG_ENV_OFFSET; } else { env_offset_1 = CONFIG_ENV_OFFSET; env_offset_2 = CONFIG_ENV_OFFSET_REDUND; } if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, env_offset_1, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_offset_1, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, env_offset_2, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_offset_2, CONFIG_ENV_SIZE, &env_new); if (ret) goto done; puts("done\n"); gd->env_valid = 1; printf("Valid environment: %d\n", (int)gd->env_valid); done: return ret; }