[coreboot] [v2] r4281 - in trunk/coreboot-v2/src: arch/i386/boot arch/ppc/boot boot include/boot

svn at coreboot.org svn at coreboot.org
Wed May 13 18:27:26 CEST 2009


Author: oxygene
Date: 2009-05-13 18:27:25 +0200 (Wed, 13 May 2009)
New Revision: 4281

Modified:
   trunk/coreboot-v2/src/arch/i386/boot/boot.c
   trunk/coreboot-v2/src/arch/ppc/boot/boot.c
   trunk/coreboot-v2/src/boot/elfboot.c
   trunk/coreboot-v2/src/boot/selfboot.c
   trunk/coreboot-v2/src/include/boot/elf.h
Log:
Allow dynamic size for the {s,}elfboot bounce buffer.
Use that to fix selfboot with compressed payloads.

Signed-off-by: Patrick Georgi <patrick.georgi at coresystems.de>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>


Modified: trunk/coreboot-v2/src/arch/i386/boot/boot.c
===================================================================
--- trunk/coreboot-v2/src/arch/i386/boot/boot.c	2009-05-13 14:39:59 UTC (rev 4280)
+++ trunk/coreboot-v2/src/arch/i386/boot/boot.c	2009-05-13 16:27:25 UTC (rev 4281)
@@ -68,7 +68,7 @@
 	
 }
 
-void jmp_to_elf_entry(void *entry, unsigned long buffer)
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long bounce_size)
 {
 	extern unsigned char _ram_seg, _eram_seg;
 	unsigned long lb_start, lb_size;
@@ -79,7 +79,7 @@
 
 	lb_start = (unsigned long)&_ram_seg;
 	lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
-	adjust = buffer + lb_size - lb_start;
+	adjust = buffer + bounce_size - lb_start;
 
 	adjusted_boot_notes = (unsigned long)&elf_boot_notes;
 	adjusted_boot_notes += adjust; 

Modified: trunk/coreboot-v2/src/arch/ppc/boot/boot.c
===================================================================
--- trunk/coreboot-v2/src/arch/ppc/boot/boot.c	2009-05-13 14:39:59 UTC (rev 4280)
+++ trunk/coreboot-v2/src/arch/ppc/boot/boot.c	2009-05-13 16:27:25 UTC (rev 4281)
@@ -16,7 +16,7 @@
 	
 }
 
-void jmp_to_elf_entry(void *entry, unsigned long buffer)
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long bounce_size)
 {
 	void (*kernel_entry)(void);       
 

Modified: trunk/coreboot-v2/src/boot/elfboot.c
===================================================================
--- trunk/coreboot-v2/src/boot/elfboot.c	2009-05-13 14:39:59 UTC (rev 4280)
+++ trunk/coreboot-v2/src/boot/elfboot.c	2009-05-13 16:27:25 UTC (rev 4281)
@@ -122,6 +122,8 @@
  * 
  */
 
+static unsigned long bounce_size;
+
 static unsigned long get_bounce_buffer(struct lb_memory *mem)
 {
 	unsigned long lb_size;
@@ -130,7 +132,8 @@
 	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_size + lb_size;
+	bounce_size = lb_size;
+	lb_size = bounce_size + lb_size;
 	mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
 	buffer = 0;
 	for(i = 0; i < mem_entries; i++) {
@@ -610,7 +613,7 @@
 	post_code(0xfe);
 
 	/* Jump to kernel */
-	jmp_to_elf_entry(entry, bounce_buffer);
+	jmp_to_elf_entry(entry, bounce_buffer, bounce_size);
 	return 1;
 
  out:

Modified: trunk/coreboot-v2/src/boot/selfboot.c
===================================================================
--- trunk/coreboot-v2/src/boot/selfboot.c	2009-05-13 14:39:59 UTC (rev 4280)
+++ trunk/coreboot-v2/src/boot/selfboot.c	2009-05-13 16:27:25 UTC (rev 4281)
@@ -92,7 +92,9 @@
  * 
  */
 
-static unsigned long get_bounce_buffer(struct lb_memory *mem)
+static unsigned long bounce_size, bounce_buffer;
+
+static void get_bounce_buffer(struct lb_memory *mem, unsigned long bounce_size)
 {
 	unsigned long lb_size;
 	unsigned long mem_entries;
@@ -100,7 +102,7 @@
 	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_size + lb_size;
+	lb_size = bounce_size + lb_size;
 	mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
 	buffer = 0;
 	for(i = 0; i < mem_entries; i++) {
@@ -123,7 +125,7 @@
 			continue;
 		buffer = tbuffer;
 	}
-	return buffer;
+	bounce_buffer = buffer;
 }
 
 static int valid_area(struct lb_memory *mem, unsigned long buffer,
@@ -180,24 +182,34 @@
 	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)
+{
+	unsigned long start, end;
+	start = seg->s_dstaddr;
+	end = start + seg->s_memsz;
+	return !((end <= lb_start) || (start >= lb_end));
+}
+
 static void relocate_segment(unsigned long buffer, struct segment *seg)
 {
 	/* Modify all segments that want to load onto coreboot
 	 * to load onto the bounce buffer instead.
 	 */
-	unsigned long lb_start = (unsigned long)&_ram_seg;
-	unsigned long lb_end = (unsigned long)&_eram_seg;
 	unsigned long start, middle, end;
 
 	printk_spew("lb: [0x%016lx, 0x%016lx)\n", 
 		lb_start, lb_end);
 
+	/* I don't conflict with coreboot so get out of here */
+	if (!overlaps_coreboot(seg))
+		return;
+
 	start = seg->s_dstaddr;
 	middle = start + seg->s_filesz;
 	end = start + seg->s_memsz;
-	/* I don't conflict with coreboot so get out of here */
-	if ((end <= lb_start) || (start >= lb_end))
-		return;
 
 	printk_spew("segment: [0x%016lx, 0x%016lx, 0x%016lx)\n", 
 		start, middle, end);
@@ -297,7 +309,7 @@
 
 static int build_self_segment_list(
 	struct segment *head, 
-	unsigned long bounce_buffer, struct lb_memory *mem,
+	struct lb_memory *mem,
 	struct cbfs_payload *payload, u32 *entry)
 {
 	struct segment *new;
@@ -369,32 +381,47 @@
 		new->phdr_prev = head->phdr_prev;
 		head->phdr_prev->phdr_next  = new;
 		head->phdr_prev = new;
-
-		/* Verify the memory addresses in the segment are valid */
-		if (!valid_area(mem, bounce_buffer, new->s_dstaddr, new->s_memsz)) 
-			goto out;
-
-		/* Modify the segment to load onto the bounce_buffer if necessary.
-		 */
-		relocate_segment(bounce_buffer, new);
 	}
 	return 1;
- out:
-	return 0;
 }
 
 static int load_self_segments(
-	struct segment *head, struct cbfs_payload *payload)
+	struct segment *head,
+	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;
+		unsigned long bounce = ptr->s_dstaddr + ptr->s_memsz - lb_start;
+		if (bounce > required_bounce_size) required_bounce_size = bounce;
+	}
+	get_bounce_buffer(mem, required_bounce_size);
+	if (!bounce_buffer) {
+		printk_err("Could not find a bounce buffer...\n");
+		return 0;
+	}
+	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, *middle, *end, *src;
 		printk_debug("Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
 			ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
 		
+		/* Modify the segment to load onto the bounce_buffer if necessary.
+		 */
+		relocate_segment(bounce_buffer, ptr);
+
+		printk_debug("Post relocation: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
+			ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
+
 		/* Compute the boundaries of the segment */
 		dest = (unsigned char *)(ptr->s_dstaddr);
 		src = (unsigned char *)(ptr->s_srcaddr);
@@ -454,21 +481,13 @@
 {
 	u32 entry=0;
 	struct segment head;
-	unsigned long bounce_buffer;
 
-	/* Find a bounce buffer so I can load to coreboot's current location */
-	bounce_buffer = get_bounce_buffer(mem);
-	if (!bounce_buffer) {
-		printk_err("Could not find a bounce buffer...\n");
-		goto out;
-	}
-
 	/* Preprocess the self segments */
-	if (!build_self_segment_list(&head, bounce_buffer, mem, payload, &entry))
+	if (!build_self_segment_list(&head, mem, payload, &entry))
 		goto out;
 
 	/* Load the segments */
-	if (!load_self_segments(&head, payload))
+	if (!load_self_segments(&head, mem, payload))
 		goto out;
 
 	printk_spew("Loaded segments\n");
@@ -480,7 +499,7 @@
 	post_code(0xfe);
 
 	/* Jump to kernel */
-	jmp_to_elf_entry((void*)entry, bounce_buffer);
+	jmp_to_elf_entry((void*)entry, bounce_buffer, bounce_size);
 	return 1;
 
  out:

Modified: trunk/coreboot-v2/src/include/boot/elf.h
===================================================================
--- trunk/coreboot-v2/src/include/boot/elf.h	2009-05-13 14:39:59 UTC (rev 4280)
+++ trunk/coreboot-v2/src/include/boot/elf.h	2009-05-13 16:27:25 UTC (rev 4281)
@@ -390,7 +390,7 @@
 #endif
 
 int elf_check_arch(Elf_ehdr *ehdr);
-void jmp_to_elf_entry(void *entry, unsigned long buffer);
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long bounce_size);
 struct lb_memory;
 int elfboot(struct lb_memory *mem);
 /* Temporary compile fix, FILO should be dropped from coreboot */





More information about the coreboot mailing list