Author: oxygene Date: 2009-07-24 00:03:14 +0200 (Fri, 24 Jul 2009) New Revision: 4466
Modified: trunk/coreboot-v2/src/arch/i386/Config.lb trunk/coreboot-v2/src/arch/i386/init/crt0.S.lb trunk/coreboot-v2/src/boot/elfboot.c trunk/coreboot-v2/src/boot/selfboot.c trunk/coreboot-v2/src/lib/cbfs.c trunk/coreboot-v2/util/cbfstool/fs.c Log: CBFS stuff: - update, add, and improve comments - whitespace here and there - remove unused or write-only variables - improve debug output - only build payload.{nrv2b,lzma} for non-cbfs - improved error checking in cbfstool
Signed-off-by: Stefan Reinauer stepan@coresystems.de Acked-by: Peter Stuge peter@stuge.se
Modified: trunk/coreboot-v2/src/arch/i386/Config.lb =================================================================== --- trunk/coreboot-v2/src/arch/i386/Config.lb 2009-07-23 16:04:58 UTC (rev 4465) +++ trunk/coreboot-v2/src/arch/i386/Config.lb 2009-07-23 22:03:14 UTC (rev 4466) @@ -5,6 +5,7 @@ uses CONFIG_HAVE_FAILOVER_BOOT uses CONFIG_USE_FAILOVER_IMAGE uses CONFIG_USE_FALLBACK_IMAGE +uses CONFIG_CBFS
init init/crt0.S.lb
@@ -82,9 +83,12 @@ # catch the case where there is no compression makedefine PAYLOAD-1:=payload
+if CONFIG_CBFS +else # match the case where a compression type is specified. makedefine PAYLOAD-$(CONFIG_COMPRESSED_PAYLOAD_NRV2B):=payload.nrv2b makedefine PAYLOAD-$(CONFIG_COMPRESSED_PAYLOAD_LZMA):=payload.lzma +end
# catch the case where there is precompression. Yes, this bites. if CONFIG_PRECOMPRESSED_PAYLOAD
Modified: trunk/coreboot-v2/src/arch/i386/init/crt0.S.lb =================================================================== --- trunk/coreboot-v2/src/arch/i386/init/crt0.S.lb 2009-07-23 16:04:58 UTC (rev 4465) +++ trunk/coreboot-v2/src/arch/i386/init/crt0.S.lb 2009-07-23 22:03:14 UTC (rev 4466) @@ -142,7 +142,7 @@ #else str_copying_to_ram: .string "Copying coreboot to RAM.\r\n" #endif -#if CONFIG_CBFS +#if CONFIG_CBFS == 1 # if CONFIG_USE_FALLBACK_IMAGE == 1 str_coreboot_ram_name: .string "fallback/coreboot_ram" # else
Modified: trunk/coreboot-v2/src/boot/elfboot.c =================================================================== --- trunk/coreboot-v2/src/boot/elfboot.c 2009-07-23 16:04:58 UTC (rev 4465) +++ trunk/coreboot-v2/src/boot/elfboot.c 2009-07-23 22:03:14 UTC (rev 4466) @@ -107,11 +107,11 @@ * a machine, and implementing general relocation is hard. * * The solution: - * - Allocate a buffer twice the size of the coreboot image. - * - Anything that would overwrite coreboot copy into the lower half of + * - Allocate a buffer the size of the coreboot image plus additional + * required space. + * - Anything that would overwrite coreboot copy into the lower part of * the buffer. - * - After loading an ELF image copy coreboot to the upper half of the - * buffer. + * - After loading an ELF image copy coreboot to the top of the buffer. * - Then jump to the loaded image. * * Benefits:
Modified: trunk/coreboot-v2/src/boot/selfboot.c =================================================================== --- trunk/coreboot-v2/src/boot/selfboot.c 2009-07-23 16:04:58 UTC (rev 4465) +++ trunk/coreboot-v2/src/boot/selfboot.c 2009-07-23 22:03:14 UTC (rev 4466) @@ -74,15 +74,13 @@ void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name) { int selfboot(struct lb_memory *mem, struct cbfs_payload *payload); - struct cbfs_payload *payload = (struct cbfs_payload *) - cbfs_find_file(name, CBFS_TYPE_PAYLOAD); + struct cbfs_payload *payload;
- struct cbfs_payload_segment *segment, *first_segment; - + payload = (struct cbfs_payload *)cbfs_find_file(name, CBFS_TYPE_PAYLOAD); if (payload == NULL) return (void *) -1; printk_debug("Got a payload\n"); - first_segment = segment = &payload->segments; + selfboot(lb_mem, payload); printk_emerg("SELFBOOT RETURNED!\n");
@@ -95,11 +93,11 @@ * a machine, and implementing general relocation is hard. * * The solution: - * - Allocate a buffer twice the size of the coreboot image. - * - Anything that would overwrite coreboot copy into the lower half of + * - Allocate a buffer the size of the coreboot image plus additional + * required space. + * - Anything that would overwrite coreboot copy into the lower part of * the buffer. - * - After loading an ELF image copy coreboot to the upper half of the - * buffer. + * - After loading an ELF image copy coreboot to the top of the buffer. * - Then jump to the loaded image. * * Benefits: @@ -270,9 +268,9 @@ new->s_dstaddr, new->s_dstaddr + new->s_filesz, new->s_dstaddr + new->s_memsz); - } + } - /* Slice off a piece at the end + /* Slice off a piece at the end * that doesn't conflict with coreboot */ if (end > lb_end) { @@ -301,16 +299,13 @@ seg->phdr_next->phdr_prev = new; seg->phdr_next = new;
- /* compute the new value of end */ - end = start + len; - printk_spew(" late: [0x%016lx, 0x%016lx, 0x%016lx)\n", new->s_dstaddr, new->s_dstaddr + new->s_filesz, new->s_dstaddr + new->s_memsz); - } } + /* Now retarget this segment onto the bounce buffer */ /* sort of explanation: the buffer is a 1:1 mapping to coreboot. * so you will make the dstaddr be this buffer, and it will get copied @@ -332,7 +327,6 @@ { struct segment *new; struct segment *ptr; - int datasize; struct cbfs_payload_segment *segment, *first_segment; memset(head, 0, sizeof(*head)); head->phdr_next = head->phdr_prev = head; @@ -340,66 +334,82 @@ first_segment = segment = &payload->segments;
while(1) { - printk_debug("Segment %p\n", segment); + printk_debug("Loading segment from rom address 0x%p\n", segment); switch(segment->type) { - default: printk_emerg("Bad segment type %x\n", segment->type); - return -1; case PAYLOAD_SEGMENT_PARAMS: - printk_info("found param section\n"); + printk_debug(" parameter section (skipped)\n"); segment++; continue; + case PAYLOAD_SEGMENT_CODE: case PAYLOAD_SEGMENT_DATA: - printk_info( "%s: ", segment->type == PAYLOAD_SEGMENT_CODE ? - "code" : "data"); - new = malloc(sizeof(*new)); - new->s_dstaddr = ntohl((u32) segment->load_addr); - new->s_memsz = ntohl(segment->mem_len); - new->compression = ntohl(segment->compression); + printk_debug(" %s (compression=%x)\n", + segment->type == PAYLOAD_SEGMENT_CODE ? "code" : "data", + ntohl(segment->compression)); + new = malloc(sizeof(*new)); + new->s_dstaddr = ntohl((u32) segment->load_addr); + new->s_memsz = ntohl(segment->mem_len); + new->compression = ntohl(segment->compression);
- datasize = ntohl(segment->len); - new->s_srcaddr = (u32) ((unsigned char *) first_segment) + ntohl(segment->offset); - new->s_filesz = ntohl(segment->len); - printk_debug("New segment dstaddr 0x%lx memsize 0x%lx srcaddr 0x%lx filesize 0x%lx\n", - new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz); - /* Clean up the values */ - if (new->s_filesz > new->s_memsz) { - new->s_filesz = new->s_memsz; - } - printk_debug("(cleaned up) New segment addr 0x%lx size 0x%lx offset 0x%lx filesize 0x%lx\n", - new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz); - break; + new->s_srcaddr = (u32) ((unsigned char *) first_segment) + ntohl(segment->offset); + new->s_filesz = ntohl(segment->len); + printk_debug(" New segment dstaddr 0x%lx memsize 0x%lx srcaddr 0x%lx filesize 0x%lx\n", + new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz); + /* Clean up the values */ + if (new->s_filesz > new->s_memsz) { + new->s_filesz = new->s_memsz; + } + printk_debug(" (cleaned up) New segment addr 0x%lx size 0x%lx offset 0x%lx filesize 0x%lx\n", + new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz); + break; + case PAYLOAD_SEGMENT_BSS: - printk_info("BSS %p/%d\n", (void *) ntohl((u32) segment->load_addr), + printk_debug(" BSS 0x%p (%d byte)\n", (void *) ntohl((u32) segment->load_addr), ntohl(segment->mem_len)); new = malloc(sizeof(*new)); new->s_filesz = 0; new->s_dstaddr = ntohl((u32) segment->load_addr); new->s_memsz = ntohl(segment->mem_len); - break;
case PAYLOAD_SEGMENT_ENTRY: - printk_info("Entry %p\n", (void *) ntohl((u32) segment->load_addr)); + printk_debug(" Entry Point 0x%p\n", (void *) ntohl((u32) segment->load_addr)); *entry = ntohl((u32) segment->load_addr); + /* Per definition, a payload always has the entry point + * as last segment. Thus, we use the occurence of the + * entry point as break condition for the loop. + * Can we actually just look at the number of section? + */ return 1; + + default: + /* We found something that we don't know about. Throw + * hands into the sky and run away! + */ + printk_emerg("Bad segment type %x\n", segment->type); + return -1; } + segment++; + for(ptr = head->next; ptr != head; ptr = ptr->next) { if (new->s_srcaddr < ntohl((u32) segment->load_addr)) break; } + /* Order by stream offset */ new->next = ptr; new->prev = ptr->prev; ptr->prev->next = new; ptr->prev = new; + /* Order by original program header order */ new->phdr_next = head; new->phdr_prev = head->phdr_prev; head->phdr_prev->phdr_next = new; head->phdr_prev = new; } + return 1; }
@@ -408,10 +418,8 @@ struct lb_memory *mem, struct cbfs_payload *payload) { - unsigned long offset; struct segment *ptr; - offset = 0; unsigned long required_bounce_size = lb_end - lb_start; for(ptr = head->next; ptr != head; ptr = ptr->next) { if (!overlaps_coreboot(ptr)) continue; @@ -429,7 +437,7 @@ return 0; } for(ptr = head->next; ptr != head; ptr = ptr->next) { - unsigned char *dest,*src; + unsigned char *dest, *src; printk_debug("Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n", ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
Modified: trunk/coreboot-v2/src/lib/cbfs.c =================================================================== --- trunk/coreboot-v2/src/lib/cbfs.c 2009-07-23 16:04:58 UTC (rev 4465) +++ trunk/coreboot-v2/src/lib/cbfs.c 2009-07-23 22:03:14 UTC (rev 4466) @@ -59,16 +59,16 @@ struct cbfs_header *header;
void *ptr = (void *)*((unsigned long *) CBFS_HEADPTR_ADDR); - printk_debug("Check CBFS header at %p\n", ptr); + printk_spew("Check CBFS header at %p\n", ptr); header = (struct cbfs_header *) ptr;
- printk_debug("magic is %08x\n", ntohl(header->magic)); + printk_spew("magic is %08x\n", ntohl(header->magic)); if (ntohl(header->magic) != CBFS_HEADER_MAGIC) { - printk_err("NO CBFS HEADER\n"); + printk_err("ERROR: No valid CBFS header found!\n"); return NULL; }
- printk_debug("Found CBFS header at %p\n", ptr); + printk_spew("Found CBFS header at %p\n", ptr); return header; }
@@ -86,7 +86,7 @@ while(1) { struct cbfs_file *file = (struct cbfs_file *) offset; if (!cbfs_check_magic(file)) return NULL; - printk_info("Check %s\n", CBFS_NAME(file)); + printk_debug("Check %s\n", CBFS_NAME(file)); if (!strcmp(CBFS_NAME(file), name)) return file;
Modified: trunk/coreboot-v2/util/cbfstool/fs.c =================================================================== --- trunk/coreboot-v2/util/cbfstool/fs.c 2009-07-23 16:04:58 UTC (rev 4465) +++ trunk/coreboot-v2/util/cbfstool/fs.c 2009-07-23 22:03:14 UTC (rev 4466) @@ -312,6 +312,29 @@ ntohl(rom->header->align))); }
+struct cbfs_file *rom_find_empty(struct rom *rom) +{ + unsigned int offset = ntohl(rom->header->offset); + unsigned int ret = ntohl(rom->header->offset); + + while (offset < rom->fssize) { + + struct cbfs_file *c = + (struct cbfs_file *)ROM_PTR(rom, offset); + + if (!strcmp(c->magic, COMPONENT_MAGIC)) { + offset += ALIGN(ntohl(c->offset) + ntohl(c->len), + ntohl(rom->header->align)); + + ret = offset; + } else + offset += ntohl(rom->header->align); + } + + return (ret < rom->fssize) ? + (struct cbfs_file *)ROM_PTR(rom, ret) : NULL; +} + struct cbfs_file *rom_find_by_name(struct rom *rom, const char *name) { struct cbfs_file *c = rom_find_first(rom); @@ -363,6 +386,24 @@
c->type = CBFS_COMPONENT_DELETED;
+ void *n = rom_find_next(rom, c); + int clear; + + if (n != NULL) { + memcpy(c, n, rom->fssize - ROM_OFFSET(rom, n)); + clear = ROM_OFFSET(rom, n) - ROM_OFFSET(rom, c); + } + else { /* No component after this one. */ + unsigned int csize; + csize = sizeof(struct cbfs_file) + ALIGN(strlen(name) + 1, 16); + clear = ntohl(c->len) + csize; + memcpy(c, ((void*)c) + clear, + rom->fssize - (ROM_OFFSET(rom, c)+clear)); + } + + /* Zero the new space, which is always at the end. */ + memset(ROM_PTR(rom, rom->fssize - clear), 0, clear); + return 0; }
@@ -394,6 +435,7 @@ int rom_add(struct rom *rom, const char *name, void *buffer, unsigned long address, int size, int type) { struct cbfs_file *c; + int csize;
if (rom_find_by_name(rom, name)) { ERROR("Component %s already exists in this rom\n", name); @@ -410,7 +452,28 @@ return -1; }
- memcpy(((unsigned char *)c) + ntohl(c->offset), buffer, size); + csize = sizeof(struct cbfs_file) + ALIGN(strlen(name) + 1, 16); + + int offset = ROM_OFFSET(rom, c); + + if (offset + csize + size > rom->fssize) { + ERROR("There is not enough room in this ROM for this\n"); + ERROR("component. I need %d bytes, only have %d bytes avail\n", + csize + size, rom->fssize - offset); + + return -1; + } + + strcpy(c->magic, COMPONENT_MAGIC); + + c->len = htonl(size); + c->offset = htonl(csize); + c->type = htonl(type); + + memset(CBFS_NAME(c), 0, ALIGN(strlen(name) + 1, 16)); + strcpy((char *)CBFS_NAME(c), name); + + memcpy(((unsigned char *)c) + csize, buffer, size); return 0; }