diff options
-rw-r--r-- | core/flash.c | 144 | ||||
-rw-r--r-- | include/skiboot.h | 4 |
2 files changed, 86 insertions, 62 deletions
diff --git a/core/flash.c b/core/flash.c index 0424479..24c34cf 100644 --- a/core/flash.c +++ b/core/flash.c @@ -457,8 +457,7 @@ static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid, bool ecc) { struct flash_hostboot_header *header; - char eyecatcher[5]; - uint32_t i, partsize; + uint32_t partsize, offset, size; int rc; header = malloc(FLASH_SUBPART_HEADER_SIZE); @@ -478,66 +477,19 @@ static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid, goto end; } - /* Perform sanity */ - i = be32_to_cpu(header->version); - if (i != 1) { - prerror("FLASH: flash subpartition TOC version unknown %i\n", i); - rc = OPAL_RESOURCE; + rc = flash_subpart_info(header, partsize, subid, &offset, &size); + if (rc) goto end; - } - /* NULL terminate eyecatcher */ - strncpy(eyecatcher, header->eyecatcher, 4); - eyecatcher[4] = 0; - prlog(PR_DEBUG, "FLASH: flash subpartition eyecatcher %s\n", - eyecatcher); - - rc = OPAL_RESOURCE; - for (i = 0; i< FLASH_HOSTBOOT_TOC_MAX_ENTRIES; i++) { - uint32_t ec, offset, size; - - ec = be32_to_cpu(header->toc[i].ec); - offset = be32_to_cpu(header->toc[i].offset); - size = be32_to_cpu(header->toc[i].size); - /* Check for null terminating entry */ - if (!ec && !offset && !size) { - prerror("FLASH: flash subpartition not found.\n"); - goto end; - } - - if (ec != subid) - continue; - /* Sanity check the offset and size. */ - if (offset + size > partsize) { - prerror("FLASH: flash subpartition too big: %i\n", i); - goto end; - } - if (!size) { - prerror("FLASH: flash subpartition zero size: %i\n", i); - goto end; - } - if (offset < FLASH_SUBPART_HEADER_SIZE) { - prerror("FLASH: flash subpartition " - "offset too small: %i\n", i); - goto end; - } - - prlog(PR_DEBUG, "FLASH: flash found subpartition: " - "%i size: %i offset %i\n", - i, size, offset); - - /* - * Adjust the start and size. The start location in the needs - * to account for ecc but the size doesn't. - */ - *start += offset; - *total_size = size; - if (ecc) { - *start += ecc_size(offset); - *total_size += ecc_size(size); - } - rc = 0; - goto end; + /* + * Adjust the start and size. The start location in the needs + * to account for ecc but the size doesn't. + */ + *start += offset; + *total_size = size; + if (ecc) { + *start += ecc_size(offset); + *total_size += ecc_size(size); } end: @@ -651,7 +603,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid, rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc); if (rc) { - prerror("FLASH: failed to read %s partition\n", name); + prerror("FLASH: failed to read %s partition, rc %d\n", name, rc); goto out_free_ffs; } @@ -779,3 +731,73 @@ int flash_start_preload_resource(enum resource_id id, uint32_t subid, return OPAL_SUCCESS; } + +int flash_subpart_info(void *part_header, uint32_t part_size, uint32_t subid, + uint32_t *offset, uint32_t *size) +{ + struct flash_hostboot_header *header; + char eyecatcher[5]; + uint32_t i, ec; + + if (!part_header || !offset || !size) { + prlog(PR_ERR, "FLASH: invalid parameters: " + "ph %p of %p sz %p\n", part_header, offset, size); + return OPAL_PARAMETER; + } + + header = (struct flash_hostboot_header*) part_header; + + /* Perform sanity */ + i = be32_to_cpu(header->version); + if (i != 1) { + prerror("FLASH: flash subpartition TOC version unknown %i\n", i); + goto end; + } + + /* NULL terminate eyecatcher */ + strncpy(eyecatcher, header->eyecatcher, 4); + eyecatcher[4] = '\0'; + prlog(PR_DEBUG, "FLASH: flash subpartition eyecatcher %s\n", + eyecatcher); + + for (i = 0; i < FLASH_HOSTBOOT_TOC_MAX_ENTRIES; i++) { + + ec = be32_to_cpu(header->toc[i].ec); + *offset = be32_to_cpu(header->toc[i].offset); + *size = be32_to_cpu(header->toc[i].size); + + /* Check for null terminating entry */ + if (!ec && !*offset && !*size) { + prerror("FLASH: flash subpartition not found.\n"); + goto end; + } + + if (ec != subid) + continue; + + /* Sanity check the offset and size. */ + if (*offset + *size > part_size) { + prerror("FLASH: flash subpartition too big: %i\n", i); + goto end; + } + if (!*size) { + prerror("FLASH: flash subpartition zero size: %i\n", i); + goto end; + } + if (*offset < FLASH_SUBPART_HEADER_SIZE) { + prerror("FLASH: flash subpartition " + "offset too small: %i\n", i); + goto end; + } + + prlog(PR_DEBUG, "FLASH: flash found subpartition: " + "%i size: %i offset %i\n", + i, *size, *offset); + + return OPAL_SUCCESS; + } +end: + *size = 0; + *offset = 0; + return OPAL_RESOURCE; +} diff --git a/include/skiboot.h b/include/skiboot.h index 52a235b..2a9f5e2 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -223,7 +223,9 @@ extern int flash_start_preload_resource(enum resource_id id, uint32_t subid, extern int flash_resource_loaded(enum resource_id id, uint32_t idx); extern bool flash_reserve(void); extern void flash_release(void); - +extern int flash_subpart_info(void *part_header, uint32_t part_size, + uint32_t subid, uint32_t *offset, + uint32_t *size); /* NVRAM support */ extern void nvram_init(void); |