Esempio n. 1
0
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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
File: sf.c Progetto: koenkooi/u-boot
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/**
 * 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;
}
Esempio n. 6
0
/**
 * 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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
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;
}
Esempio n. 12
0
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');
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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)
}
Esempio n. 16
0
/*******************************************************************************
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;
}
Esempio n. 17
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;



}
Esempio n. 18
0
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!");
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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");
}
Esempio n. 21
0
/*
 * 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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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
}
Esempio n. 27
0
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;
}
Esempio n. 28
0
/**
 * 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;
}
Esempio n. 30
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;
}