This patch allows to boot from bootsector of first bootable partition
using "boot hd:%BOOT"

As explained in:

"PowerPC Microprocessor Common Hardware Reference Platform (CHRP)
System binding to:
IEEE Std 1275-1994 Standard for Boot (Initialization, Configuration) 
Firmware
Revision: 1.8"

"Chapter 11.1.2. Open Method Algorith"

Signed-off-by: Laurent Vivier <Laurent@vivier.info>
---
 arch/ppc/qemu/main.c  |   63 +++++++++++--------------------------
 fs/grubfs/grubfs_fs.c |    2 +
 modules/disk-label.c  |   84 +++++++++++++++++++++++++++++---------------------
 modules/mac-parts.c   |   23 ++++++++++++-
 4 files changed, 92 insertions(+), 80 deletions(-)

Index: openbios-devel/modules/disk-label.c
===================================================================
--- openbios-devel.orig/modules/disk-label.c	2009-08-11 22:20:03.000000000 +0200
+++ openbios-devel/modules/disk-label.c	2009-08-11 22:47:59.000000000 +0200
@@ -57,42 +57,28 @@
 static void
 dlabel_open( dlabel_info_t *di )
 {
-	char *s, *filename, *parstr;
+	char *path;
 	char block0[512];
 	phandle_t ph;
 	int fd, success=0;
 	xt_t xt;
 
-	parstr = my_args_copy();
-	DPRINTF("dlabel-open '%s'\n", parstr );
+	path = my_args_copy();
+	DPRINTF("dlabel-open '%s'\n", path );
+
+	/* open disk interface */
 
 	if( (fd=open_ih(my_parent())) == -1 )
 		goto out;
 	di->fd = fd;
 
-	/* argument format: parnum,filename */
-	s = parstr;
-	filename = NULL;
-	if( s ) {
-            if( *s == '-' || isdigit(*s) ||
-                (*s >= 'a' && *s < ('a' + 8)
-                 && (*(s + 1) == ',' || *(s + 1) == '\0'))) {
-			if( (s=strpbrk(parstr,",")) ) {
-				filename = s+1;
-				*s = 0;
-			}
-		} else {
-			filename = s;
-			parstr = NULL;
-			if( *s == ',' )
-				filename++;
-		}
-	}
-	DPRINTF("parstr %s filename %s\n", parstr, filename);
-
-        /* try to see if there is a filesystem without partition */
+	/* try to see if there is a filesystem without partition,
+	 * like ISO9660. This is needed to boot openSUSE 11.1 CD
+	 * which uses "boot &device;:1,\suseboot\yaboot.ibm"
+	 * whereas HFS+ partition is #2
+	 */
 
-        if (atol(parstr) == 1) {
+	if ( atol(path) == 1 ) {
 		PUSH_ih( my_self() );
 		selfword("find-filesystem");
 		ph = POP_ph();
@@ -109,11 +95,7 @@
 				call_parent(xt);
 				di->block_size = POP();
 			}
-			push_str( filename );
-			PUSH_ph( ph );
-			fword("interpose");
-			success = 1;
-			goto out;
+			goto open_file;
 		}
 	}
 
@@ -127,7 +109,7 @@
 
 	/* open partition package */
 	if( ph ) {
-		if( !(di->part_ih=open_package(parstr, ph)) )
+		if( !(di->part_ih=open_package(path, ph)) )
 			goto out;
 		if( !(xt=find_ih_method("get-info", di->part_ih)) )
 			goto out;
@@ -143,24 +125,56 @@
 			call_package(xt, di->part_ih);
 			di->block_size = POP();
 		}
+	} else {
+		/* unknown (or missing) partition map,
+		 * try the whole disk
+		 */
+		di->offs_hi = 0;
+		di->offs_lo = 0;
+		di->size_hi = 0;
+		di->size_lo = 0;
+		di->part_ih = 0;
+		di->type = -1;
+		di->block_size = 512;
+		xt = find_parent_method("block-size");
+		if (xt) {
+			call_parent(xt);
+			di->block_size = POP();
+		}
 	}
 
 	/* probe for filesystem */
+
 	PUSH_ih( my_self() );
 	selfword("find-filesystem");
 	ph = POP_ph();
 	if( ph ) {
+		char *s, *filename;
+open_file:
+		/* argument format: parnum,filename */
+		s = path;
+		filename = NULL;
+		if( *s == '-' || isdigit(*s) ||
+		    (*s >= 'a' && *s < ('a' + 8)
+		     && (*(s + 1) == ',' || *(s + 1) == '\0'))) {
+			if( (s=strpbrk(path,",")) ) {
+				filename = s+1;
+			}
+		} else {
+			filename = s;
+			if( *s == ',' )
+				filename++;
+		}
+		DPRINTF("filename %s\n", filename);
 		push_str( filename );
 		PUSH_ph( ph );
 		fword("interpose");
-	} else if( filename ) {
-		goto out;
 	}
 	success = 1;
 
  out:
-	if( parstr )
-		free( parstr );
+	if( path )
+		free( path );
 	if( !success ) {
 		dlabel_close( di );
 		RET(0);
Index: openbios-devel/modules/mac-parts.c
===================================================================
--- openbios-devel.orig/modules/mac-parts.c	2009-08-11 22:20:03.000000000 +0200
+++ openbios-devel/modules/mac-parts.c	2009-08-11 22:47:59.000000000 +0200
@@ -49,13 +49,25 @@
 	desc_map_t dmap;
 	part_entry_t par;
 	int ret = 0;
+	int want_bootcode = 0;
 
+	DPRINTF("partition %s\n", str);
 	if( str ) {
+		char *tmp;
 		parnum = atol(str);
 		if( *str == 0 || *str == ',' )
 			parnum = -1;
+		tmp = str;
+		while (*tmp && *tmp != ',')
+			tmp++;
+		if (*tmp == ',')
+			tmp++;
+		if (strcmp(tmp, "%BOOT") == 0)
+			want_bootcode = 1;
+		free(str);
 	}
 
+	DPRINTF("want_bootcode %d\n", want_bootcode);
 	DPRINTF("macparts_open %d\n", parnum);
 	SEEK( 0 );
 	if( READ(&dmap, sizeof(dmap)) != sizeof(dmap) )
@@ -97,6 +109,10 @@
 				di->blocksize =(uint)bs;
 				di->offs = (llong)par.pmPyPartStart * bs;
 				di->size = (llong)par.pmPartBlkCnt * bs;
+				if (want_bootcode) {
+					di->offs += (llong)par.pmLgBootStart*bs;
+					di->size = (llong)par.pmBootSize;
+				}
 				ret = -1;
 				goto out;
 			}
@@ -132,10 +148,13 @@
 	di->blocksize =(uint)bs;
 	di->offs = (llong)par.pmPyPartStart * bs;
 	di->size = (llong)par.pmPartBlkCnt * bs;
+	if (want_bootcode) {
+		di->offs += (llong)par.pmLgBootStart * bs;
+		di->size = (llong)par.pmBootSize;
+	}
 
 out:
-	if (str)
-		free(str);
+	DPRINTF("offset 0x%llx size 0x%llx\n", di->offs, di->size);
 	PUSH( ret);
 }
 
Index: openbios-devel/arch/ppc/qemu/main.c
===================================================================
--- openbios-devel.orig/arch/ppc/qemu/main.c	2009-08-11 22:20:03.000000000 +0200
+++ openbios-devel/arch/ppc/qemu/main.c	2009-08-11 22:58:31.000000000 +0200
@@ -321,68 +321,45 @@
     close_io( fd );
 }
 
-#define QUIK_SECOND_BASEADDR	0x3e0000
-#define QUIK_FIRST_BASEADDR	0x3f4000
-#define QUIK_SECOND_SIZE	(QUIK_FIRST_BASEADDR - QUIK_SECOND_BASEADDR)
-#define QUIK_FIRST_INFO_OFF	0x2c8
-
-struct first_info {
-	char		quik_vers[8];
-	int		nblocks;
-	int		blocksize;
-	unsigned	second_base;
-	int		conf_part;
-	char		conf_file[32];
-	unsigned	blknos[64];
-};
+#define OLDWORLD_BOOTCODE_BASEADDR	(0x3f4000)
 
 static void
-quik_startup( void )
+oldworld_boot( void )
 {
 	int fd;
-	int len;
-	const char *path = "hd:2";
-	union {
-		char buffer[1024];
-		int first_word;
-		struct {
-			char pad[QUIK_FIRST_INFO_OFF];
-			struct first_info fi;
-		} fi;
-	} u;
+	int len, total;
+	const char *path = "hd:,%BOOT";
+	char *bootcode;
 
 	if ((fd = open_io(path)) == -1) {
 		ELF_DPRINTF("Can't open %s\n", path);
 		return;
 	}
 
-	seek_io(fd, 0);
-	len = read_io(fd, u.buffer, sizeof(u));
-	close_io( fd );
 
-	if (len == -1) {
-		ELF_DPRINTF("Can't read %s\n", path);
-		return;
+	total = 0;
+	bootcode = (char*)OLDWORLD_BOOTCODE_BASEADDR;
+	while(1) {
+		if (seek_io(fd, total) == -1)
+			break;
+		len = read_io(fd, bootcode, 512);
+		bootcode += len;
+		total += len;
 	}
 
-	/* is it quik ? */
+	close_io( fd );
 
-	if (memcmp(u.fi.fi.quik_vers, "QUIK", 4))
+	if (total == -1) {
+		ELF_DPRINTF("Can't read %s\n", path);
 		return;
+	}
 
 	encode_bootpath(path, "Linux");
 
-	if( ofmem_claim( QUIK_FIRST_BASEADDR, len, 0 ) == -1 )
-		fatal_error("Claim failed!\n");
-
-	memcpy((char*)QUIK_FIRST_BASEADDR, u.buffer, len);
-
-	/* quik fist level doesn't claim second level memory */
-
-	if( ofmem_claim( QUIK_SECOND_BASEADDR, QUIK_SECOND_SIZE, 0 ) == -1 )
+	if( ofmem_claim( OLDWORLD_BOOTCODE_BASEADDR, total, 0 ) == -1 )
 		fatal_error("Claim failed!\n");
 
-	call_elf(0, 0, QUIK_FIRST_BASEADDR);
+	call_elf(0, 0, OLDWORLD_BOOTCODE_BASEADDR);
 
         return;
 }
@@ -495,7 +472,7 @@
 	        check_preloaded_kernel();
 	}
 	if (boot_device == 'c') {
-		quik_startup();
+		oldworld_boot();
 	}
 	yaboot_startup();
 }
Index: openbios-devel/fs/grubfs/grubfs_fs.c
===================================================================
--- openbios-devel.orig/fs/grubfs/grubfs_fs.c	2009-08-11 22:59:35.000000000 +0200
+++ openbios-devel/fs/grubfs/grubfs_fs.c	2009-08-11 22:59:43.000000000 +0200
@@ -298,7 +298,9 @@
 	}
 
 	if( seek_io(curfs->dev_fd, offs) ) {
+#ifdef CONFIG_DEBUG_FS
 		printk("seek failure\n");
+#endif
 		return -1;
 	}
 	return (read_io(curfs->dev_fd, buf, byte_len) == byte_len) ? 1:0;
