mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-22 20:58:22 +00:00
Add support for dataflash to U-boot environment settings tool.
* The sector size for SPI-dataflash (like AT45 flashes) are not always a power-of-2. So, the sector calculations are rewritten such that it works for either power-of-2 as any size sectors. * Make the flash sector size optional in case it is the same value as the environment size. Signed-off-by: Remy Bohmer <linux@bohmer.net>
This commit is contained in:
parent
976b38c074
commit
9eeaa8e66c
3 changed files with 56 additions and 28 deletions
60
tools/env/fw_env.c
vendored
60
tools/env/fw_env.c
vendored
|
@ -674,11 +674,7 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,
|
||||||
MEMGETBADBLOCK needs 64 bits */
|
MEMGETBADBLOCK needs 64 bits */
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
blockstart = (offset / DEVESIZE (dev)) * DEVESIZE (dev);
|
||||||
* Start of the first block to be read, relies on the fact, that
|
|
||||||
* erase sector size is always a power of 2
|
|
||||||
*/
|
|
||||||
blockstart = offset & ~(DEVESIZE (dev) - 1);
|
|
||||||
|
|
||||||
/* Offset inside a block */
|
/* Offset inside a block */
|
||||||
block_seek = offset - blockstart;
|
block_seek = offset - blockstart;
|
||||||
|
@ -694,8 +690,8 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,
|
||||||
* To calculate the top of the range, we have to use the
|
* To calculate the top of the range, we have to use the
|
||||||
* global DEVOFFSET (dev), which can be different from offset
|
* global DEVOFFSET (dev), which can be different from offset
|
||||||
*/
|
*/
|
||||||
top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) +
|
top_of_range = ((DEVOFFSET(dev) / blocklen) +
|
||||||
ENVSECTORS (dev) * blocklen;
|
ENVSECTORS (dev)) * blocklen;
|
||||||
|
|
||||||
/* Limit to one block for the first read */
|
/* Limit to one block for the first read */
|
||||||
if (readlen > blocklen - block_seek)
|
if (readlen > blocklen - block_seek)
|
||||||
|
@ -749,9 +745,9 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write count bytes at offset, but stay within ENVSETCORS (dev) sectors of
|
* Write count bytes at offset, but stay within ENVSECTORS (dev) sectors of
|
||||||
* DEVOFFSET (dev). Similar to the read case above, on NOR we erase and write
|
* DEVOFFSET (dev). Similar to the read case above, on NOR and dataflash we
|
||||||
* the whole data at once.
|
* erase and write the whole data at once.
|
||||||
*/
|
*/
|
||||||
static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
||||||
off_t offset, uint8_t mtd_type)
|
off_t offset, uint8_t mtd_type)
|
||||||
|
@ -764,7 +760,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
||||||
size_t erasesize; /* erase / write length - one block on NAND,
|
size_t erasesize; /* erase / write length - one block on NAND,
|
||||||
whole area on NOR */
|
whole area on NOR */
|
||||||
size_t processed = 0; /* progress counter */
|
size_t processed = 0; /* progress counter */
|
||||||
size_t write_total; /* total size to actually write - excludinig
|
size_t write_total; /* total size to actually write - excluding
|
||||||
bad blocks */
|
bad blocks */
|
||||||
off_t erase_offset; /* offset to the first erase block (aligned)
|
off_t erase_offset; /* offset to the first erase block (aligned)
|
||||||
below offset */
|
below offset */
|
||||||
|
@ -777,11 +773,10 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
||||||
|
|
||||||
blocklen = DEVESIZE (dev);
|
blocklen = DEVESIZE (dev);
|
||||||
|
|
||||||
/* Erase sector size is always a power of 2 */
|
top_of_range = ((DEVOFFSET(dev) / blocklen) +
|
||||||
top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) +
|
ENVSECTORS (dev)) * blocklen;
|
||||||
ENVSECTORS (dev) * blocklen;
|
|
||||||
|
|
||||||
erase_offset = offset & ~(blocklen - 1);
|
erase_offset = (offset / blocklen) * blocklen;
|
||||||
|
|
||||||
/* Maximum area we may use */
|
/* Maximum area we may use */
|
||||||
erase_len = top_of_range - erase_offset;
|
erase_len = top_of_range - erase_offset;
|
||||||
|
@ -795,7 +790,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
||||||
* to the start of the data, then count bytes of data, and to the
|
* to the start of the data, then count bytes of data, and to the
|
||||||
* end of the block
|
* end of the block
|
||||||
*/
|
*/
|
||||||
write_total = (block_seek + count + blocklen - 1) & ~(blocklen - 1);
|
write_total = ((block_seek + count + blocklen - 1) /
|
||||||
|
blocklen) * blocklen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support data anywhere within erase sectors: read out the complete
|
* Support data anywhere within erase sectors: read out the complete
|
||||||
|
@ -838,7 +834,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
||||||
|
|
||||||
erase.length = erasesize;
|
erase.length = erasesize;
|
||||||
|
|
||||||
/* This only runs once on NOR flash */
|
/* This only runs once on NOR flash and SPI-dataflash */
|
||||||
while (processed < write_total) {
|
while (processed < write_total) {
|
||||||
rc = flash_bad_block (fd, mtd_type, &blockstart);
|
rc = flash_bad_block (fd, mtd_type, &blockstart);
|
||||||
if (rc < 0) /* block test failed */
|
if (rc < 0) /* block test failed */
|
||||||
|
@ -857,6 +853,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
|
||||||
erase.start = blockstart;
|
erase.start = blockstart;
|
||||||
ioctl (fd, MEMUNLOCK, &erase);
|
ioctl (fd, MEMUNLOCK, &erase);
|
||||||
|
|
||||||
|
/* Dataflash does not need an explicit erase cycle */
|
||||||
|
if (mtd_type != MTD_DATAFLASH)
|
||||||
if (ioctl (fd, MEMERASE, &erase) != 0) {
|
if (ioctl (fd, MEMERASE, &erase) != 0) {
|
||||||
fprintf (stderr, "MTD erase error on %s: %s\n",
|
fprintf (stderr, "MTD erase error on %s: %s\n",
|
||||||
DEVNAME (dev),
|
DEVNAME (dev),
|
||||||
|
@ -973,7 +971,9 @@ static int flash_read (int fd)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) {
|
if (mtdinfo.type != MTD_NORFLASH &&
|
||||||
|
mtdinfo.type != MTD_NANDFLASH &&
|
||||||
|
mtdinfo.type != MTD_DATAFLASH) {
|
||||||
fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type);
|
fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1143,6 +1143,9 @@ int fw_env_open(void)
|
||||||
} else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&
|
} else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&
|
||||||
DEVTYPE(!dev_current) == MTD_NANDFLASH) {
|
DEVTYPE(!dev_current) == MTD_NANDFLASH) {
|
||||||
environment.flag_scheme = FLAG_INCREMENTAL;
|
environment.flag_scheme = FLAG_INCREMENTAL;
|
||||||
|
} else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
|
||||||
|
DEVTYPE(!dev_current) == MTD_DATAFLASH) {
|
||||||
|
environment.flag_scheme = FLAG_BOOLEAN;
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, "Incompatible flash types!\n");
|
fprintf (stderr, "Incompatible flash types!\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1234,14 +1237,29 @@ static int parse_config ()
|
||||||
strcpy (DEVNAME (0), DEVICE1_NAME);
|
strcpy (DEVNAME (0), DEVICE1_NAME);
|
||||||
DEVOFFSET (0) = DEVICE1_OFFSET;
|
DEVOFFSET (0) = DEVICE1_OFFSET;
|
||||||
ENVSIZE (0) = ENV1_SIZE;
|
ENVSIZE (0) = ENV1_SIZE;
|
||||||
|
/* Default values are: erase-size=env-size, #sectors=1 */
|
||||||
|
DEVESIZE (0) = ENVSIZE (0);
|
||||||
|
ENVSECTORS (0) = 1;
|
||||||
|
#ifdef DEVICE1_ESIZE
|
||||||
DEVESIZE (0) = DEVICE1_ESIZE;
|
DEVESIZE (0) = DEVICE1_ESIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef DEVICE1_ENVSECTORS
|
||||||
ENVSECTORS (0) = DEVICE1_ENVSECTORS;
|
ENVSECTORS (0) = DEVICE1_ENVSECTORS;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_REDUND
|
#ifdef HAVE_REDUND
|
||||||
strcpy (DEVNAME (1), DEVICE2_NAME);
|
strcpy (DEVNAME (1), DEVICE2_NAME);
|
||||||
DEVOFFSET (1) = DEVICE2_OFFSET;
|
DEVOFFSET (1) = DEVICE2_OFFSET;
|
||||||
ENVSIZE (1) = ENV2_SIZE;
|
ENVSIZE (1) = ENV2_SIZE;
|
||||||
|
/* Default values are: erase-size=env-size, #sectors=1 */
|
||||||
|
DEVESIZE (1) = ENVSIZE (1);
|
||||||
|
ENVSECTORS (1) = 1;
|
||||||
|
#ifdef DEVICE2_ESIZE
|
||||||
DEVESIZE (1) = DEVICE2_ESIZE;
|
DEVESIZE (1) = DEVICE2_ESIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef DEVICE2_ENVSECTORS
|
||||||
ENVSECTORS (1) = DEVICE2_ENVSECTORS;
|
ENVSECTORS (1) = DEVICE2_ENVSECTORS;
|
||||||
|
#endif
|
||||||
HaveRedundEnv = 1;
|
HaveRedundEnv = 1;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -1285,9 +1303,13 @@ static int get_config (char *fname)
|
||||||
&DEVESIZE (i),
|
&DEVESIZE (i),
|
||||||
&ENVSECTORS (i));
|
&ENVSECTORS (i));
|
||||||
|
|
||||||
if (rc < 4)
|
if (rc < 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (rc < 4)
|
||||||
|
/* Assume the erase size is the same as the env-size */
|
||||||
|
DEVESIZE(i) = ENVSIZE(i);
|
||||||
|
|
||||||
if (rc < 5)
|
if (rc < 5)
|
||||||
/* Default - 1 sector */
|
/* Default - 1 sector */
|
||||||
ENVSECTORS (i) = 1;
|
ENVSECTORS (i) = 1;
|
||||||
|
|
10
tools/env/fw_env.config
vendored
10
tools/env/fw_env.config
vendored
|
@ -1,11 +1,19 @@
|
||||||
# Configuration file for fw_(printenv/saveenv) utility.
|
# Configuration file for fw_(printenv/saveenv) utility.
|
||||||
# Up to two entries are valid, in this case the redundant
|
# Up to two entries are valid, in this case the redundant
|
||||||
# environment sector is assumed present.
|
# environment sector is assumed present.
|
||||||
# Notice, that the "Number of sectors" is ignored on NOR.
|
# Notice, that the "Number of sectors" is ignored on NOR and SPI-dataflash.
|
||||||
|
# Futhermore, if the Flash sector size is ommitted, this value is assumed to
|
||||||
|
# be the same as the Environment size, which is valid for NOR and SPI-dataflash
|
||||||
|
|
||||||
|
# NOR example
|
||||||
# MTD device name Device offset Env. size Flash sector size Number of sectors
|
# MTD device name Device offset Env. size Flash sector size Number of sectors
|
||||||
/dev/mtd1 0x0000 0x4000 0x4000
|
/dev/mtd1 0x0000 0x4000 0x4000
|
||||||
/dev/mtd2 0x0000 0x4000 0x4000
|
/dev/mtd2 0x0000 0x4000 0x4000
|
||||||
|
|
||||||
|
# MTD SPI-dataflash example
|
||||||
|
# MTD device name Device offset Env. size Flash sector size Number of sectors
|
||||||
|
#/dev/mtd5 0x4200 0x4200
|
||||||
|
#/dev/mtd6 0x4200 0x4200
|
||||||
|
|
||||||
# NAND example
|
# NAND example
|
||||||
#/dev/mtd0 0x4000 0x4000 0x20000 2
|
#/dev/mtd0 0x4000 0x4000 0x20000 2
|
||||||
|
|
2
tools/env/fw_env.h
vendored
2
tools/env/fw_env.h
vendored
|
@ -34,10 +34,8 @@
|
||||||
#define DEVICE2_NAME "/dev/mtd2"
|
#define DEVICE2_NAME "/dev/mtd2"
|
||||||
#define DEVICE1_OFFSET 0x0000
|
#define DEVICE1_OFFSET 0x0000
|
||||||
#define ENV1_SIZE 0x4000
|
#define ENV1_SIZE 0x4000
|
||||||
#define DEVICE1_ESIZE 0x4000
|
|
||||||
#define DEVICE2_OFFSET 0x0000
|
#define DEVICE2_OFFSET 0x0000
|
||||||
#define ENV2_SIZE 0x4000
|
#define ENV2_SIZE 0x4000
|
||||||
#define DEVICE2_ESIZE 0x4000
|
|
||||||
|
|
||||||
#define CONFIG_BAUDRATE 115200
|
#define CONFIG_BAUDRATE 115200
|
||||||
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
|
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
|
||||||
|
|
Loading…
Add table
Reference in a new issue