Merge branch '2021-10-26-add-nand-biterr-and-bugfixes'

- Add biterr sub-command to "nand"
- scmi, rsa, uuid bugfixes, re-sort DFU menu in Kconfig and remove
  superfluous checks before free in env.
This commit is contained in:
Tom Rini
2021-10-26 18:34:55 -04:00
7 changed files with 144 additions and 18 deletions

View File

@@ -17,6 +17,10 @@
* and/or modified under the terms of the GNU General Public License as * and/or modified under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the * published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version. * License, or (at your option) any later version.
*
* The function nand_biterror() in this file is inspired from
* mtd-utils/nand-utils/nandflipbits.c which was released under GPLv2
* only
*/ */
#include <common.h> #include <common.h>
@@ -44,6 +48,116 @@ int find_dev_and_part(const char *id, struct mtd_device **dev,
u8 *part_num, struct part_info **part); u8 *part_num, struct part_info **part);
#endif #endif
#define MAX_NUM_PAGES 64
static int nand_biterror(struct mtd_info *mtd, ulong off, int bit)
{
int ret = 0;
int page = 0;
ulong block_off;
u_char *datbuf[MAX_NUM_PAGES]; /* Data and OOB */
u_char data;
int pages_per_blk = mtd->erasesize / mtd->writesize;
struct erase_info einfo;
if (pages_per_blk > MAX_NUM_PAGES) {
printf("Too many pages in one erase block\n");
return 1;
}
if (bit < 0 || bit > 7) {
printf("bit position 0 to 7 is allowed\n");
return 1;
}
/* Allocate memory */
memset(datbuf, 0, sizeof(datbuf));
for (page = 0; page < pages_per_blk ; page++) {
datbuf[page] = malloc(mtd->writesize + mtd->oobsize);
if (!datbuf[page]) {
printf("No memory for page buffer\n");
ret = -ENOMEM;
goto free_memory;
}
}
/* Align to erase block boundary */
block_off = off & (~(mtd->erasesize - 1));
/* Read out memory as first step */
for (page = 0; page < pages_per_blk ; page++) {
struct mtd_oob_ops ops;
loff_t addr = (loff_t)block_off;
memset(&ops, 0, sizeof(ops));
ops.datbuf = datbuf[page];
ops.oobbuf = datbuf[page] + mtd->writesize;
ops.len = mtd->writesize;
ops.ooblen = mtd->oobsize;
ops.mode = MTD_OPS_RAW;
ret = mtd_read_oob(mtd, addr, &ops);
if (ret < 0) {
printf("Error (%d) reading page %08lx\n",
ret, block_off);
ret = 1;
goto free_memory;
}
block_off += mtd->writesize;
}
/* Erase the block */
memset(&einfo, 0, sizeof(einfo));
einfo.mtd = mtd;
/* Align to erase block boundary */
einfo.addr = (loff_t)(off & (~(mtd->erasesize - 1)));
einfo.len = mtd->erasesize;
ret = mtd_erase(mtd, &einfo);
if (ret < 0) {
printf("Error (%d) nand_erase_nand page %08llx\n",
ret, einfo.addr);
ret = 1;
goto free_memory;
}
/* Twist a bit in data part */
block_off = off & (mtd->erasesize - 1);
data = datbuf[block_off / mtd->writesize][block_off % mtd->writesize];
data ^= (1 << bit);
datbuf[block_off / mtd->writesize][block_off % mtd->writesize] = data;
printf("Flip data at 0x%lx with xor 0x%02x (bit=%d) to value=0x%02x\n",
off, (1 << bit), bit, data);
/* Write back twisted data and unmodified OOB */
/* Align to erase block boundary */
block_off = off & (~(mtd->erasesize - 1));
for (page = 0; page < pages_per_blk; page++) {
struct mtd_oob_ops ops;
loff_t addr = (loff_t)block_off;
memset(&ops, 0, sizeof(ops));
ops.datbuf = datbuf[page];
ops.oobbuf = datbuf[page] + mtd->writesize;
ops.len = mtd->writesize;
ops.ooblen = mtd->oobsize;
ops.mode = MTD_OPS_RAW;
ret = mtd_write_oob(mtd, addr, &ops);
if (ret < 0) {
printf("Error (%d) write page %08lx\n", ret, block_off);
ret = 1;
goto free_memory;
}
block_off += mtd->writesize;
}
free_memory:
for (page = 0; page < pages_per_blk ; page++) {
if (datbuf[page])
free(datbuf[page]);
}
return ret;
}
static int nand_dump(struct mtd_info *mtd, ulong off, int only_oob, static int nand_dump(struct mtd_info *mtd, ulong off, int only_oob,
int repeat) int repeat)
{ {
@@ -733,8 +847,15 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc,
} }
if (strcmp(cmd, "biterr") == 0) { if (strcmp(cmd, "biterr") == 0) {
/* todo */ int bit;
return 1;
if (argc != 4)
goto usage;
off = (int)simple_strtoul(argv[2], NULL, 16);
bit = (int)simple_strtoul(argv[3], NULL, 10);
ret = nand_biterror(mtd, off, bit);
return ret;
} }
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
@@ -825,7 +946,7 @@ static char nand_help_text[] =
"nand scrub [-y] off size | scrub.part partition | scrub.chip\n" "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
" really clean NAND erasing bad blocks (UNSAFE)\n" " really clean NAND erasing bad blocks (UNSAFE)\n"
"nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n" "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
"nand biterr off - make a bit error at offset (UNSAFE)" "nand biterr off bit - make a bit error at offset and bit position (UNSAFE)"
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
"\n" "\n"
"nand lock [tight] [status]\n" "nand lock [tight] [status]\n"

View File

@@ -175,6 +175,13 @@ config SPL_FIT_SIGNATURE_MAX_SIZE
device memory. Assure this size does not extend past expected storage device memory. Assure this size does not extend past expected storage
space. space.
config SPL_FIT_RSASSA_PSS
bool "Support rsassa-pss signature scheme of FIT image contents in SPL"
depends on SPL_FIT_SIGNATURE
help
Enable this to support the pss padding algorithm as described
in the rfc8017 (https://tools.ietf.org/html/rfc8017) in SPL.
config SPL_LOAD_FIT config SPL_LOAD_FIT
bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)" bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
select SPL_FIT select SPL_FIT

View File

@@ -38,6 +38,13 @@ config DFU_MMC
help help
This option enables using DFU to read and write to MMC based storage. This option enables using DFU to read and write to MMC based storage.
config DFU_MTD
bool "MTD back end for DFU"
depends on DM_MTD
depends on CMD_MTDPARTS
help
This option enables using DFU to read and write to on any MTD device.
config DFU_NAND config DFU_NAND
bool "NAND back end for DFU" bool "NAND back end for DFU"
depends on CMD_MTDPARTS depends on CMD_MTDPARTS
@@ -72,13 +79,6 @@ config DFU_SF_PART
This option enables the support of "part" and "partubi" target in This option enables the support of "part" and "partubi" target in
SPI flash DFU back end. SPI flash DFU back end.
config DFU_MTD
bool "MTD back end for DFU"
depends on DM_MTD
depends on CMD_MTDPARTS
help
This option enables using DFU to read and write to on any MTD device.
config DFU_VIRT config DFU_VIRT
bool "VIRTUAL flash back end for DFU" bool "VIRTUAL flash back end for DFU"
help help

6
env/flash.c vendored
View File

@@ -210,8 +210,7 @@ static int env_flash_save(void)
perror: perror:
flash_perror(rc); flash_perror(rc);
done: done:
if (saved_data) free(saved_data);
free(saved_data);
/* try to re-protect */ /* try to re-protect */
flash_sect_protect(1, (ulong)flash_addr, end_addr); flash_sect_protect(1, (ulong)flash_addr, end_addr);
flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new); flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);
@@ -298,8 +297,7 @@ static int env_flash_save(void)
perror: perror:
flash_perror(rc); flash_perror(rc);
done: done:
if (saved_data) free(saved_data);
free(saved_data);
/* try to re-protect */ /* try to re-protect */
flash_sect_protect(1, (long)flash_addr, end_addr); flash_sect_protect(1, (long)flash_addr, end_addr);
return rc; return rc;

View File

@@ -97,14 +97,14 @@ struct scmi_clk_rate_get_out {
/** /**
* struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command
* @clock_id: SCMI clock ID
* @flags: Flags for the clock rate set request * @flags: Flags for the clock rate set request
* @clock_id: SCMI clock ID
* @rate_lsb: 32bit LSB of the clock rate in Hertz * @rate_lsb: 32bit LSB of the clock rate in Hertz
* @rate_msb: 32bit MSB of the clock rate in Hertz * @rate_msb: 32bit MSB of the clock rate in Hertz
*/ */
struct scmi_clk_rate_set_in { struct scmi_clk_rate_set_in {
u32 clock_id;
u32 flags; u32 flags;
u32 clock_id;
u32 rate_lsb; u32 rate_lsb;
u32 rate_msb; u32 rate_msb;
}; };

View File

@@ -340,7 +340,7 @@ static int rsa_verify_key(struct image_sign_info *info,
struct padding_algo *padding = info->padding; struct padding_algo *padding = info->padding;
int hash_len; int hash_len;
if (!prop || !sig || !hash || !checksum) if (!prop || !sig || !hash || !checksum || !padding)
return -EIO; return -EIO;
if (sig_len != (prop->num_bits / 8)) { if (sig_len != (prop->num_bits / 8)) {

View File

@@ -257,7 +257,7 @@ void gen_rand_uuid(unsigned char *uuid_bin)
if (IS_ENABLED(CONFIG_DM_RNG)) { if (IS_ENABLED(CONFIG_DM_RNG)) {
ret = uclass_get_device(UCLASS_RNG, 0, &devp); ret = uclass_get_device(UCLASS_RNG, 0, &devp);
if (ret) { if (!ret) {
ret = dm_rng_read(devp, &randv, sizeof(randv)); ret = dm_rng_read(devp, &randv, sizeof(randv));
if (ret < 0) if (ret < 0)
randv = 0; randv = 0;