Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5303
-gerrit
commit 4120a3e48a152a5e15b4c6eaa9d93ecc9ccc6068 Author: Aaron Durbin adurbin@chromium.org Date: Tue Feb 25 00:21:10 2014 -0600
selfboot: use bootmem infrastructure
Instead of packing and unpacking entries in lb_mem use the bootmem infrastructure for performing sanity checks during payload loading.
Change-Id: Ica2bee7ebb0f6bf9ded31deac8cb700aa387bc7a Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/include/payload_loader.h | 3 +- src/lib/loaders/load_and_run_payload.c | 5 +- src/lib/selfboot.c | 140 ++++++++------------------------- 3 files changed, 33 insertions(+), 115 deletions(-)
diff --git a/src/include/payload_loader.h b/src/include/payload_loader.h index 0715d37..6f4a858 100644 --- a/src/include/payload_loader.h +++ b/src/include/payload_loader.h @@ -58,7 +58,6 @@ struct payload_loader_ops { };
/* Defined in src/lib/selfboot.c */ -struct lb_memory; -void *selfload(struct lb_memory *mem, struct payload *payload); +void *selfload(struct payload *payload);
#endif /* PAYLOAD_LOADER_H */ diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c index cab437d..7e1383e 100644 --- a/src/lib/loaders/load_and_run_payload.c +++ b/src/lib/loaders/load_and_run_payload.c @@ -20,7 +20,6 @@ #include <stdint.h> #include <stdlib.h> #include <console/console.h> -#include <boot/coreboot_tables.h> #include <fallback.h> #include <lib.h> #include <payload_loader.h> @@ -44,7 +43,6 @@ struct payload *payload_load(void) { int i; void *entry; - struct lb_mem *mem; const struct payload_loader_ops *ops; struct payload *payload = &global_payload;
@@ -64,8 +62,7 @@ struct payload *payload_load(void) if (i == ARRAY_SIZE(payload_ops)) return NULL;
- mem = get_lb_mem(); - entry = selfload(mem, payload); + entry = selfload(payload);
if (entry == NULL) return NULL; diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index 6dc3a75..74a74f9 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -21,19 +21,14 @@ #include <arch/byteorder.h> #include <console/console.h> #include <cpu/cpu.h> -#include <boot/coreboot_tables.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <cbfs.h> #include <lib.h> +#include <bootmem.h> #include <payload_loader.h>
-/* 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; @@ -73,12 +68,10 @@ struct segment {
static unsigned long bounce_size, bounce_buffer;
-static void get_bounce_buffer(struct lb_memory *mem, unsigned long req_size) +static void get_bounce_buffer(unsigned long req_size) { unsigned long lb_size; - unsigned long mem_entries; - unsigned long buffer; - int i; + void *buffer;
/* When the ramstage is relocatable there is no need for a bounce * buffer. All payloads should not overlap the ramstage. @@ -94,93 +87,15 @@ static void get_bounce_buffer(struct lb_memory *mem, unsigned long req_size) * to place a copy to return to. */ lb_size = req_size + lb_size; - mem_entries = (mem->size - sizeof(*mem)) / sizeof(mem->map[0]); - buffer = 0; - for(i = 0; i < mem_entries; i++) { - unsigned long mstart, mend; - unsigned long msize; - unsigned long tbuffer; - if (mem->map[i].type != LB_MEM_RAM) - continue; - if (unpack_lb64(mem->map[i].start) > MAX_ADDR) - continue; - if (unpack_lb64(mem->map[i].size) < lb_size) - continue; - mstart = unpack_lb64(mem->map[i].start); - msize = MAX_ADDR - mstart +1; - if (msize > unpack_lb64(mem->map[i].size)) - msize = unpack_lb64(mem->map[i].size); - mend = mstart + msize; - tbuffer = mend - lb_size; - if (tbuffer < buffer) - continue; - buffer = tbuffer; - } - bounce_buffer = buffer; - bounce_size = req_size; -} - -static int valid_area(struct lb_memory *mem, unsigned long buffer, - unsigned long start, unsigned long len) -{ - /* Check through all of the memory segments and ensure - * the segment that was passed in is completely contained - * in RAM. - */ - int i; - unsigned long end = start + len; - unsigned long mem_entries = (mem->size - sizeof(*mem)) / - sizeof(mem->map[0]);
- /* See if I conflict with the bounce buffer */ - if (end >= buffer) { - return 0; - } + buffer = bootmem_allocate_buffer(lb_size);
- /* Walk through the table of valid memory ranges and see if I - * have a match. - */ - for(i = 0; i < mem_entries; i++) { - uint64_t mstart, mend; - uint32_t mtype; - 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 >= mstart) && (end < mend)) { - break; - } - if ((mtype == LB_MEM_TABLE) && (start >= mstart) && (end < mend)) { - printk(BIOS_ERR, "Payload is overwriting coreboot tables.\n"); - break; - } - } - if (i == mem_entries) { - if (start < (1024*1024) && end <=(1024*1024)) { - printk(BIOS_DEBUG, "Payload (probably SeaBIOS) loaded" - " into a reserved area in the lower 1MB\n"); - return 1; - } - printk(BIOS_ERR, "No matching ram area found for range:\n"); - printk(BIOS_ERR, " [0x%016lx, 0x%016lx)\n", start, end); - printk(BIOS_ERR, "Ram areas\n"); - for(i = 0; i < mem_entries; i++) { - uint64_t mstart, mend; - uint32_t mtype; - mtype = mem->map[i].type; - mstart = unpack_lb64(mem->map[i].start); - mend = mstart + unpack_lb64(mem->map[i].size); - printk(BIOS_ERR, " [0x%016lx, 0x%016lx) %s\n", - (unsigned long)mstart, - (unsigned long)mend, - (mtype == LB_MEM_RAM)?"RAM":"Reserved"); + printk(BIOS_SPEW, "Bounce Buffer at %p, %lu bytes\n", buffer, lb_size);
- } - return 0; - } - return 1; + bounce_buffer = (uintptr_t)buffer; + bounce_size = req_size; }
- static int overlaps_coreboot(struct segment *seg) { unsigned long start, end; @@ -299,7 +214,6 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
static int build_self_segment_list( struct segment *head, - struct lb_memory *mem, struct payload *payload, uintptr_t *entry) { struct segment *new; @@ -393,24 +307,37 @@ static int build_self_segment_list(
static int load_self_segments( struct segment *head, - struct lb_memory *mem, struct payload *payload) { struct segment *ptr; - unsigned long bounce_high = lb_end; + + for(ptr = head->next; ptr != head; ptr = ptr->next) { + if (!bootmem_region_targets_usable_ram(ptr->s_dstaddr, + ptr->s_memsz)) { + printk(BIOS_ERR, "SELF Payload doesn't target RAM:\n"); + printk(BIOS_ERR, "Failed Segment: 0x%lx, %lu bytes\n", + ptr->s_dstaddr, ptr->s_memsz); + bootmem_dump_ranges(); + return 0; + } + } + for(ptr = head->next; ptr != head; ptr = ptr->next) { + /* + * Add segments to bootmem memory map before a bounce buffer is + * allocated so that there aren't conflicts with the actual + * payload. + */ + bootmem_add_range(ptr->s_dstaddr, ptr->s_memsz, + LB_MEM_UNUSABLE); + if (!overlaps_coreboot(ptr)) continue; -#if CONFIG_RELOCATABLE_RAMSTAGE - /* payloads are required to not overlap ramstage. */ - return 0; -#else if (ptr->s_dstaddr + ptr->s_memsz > bounce_high) bounce_high = ptr->s_dstaddr + ptr->s_memsz; -#endif } - get_bounce_buffer(mem, bounce_high - lb_start); + get_bounce_buffer(bounce_high - lb_start); if (!bounce_buffer) { printk(BIOS_ERR, "Could not find a bounce buffer...\n"); return 0; @@ -421,11 +348,6 @@ static int load_self_segments( payload->bounce.size = bounce_size;
for(ptr = head->next; ptr != head; ptr = ptr->next) { - /* Verify the memory addresses in the segment are valid */ - if (!valid_area(mem, bounce_buffer, ptr->s_dstaddr, ptr->s_memsz)) - return 0; - } - for(ptr = head->next; ptr != head; ptr = ptr->next) { unsigned char *dest, *src; printk(BIOS_DEBUG, "Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n", ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz); @@ -505,17 +427,17 @@ static int load_self_segments( return 1; }
-void *selfload(struct lb_memory *mem, struct payload *payload) +void *selfload(struct payload *payload) { uintptr_t entry = 0; struct segment head;
/* Preprocess the self segments */ - if (!build_self_segment_list(&head, mem, payload, &entry)) + if (!build_self_segment_list(&head, payload, &entry)) goto out;
/* Load the segments */ - if (!load_self_segments(&head, mem, payload)) + if (!load_self_segments(&head, payload)) goto out;
printk(BIOS_SPEW, "Loaded segments\n");