Move C labels to start-of-line
[coreboot.git] / src / boot / selfboot.c
index f3f1aa38c5c6c680a49ef8c69c6f979dad785953..99b1493ed7c39d0d6ed3db78a7845bb6bf41ed5c 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
  */
 
+#include <arch/byteorder.h>
 #include <console/console.h>
 #include <fallback.h>
 #include <boot/elf.h>
 #include <boot/elf_boot.h>
 #include <boot/coreboot_tables.h>
-#include <ip_checksum.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <cbfs.h>
 #include <lib.h>
 
-#ifndef CONFIG_BIG_ENDIAN
-#define ntohl(x) ( ((x&0xff)<<24) | ((x&0xff00)<<8) | \
-               ((x&0xff0000) >> 8) | ((x&0xff000000) >> 24) )
-#else
-#define ntohl(x) (x)
-#endif
-
-/* Maximum physical address we can use for the coreboot bounce buffer.
- */
+/* Maximum physical address we can use for the coreboot bounce buffer. */
 #ifndef MAX_ADDR
 #define MAX_ADDR -1UL
 #endif
 
+/* from coreboot_ram.ld: */
 extern unsigned char _ram_seg;
 extern unsigned char _eram_seg;
 
+static const unsigned long lb_start = (unsigned long)&_ram_seg;
+static const unsigned long lb_end = (unsigned long)&_eram_seg;
+
 struct segment {
        struct segment *next;
        struct segment *prev;
-       struct segment *phdr_next;
-       struct segment *phdr_prev;
        unsigned long s_dstaddr;
        unsigned long s_srcaddr;
        unsigned long s_memsz;
@@ -58,36 +52,6 @@ struct segment {
        int compression;
 };
 
-struct verify_callback {
-       struct verify_callback *next;
-       int (*callback)(struct verify_callback *vcb,
-               Elf_ehdr *ehdr, Elf_phdr *phdr, struct segment *head);
-       unsigned long desc_offset;
-       unsigned long desc_addr;
-};
-
-struct ip_checksum_vcb {
-       struct verify_callback data;
-       unsigned short ip_checksum;
-};
-
-static int selfboot(struct lb_memory *mem, struct cbfs_payload *payload);
-
-void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
-{
-       struct cbfs_payload *payload;
-
-       payload = (struct cbfs_payload *)cbfs_find_file(name, CBFS_TYPE_PAYLOAD);
-       if (payload == NULL)
-               return (void *) -1;
-       printk(BIOS_DEBUG, "Got a payload\n");
-
-       selfboot(lb_mem, payload);
-       printk(BIOS_EMERG, "SELFBOOT RETURNED!\n");
-
-       return (void *) -1;
-}
-
 /* The problem:
  * Static executables all want to share the same addresses
  * in memory because only a few addresses are reliably present on
@@ -106,7 +70,6 @@ void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
  * - Coreboot is preserved, so it can be returned to.
  * - The implementation is still relatively simple,
  *   and much simpler than the general case implemented in kexec.
- *
  */
 
 static unsigned long bounce_size, bounce_buffer;
@@ -117,10 +80,12 @@ static void get_bounce_buffer(struct lb_memory *mem, unsigned long req_size)
        unsigned long mem_entries;
        unsigned long buffer;
        int i;
-       lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
-       /* Double coreboot size so I have somewhere to place a copy to return to */
+       lb_size = lb_end - lb_start;
+       /* Plus coreboot size so I have somewhere
+        * to place a copy to return to.
+        */
        lb_size = req_size + lb_size;
-       mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+       mem_entries = (mem->size - sizeof(*mem)) / sizeof(mem->map[0]);
        buffer = 0;
        for(i = 0; i < mem_entries; i++) {
                unsigned long mstart, mend;
@@ -155,7 +120,8 @@ static int valid_area(struct lb_memory *mem, unsigned long buffer,
         */
        int i;
        unsigned long end = start + len;
-       unsigned long mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
+       unsigned long mem_entries = (mem->size - sizeof(*mem)) /
+               sizeof(mem->map[0]);
 
        /* See if I conflict with the bounce buffer */
        if (end >= buffer) {
@@ -171,11 +137,11 @@ static int valid_area(struct lb_memory *mem, unsigned long buffer,
                mtype = mem->map[i].type;
                mstart = unpack_lb64(mem->map[i].start);
                mend = mstart + unpack_lb64(mem->map[i].size);
-               if ((mtype == LB_MEM_RAM) && (start < mend) && (end > mstart)) {
+               if ((mtype == LB_MEM_RAM) && (start >= mstart) && (end < mend)) {
                        break;
                }
-               if ((mtype == LB_MEM_TABLE) && (start < mend) && (end > mstart)) {
-                       printk(BIOS_ERR, "Payload is overwriting Coreboot tables.\n");
+               if ((mtype == LB_MEM_TABLE) && (start >= mstart) && (end < mend)) {
+                       printk(BIOS_ERR, "Payload is overwriting coreboot tables.\n");
                        break;
                }
        }
@@ -200,8 +166,6 @@ static int valid_area(struct lb_memory *mem, unsigned long buffer,
        return 1;
 }
 
-static const unsigned long lb_start = (unsigned long)&_ram_seg;
-static const unsigned long lb_end = (unsigned long)&_eram_seg;
 
 static int overlaps_coreboot(struct segment *seg)
 {
@@ -217,7 +181,8 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
         * to load onto the bounce buffer instead.
         */
        /* ret:  1 : A new segment is inserted before the seg.
-        *       0 : A new segment is inserted after the seg, or no new one. */
+        *       0 : A new segment is inserted after the seg, or no new one.
+        */
        unsigned long start, middle, end, ret = 0;
 
        printk(BIOS_SPEW, "lb: [0x%016lx, 0x%016lx)\n",
@@ -259,11 +224,6 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
                        new->prev = seg->prev;
                        seg->prev->next = new;
                        seg->prev = new;
-                       /* Order by original program header order */
-                       new->phdr_next = seg;
-                       new->phdr_prev = seg->phdr_prev;
-                       seg->phdr_prev->phdr_next = new;
-                       seg->phdr_prev = new;
 
                        /* compute the new value of start */
                        start = seg->s_dstaddr;
@@ -299,11 +259,6 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
                        new->prev = seg;
                        seg->next->prev = new;
                        seg->next = new;
-                       /* Order by original program header order */
-                       new->phdr_next = seg->phdr_next;
-                       new->phdr_prev = seg;
-                       seg->phdr_next->phdr_prev = new;
-                       seg->phdr_next = new;
 
                        printk(BIOS_SPEW, "   late: [0x%016lx, 0x%016lx, 0x%016lx)\n",
                                new->s_dstaddr,
@@ -337,7 +292,6 @@ static int build_self_segment_list(
        struct segment *ptr;
        struct cbfs_payload_segment *segment, *first_segment;
        memset(head, 0, sizeof(*head));
-       head->phdr_next = head->phdr_prev = head;
        head->next = head->prev = head;
        first_segment = segment = &payload->segments;
 
@@ -355,11 +309,12 @@ static int build_self_segment_list(
                                        segment->type == PAYLOAD_SEGMENT_CODE ?  "code" : "data",
                                        ntohl(segment->compression));
                        new = malloc(sizeof(*new));
-                       new->s_dstaddr = ntohl((u32) segment->load_addr);
+                       new->s_dstaddr = ntohll(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_srcaddr = (u32) ((unsigned char *)first_segment)
+                                               + ntohl(segment->offset);
                        new->s_filesz = ntohl(segment->len);
                        printk(BIOS_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);
@@ -372,17 +327,18 @@ static int build_self_segment_list(
                        break;
 
                case PAYLOAD_SEGMENT_BSS:
-                       printk(BIOS_DEBUG, "  BSS 0x%p (%d byte)\n", (void *) ntohl((u32) segment->load_addr),
-                                ntohl(segment->mem_len));
+                       printk(BIOS_DEBUG, "  BSS 0x%p (%d byte)\n", (void *)
+                                       (intptr_t)ntohll(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_dstaddr = ntohll(segment->load_addr);
                        new->s_memsz = ntohl(segment->mem_len);
                        break;
 
                case PAYLOAD_SEGMENT_ENTRY:
                        printk(BIOS_DEBUG, "  Entry Point 0x%p\n", (void *) ntohl((u32) segment->load_addr));
-                       *entry =  ntohl((u32) segment->load_addr);
+                       *entry =  ntohll(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.
@@ -398,11 +354,12 @@ static int build_self_segment_list(
                        return -1;
                }
 
+               /* We have found another CODE, DATA or BSS segment */
                segment++;
 
-               // FIXME: Explain what this is
+               /* Find place where to insert our segment */
                for(ptr = head->next; ptr != head; ptr = ptr->next) {
-                       if (new->s_srcaddr < ntohl((u32) segment->load_addr))
+                       if (new->s_srcaddr < ntohll(segment->load_addr))
                                break;
                }
 
@@ -411,12 +368,6 @@ static int build_self_segment_list(
                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;
@@ -431,7 +382,8 @@ static int load_self_segments(
 
        unsigned long bounce_high = lb_end;
        for(ptr = head->next; ptr != head; ptr = ptr->next) {
-               if (!overlaps_coreboot(ptr)) continue;
+               if (!overlaps_coreboot(ptr))
+                       continue;
                if (ptr->s_dstaddr + ptr->s_memsz > bounce_high)
                        bounce_high = ptr->s_dstaddr + ptr->s_memsz;
        }
@@ -477,7 +429,7 @@ static int load_self_segments(
                                                return 0;
                                        break;
                                }
-#if CONFIG_COMPRESSED_PAYLOAD_NRV2B==1
+#if CONFIG_COMPRESSED_PAYLOAD_NRV2B
                                case CBFS_COMPRESS_NRV2B: {
                                        printk(BIOS_DEBUG, "using NRV2B\n");
                                        unsigned long unrv2b(u8 *src, u8 *dst, unsigned long *ilen_p);
@@ -553,13 +505,28 @@ static int selfboot(struct lb_memory *mem, struct cbfs_payload *payload)
        boot_successful();
 
        printk(BIOS_DEBUG, "Jumping to boot code at %x\n", entry);
-       post_code(0xfe);
+       post_code(POST_ENTER_ELF_BOOT);
 
        /* Jump to kernel */
        jmp_to_elf_entry((void*)entry, bounce_buffer, bounce_size);
        return 1;
 
- out:
+out:
        return 0;
 }
 
+void *cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
+{
+       struct cbfs_payload *payload;
+
+       payload = (struct cbfs_payload *)cbfs_find_file(name, CBFS_TYPE_PAYLOAD);
+       if (payload == NULL)
+               return (void *) -1;
+       printk(BIOS_DEBUG, "Got a payload\n");
+
+       selfboot(lb_mem, payload);
+       printk(BIOS_EMERG, "SELFBOOT RETURNED!\n");
+
+       return (void *) -1;
+}
+