summaryrefslogtreecommitdiffstats
path: root/util/cbfstool/common.c
diff options
context:
space:
mode:
authorDavid Hendricks <dhendrix@chromium.org>2013-01-14 20:58:50 -0800
committerRonald G. Minnich <rminnich@gmail.com>2013-01-17 01:06:43 +0100
commit0b23d47ffd1c87cb41df9e3e1b73cdfddd425dcd (patch)
tree3d633d92379b0464663a94462e4d027b0d3ecfa7 /util/cbfstool/common.c
parent3d7344a7a1fcf09406460da59b61baff564bbbd3 (diff)
downloadcoreboot-0b23d47ffd1c87cb41df9e3e1b73cdfddd425dcd.tar.gz
coreboot-0b23d47ffd1c87cb41df9e3e1b73cdfddd425dcd.tar.bz2
coreboot-0b23d47ffd1c87cb41df9e3e1b73cdfddd425dcd.zip
armv7: Place reset vector + CBFS header + bootblock dynamically
This replaces hard-coded bootblock offsets using the new scheme. The assembler will place the initial branch instruction after BL1, skip 2 aligned chunks, and place the remaining bootblock code after. It will also leave an anchor string, currently 0xdeadbeef which cbfstool will find. Once found, cbfstool will place the master CBFS header at the next aligned offset. Here is how it looks: 0x0000 |--------------| | BL1 | 0x2000 |--------------| | branch | 0x2000 + align |--------------| | CBFS header | 0x2000 + align * 2 |--------------| | bootblock | |--------------| TODO: The option for alignment passed into cbfstool has always been 64. Can we set it to 16 instead? Change-Id: Icbe817cbd8a37f11990aaf060aab77d2dc113cb1 Signed-off-by: David Hendricks <dhendrix@chromium.org> Reviewed-on: http://review.coreboot.org/2148 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'util/cbfstool/common.c')
-rw-r--r--util/cbfstool/common.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index 195cda13c605..54139584476d 100644
--- a/util/cbfstool/common.c
+++ b/util/cbfstool/common.c
@@ -565,23 +565,32 @@ int create_cbfs_image(const char *romfile, uint32_t _romsize,
/* Set up physical/virtual mapping */
offset = romarea;
- // should be aligned to align
- uint32_t *arm_vec = (uint32_t *)(romarea + offs);
- master_header = (struct cbfs_header *)(romarea + offs + 0x20);
- loadfile(bootblock, &bootblocksize, romarea + offs + 0x20 +
- sizeof(struct cbfs_header), SEEK_SET);
-
/*
- * Encoding for this branch instruction is:
- * 31:28 - condition (0xe for always/unconditional)
- * 27:24 - Branch (0xa, encoding A1)
- * 23: 0 - sign-extended offset (in multiples of 4)
+ * The initial jump instruction and bootblock will be placed
+ * before and after the master header, respectively. The
+ * bootblock image must contain a blank, aligned region large
+ * enough for the master header to fit.
*
- * When executing the branch, the PC will read as the address
- * of current instruction + 8.
+ * An anchor string must be left such that when cbfstool is run
+ * we can find it and insert the master header at the next
+ * aligned boundary.
*/
- uint32_t imm = ((0x20 + sizeof(struct cbfs_header)) - 8) / 4;
- arm_vec[0] = imm | (0xa << 24) | (0xe << 28);
+ loadfile(bootblock, &bootblocksize, romarea + offs, SEEK_SET);
+
+ unsigned char *p = romarea + offs;
+ while (1) {
+ /* FIXME: assumes little endian... */
+ if (*(uint32_t *)p == 0xdeadbeef)
+ break;
+ if (p >= (romarea + _romsize)) {
+ fprintf(stderr, "E: Could not determine CBFS "
+ "header location.\n", bootblock);
+ return 1;
+ }
+ p += (sizeof(unsigned int));
+ }
+ unsigned int u = ALIGN((unsigned int)(p - romarea), align);
+ master_header = (struct cbfs_header *)(romarea + u);
master_header->magic = ntohl(CBFS_HEADER_MAGIC);
master_header->version = ntohl(CBFS_HEADER_VERSION);