diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-10-25 15:47:47 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-10-25 15:47:47 +1100 |
commit | 26895ba411d5d4d86cbb377862cd2e43fcc07cf8 (patch) | |
tree | 6d867fd1601da4afe3d41d6a3d65e147072fd1c5 | |
parent | 1408f6f9baa684f280dfb2c4a66daa4d5db996b2 (diff) | |
download | skiboot-26895ba411d5d4d86cbb377862cd2e43fcc07cf8.zip skiboot-26895ba411d5d4d86cbb377862cd2e43fcc07cf8.tar.gz skiboot-26895ba411d5d4d86cbb377862cd2e43fcc07cf8.tar.bz2 |
core/flash: Move subpartition locating logic out into own file, add tests
A unit test for parsing sub-partition info is useful for a number
of reasons, one of which showed its head during development of
secure/trusted boot.
This patch just moves things around, there's no functional changes.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | core/Makefile.inc | 1 | ||||
-rw-r--r-- | core/flash-subpartition.c | 102 | ||||
-rw-r--r-- | core/flash.c | 73 | ||||
-rw-r--r-- | core/test/Makefile.check | 1 | ||||
-rw-r--r-- | core/test/run-flash-subpartition.c | 55 | ||||
-rw-r--r-- | include/skiboot.h | 3 |
6 files changed, 161 insertions, 74 deletions
diff --git a/core/Makefile.inc b/core/Makefile.inc index be59bca..9223af1 100644 --- a/core/Makefile.inc +++ b/core/Makefile.inc @@ -8,6 +8,7 @@ CORE_OBJS += pci-opal.o fast-reboot.o device.o exceptions.o trace.o affinity.o CORE_OBJS += vpd.o hostservices.o platform.o nvram.o nvram-format.o hmi.o CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o +CORE_OBJS += flash-subpartition.o ifeq ($(SKIBOOT_GCOV),1) CORE_OBJS += gcov-profiling.o diff --git a/core/flash-subpartition.c b/core/flash-subpartition.c new file mode 100644 index 0000000..ba7f0a3 --- /dev/null +++ b/core/flash-subpartition.c @@ -0,0 +1,102 @@ +/* Copyright 2013-2016 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <skiboot.h> +#include <opal-api.h> + +struct flash_hostboot_toc { + be32 ec; + be32 offset; /* From start of header. 4K aligned */ + be32 size; +}; +#define FLASH_HOSTBOOT_TOC_MAX_ENTRIES ((FLASH_SUBPART_HEADER_SIZE - 8) \ + /sizeof(struct flash_hostboot_toc)) + +struct flash_hostboot_header { + char eyecatcher[4]; + be32 version; + struct flash_hostboot_toc toc[FLASH_HOSTBOOT_TOC_MAX_ENTRIES]; +}; + +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/core/flash.c b/core/flash.c index 92de421..4b7f4b3 100644 --- a/core/flash.c +++ b/core/flash.c @@ -418,9 +418,6 @@ static struct { { RESOURCE_ID_CAPP, RESOURCE_SUBID_SUPPORTED, "CAPP" }, }; -/* This mimics the hostboot SBE format */ -#define FLASH_SUBPART_ALIGNMENT 0x1000 -#define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT struct flash_hostboot_toc { be32 ec; @@ -723,73 +720,3 @@ 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/core/test/Makefile.check b/core/test/Makefile.check index fa1b806..d3dd260 100644 --- a/core/test/Makefile.check +++ b/core/test/Makefile.check @@ -1,5 +1,6 @@ # -*-Makefile-*- CORE_TEST := core/test/run-device \ + core/test/run-flash-subpartition \ core/test/run-mem_region \ core/test/run-malloc \ core/test/run-malloc-speed \ diff --git a/core/test/run-flash-subpartition.c b/core/test/run-flash-subpartition.c new file mode 100644 index 0000000..169362e --- /dev/null +++ b/core/test/run-flash-subpartition.c @@ -0,0 +1,55 @@ +/* Copyright 2013-2016 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <skiboot.h> +#include <opal-api.h> +#include <stdlib.h> + +#include "../flash-subpartition.c" +#include <assert.h> + +/* This is a straight dump of the CAPP ucode partition header */ +char capp[4096] = {0x43, 0x41, 0x50, 0x50, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x01, 0x00, 0xea, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x8e, 0x50, 0x00, 0x02, 0x00, 0xea, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x8e, 0x50, + 0x00, 0x02, 0x00, 0xef, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x8e, 0x50, 0x00, 0x02, 0x01, 0xef, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x8e, 0x50, + 0x00, 0x01, 0x00, 0xd3, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x8e, 0x50, 0x00, 0x00, 0x00, 0x00 }; + +int main(void) +{ + int rc; + uint32_t offset; + uint32_t size; + uint32_t subids[] = { 0x100ea, 0x200ea, 0x200ef, 0x201ef, 0x100d3 }; + + for (int i = 0; i < sizeof(subids)/sizeof(uint32_t); i++) { + offset = 0; + rc = flash_subpart_info(capp, 0x24000, subids[i], + &offset, &size); + printf("\nsubid %x\n", subids[i]); + printf("offset %u\n", offset); + printf("size %u\n", size); + assert (rc == 0); + assert (size == 36432); + assert (offset == 4096); + } + + return 0; +} diff --git a/include/skiboot.h b/include/skiboot.h index 2ef7677..30149a1 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -225,10 +225,11 @@ 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); +#define FLASH_SUBPART_ALIGNMENT 0x1000 +#define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT 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); extern void nvram_read_complete(bool success); |