CBFS stuff:
authorStefan Reinauer <stepan@coresystems.de>
Thu, 23 Jul 2009 22:03:14 +0000 (22:03 +0000)
committerPatrick Georgi <patrick.georgi@coresystems.de>
Thu, 23 Jul 2009 22:03:14 +0000 (22:03 +0000)
- 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>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4466 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/arch/i386/Config.lb
src/arch/i386/init/crt0.S.lb
src/boot/elfboot.c
src/boot/selfboot.c
src/lib/cbfs.c
util/cbfstool/fs.c

index 1691d29a7968372a397c88975e276077c89a5c34..4c6278acb54f513e74e2ff58a3df3e89e59955fb 100644 (file)
@@ -5,6 +5,7 @@ uses CONFIG_USE_INIT
 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 @@ end
 # 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 
index e60144840c6265ddd814ce2b5b863478e51ea966..3865ba3c3f927154876480f6ddf34ccf91b9a325 100644 (file)
@@ -142,7 +142,7 @@ str_copying_to_ram:  .string "Uncompressing coreboot to RAM.\r\n"
 #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
index e6339627991088b88c8955d79f56d8c924fef08d..958112d669fb791d14a5312b8cda1c8632d86261 100644 (file)
@@ -107,11 +107,11 @@ int verify_ip_checksum(
  * 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:
index faeadba0f031629be2500cb9a66cae6b69de8013..254c131a5324f78447f5162efe974203a43a09a4 100644 (file)
@@ -74,15 +74,13 @@ struct ip_checksum_vcb {
 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_segment *segment, *first_segment;
+       struct cbfs_payload *payload;
 
+       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 @@ void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
  * 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 @@ static void relocate_segment(unsigned long buffer, struct segment *seg)
                                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 @@ static void relocate_segment(unsigned long buffer, struct segment *seg)
                        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 @@ static int build_self_segment_list(
 {
        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 @@ static int build_self_segment_list(
        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);
-
-               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;
+                       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);
+
+                       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 @@ static int load_self_segments(
        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 @@ static int load_self_segments(
                        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);
                
index f57a14a8000e25915419330dfda166d8d6cb08d7..5a8b5f776247be6407f3397d7a34eb77be4a7d20 100644 (file)
@@ -59,16 +59,16 @@ struct cbfs_header *cbfs_master_header(void)
        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 @@ struct cbfs_file *cbfs_find(const char *name)
        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;
 
index 1e4f06907a73a631f437322661e95d2ec72e35be..611b8fc6735f76c737e902f03af85299e6e601c2 100644 (file)
@@ -312,6 +312,29 @@ struct cbfs_file *rom_find_next(struct rom *rom, struct cbfs_file *prev)
                              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 @@ int rom_remove(struct rom *rom, const char *name)
 
        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_extract(struct rom *rom, const char *name, void** buf, int *size )
 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 @@ int rom_add(struct rom *rom, const char *name, void *buffer, unsigned long addre
                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;
 }