Commit 7fffa694 authored by Simon Arlott's avatar Simon Arlott Committed by Brian Norris

mtd: bcm63xxpart: Extract read of image tag to separate function

Extract image tag reading and CRC check to a separate function.
Signed-off-by: default avatarSimon Arlott <simon@fire.lp0.eu>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 436e94a6
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
#define BCM963XX_CFE_VERSION_OFFSET 0x570 #define BCM963XX_CFE_VERSION_OFFSET 0x570
#define BCM963XX_NVRAM_OFFSET 0x580 #define BCM963XX_NVRAM_OFFSET 0x580
/* Ensure strings read from flash structs are null terminated */
#define STR_NULL_TERMINATE(x) \
do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0)
static int bcm63xx_detect_cfe(struct mtd_info *master) static int bcm63xx_detect_cfe(struct mtd_info *master)
{ {
char buf[9]; char buf[9];
...@@ -89,6 +93,37 @@ static int bcm63xx_read_nvram(struct mtd_info *master, ...@@ -89,6 +93,37 @@ static int bcm63xx_read_nvram(struct mtd_info *master,
return 0; return 0;
} }
static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name,
loff_t tag_offset, struct bcm_tag *buf)
{
int ret;
size_t retlen;
u32 computed_crc;
ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf);
if (ret)
return ret;
if (retlen != sizeof(*buf))
return -EIO;
computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
offsetof(struct bcm_tag, header_crc));
if (computed_crc == buf->header_crc) {
STR_NULL_TERMINATE(buf->board_id);
STR_NULL_TERMINATE(buf->tag_version);
pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n",
name, tag_offset, buf->tag_version, buf->board_id);
return 0;
}
pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n",
name, tag_offset, buf->header_crc, computed_crc);
return 1;
}
static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
const struct mtd_partition **pparts, const struct mtd_partition **pparts,
struct mtd_part_parser_data *data) struct mtd_part_parser_data *data)
...@@ -99,13 +134,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, ...@@ -99,13 +134,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
struct bcm_tag *buf = NULL; struct bcm_tag *buf = NULL;
struct mtd_partition *parts; struct mtd_partition *parts;
int ret; int ret;
size_t retlen;
unsigned int rootfsaddr, kerneladdr, spareaddr; unsigned int rootfsaddr, kerneladdr, spareaddr;
unsigned int rootfslen, kernellen, sparelen, totallen; unsigned int rootfslen, kernellen, sparelen, totallen;
unsigned int cfelen, nvramlen; unsigned int cfelen, nvramlen;
unsigned int cfe_erasesize; unsigned int cfe_erasesize;
int i; int i;
u32 computed_crc;
bool rootfs_first = false; bool rootfs_first = false;
if (bcm63xx_detect_cfe(master)) if (bcm63xx_detect_cfe(master))
...@@ -134,28 +167,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, ...@@ -134,28 +167,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
} }
/* Get the tag */ /* Get the tag */
ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf);
(void *)buf); if (!ret) {
if (retlen != sizeof(struct bcm_tag)) {
ret = -EIO;
goto out;
}
computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
offsetof(struct bcm_tag, header_crc));
if (computed_crc == buf->header_crc) {
char *boardid = &(buf->board_id[0]);
char *tagversion = &(buf->tag_version[0]);
sscanf(buf->flash_image_start, "%u", &rootfsaddr); sscanf(buf->flash_image_start, "%u", &rootfsaddr);
sscanf(buf->kernel_address, "%u", &kerneladdr); sscanf(buf->kernel_address, "%u", &kerneladdr);
sscanf(buf->kernel_length, "%u", &kernellen); sscanf(buf->kernel_length, "%u", &kernellen);
sscanf(buf->total_length, "%u", &totallen); sscanf(buf->total_length, "%u", &totallen);
pr_info("CFE boot tag found with version %s and board type %s\n",
tagversion, boardid);
kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE;
rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE;
spareaddr = roundup(totallen, master->erasesize) + cfelen; spareaddr = roundup(totallen, master->erasesize) + cfelen;
...@@ -169,13 +187,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, ...@@ -169,13 +187,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
rootfsaddr = kerneladdr + kernellen; rootfsaddr = kerneladdr + kernellen;
rootfslen = spareaddr - rootfsaddr; rootfslen = spareaddr - rootfsaddr;
} }
} else { } else if (ret > 0) {
pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
buf->header_crc, computed_crc);
kernellen = 0; kernellen = 0;
rootfslen = 0; rootfslen = 0;
rootfsaddr = 0; rootfsaddr = 0;
spareaddr = cfelen; spareaddr = cfelen;
} else {
goto out;
} }
sparelen = master->size - spareaddr - nvramlen; sparelen = master->size - spareaddr - nvramlen;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment