Hi,

attached is the multiple payload support originally by Uwe Hermann. I am
lazy to attach Uwe's Kconfig and Makefile changes, get them at:
http://www.linuxbios.org/pipermail/linuxbios/2007-August/023728.html

To be less obtrusive, created a run_payload function which does the
logic already present. This function will be called in every iteration
(normal/payload0..9 and as a last resolt normal/payload).

Added pusha/popa around payload entry points. Not a big safety otoh.

In no means is this mature enough for a commit.

--
Alex

Index: arch/x86/stage1.c
===================================================================
--- arch/x86/stage1.c	(revision 494)
+++ arch/x86/stage1.c	(working copy)
@@ -68,6 +68,49 @@
 	return -1;
 }
 
+static inline int run_payload(struct mem_file *archive, char *name, struct lb_memory *mem)
+{
+	int ret, i;
+	struct mem_file result;
+	void *entry;
+	
+	printk(BIOS_SPEW, "Try payload: %s\n", name);
+
+	ret = find_file(archive, name, &result);
+	if (! ret) {
+		__asm__ __volatile__ ("pusha");
+		ret = legacy(archive, name, (void *)UNCOMPRESS_AREA, mem);
+		__asm__ __volatile__ ("popa");
+		return ret;
+	}
+
+	/* new style lar boot. Install all the files in memory. 
+	  * By convention we take the entry point from the first 
+	  * one. Look for a cmdline as well. 
+	  */
+	for(i = 0, entry = (void *)0; ;i++) {
+		char filename[64];
+		void *newentry;
+		sprintf(filename, "%s/segment%d", name, i);
+		archive->len = *(u32 *)0xfffffff4;
+		archive->start =(void *)(0UL-archive->len);
+		newentry = load_file(archive, filename);
+		printk(BIOS_SPEW, "newentry is %p\n", newentry);
+		if (newentry == (void *)-1)
+			break;
+		if (! entry)
+			entry = newentry;
+	}
+	printk(BIOS_SPEW, "all loaded, entry %p\n", entry);
+	if (entry) {
+		__asm__ __volatile__ ("pusha");
+		run_address(entry);
+		__asm__ __volatile__ ("popa");
+		return 1;
+	}
+	return -1;
+}
+
 /*
  * This function is called from assembler code whith its argument on the
  * stack. Force the compiler to generate always correct code for this case.
@@ -75,10 +118,10 @@
 void __attribute__((stdcall)) stage1_main(u32 bist)
 {
 	int ret;
-	struct mem_file archive, result;
+	struct mem_file archive;
 	int elfboot_mem(struct lb_memory *mem, void *where, int size);
-	void *entry;
 	int i;
+	char filename[40];
 
 	/* we can't statically init this hack. */
 	unsigned char faker[64];
@@ -165,32 +208,16 @@
 
 	printk(BIOS_DEBUG, "Stage2 code done.\n");
 
-	ret = find_file(&archive, "normal/payload", &result);
-	if (! ret)
-		legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem);
+	#define MAX_PAYLOADS 10
+	for (i = 0; i < MAX_PAYLOADS; i++) {
+		sprintf((char *)&filename, "normal/payload%d", i);
+		run_payload(&archive, (char *)&filename, mem);
+	}
 
+	/* Fallback to old normal/payload */
+	sprintf((char *)&filename, "normal/payload");
+	run_payload(&archive, (char *)&filename, mem);
 
-	/* new style lar boot. Install all the files in memory. 
-	  * By convention we take the entry point from the first 
-	  * one. Look for a cmdline as well. 
-	  */
-	for(i = 0, entry = (void *)0; ;i++) {
-		char filename[64];
-		void *newentry;
-		sprintf(filename, "normal/payload/segment%d", i);
-		archive.len = *(u32 *)0xfffffff4;
-		archive.start =(void *)(0UL-archive.len);
-		newentry = load_file(&archive, filename);
-		printk(BIOS_SPEW, "newentry is %p\n", newentry);
-		if (newentry == (void *)-1)
-			break;
-		if (! entry)
-			entry = newentry;
-	}
-	printk(BIOS_SPEW, "all loaded, entry %p\n", entry);
-	if (entry)
-		run_address(entry);
-
 	die("FATAL: No usable payload found.\n");
 
 	die ("FATAL: Last stage returned to LinuxBIOS.\n");
-- 
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to