[OpenBIOS] [commit] r791 - in trunk/openbios-devel: fs/grubfs include/fs packages

repository service svn at openbios.org
Tue Jun 8 22:59:09 CEST 2010


Author: mcayland
Date: Tue Jun  8 22:59:08 2010
New Revision: 791
URL: http://tracker.coreboot.org/trac/openbios/changeset/791

Log:
As documented on the mailing lists, change the interposition order of the disk packages from:

cdrom -> deblocker -> disk-label -> (misc-files | sun-parts | pc-parts | mac-parts) 

to:

cdrom -> deblocker -> disk-label -> (sun-parts | pc-parts | mac-parts) -> misc-files 

This makes the overall code much simpler, since instead of passing get-info structures between the different layers to work out 
the current device offset, each package can simply maintain its own offsets and bubble them back up to the parent.

There are also many, many bugfixes present is patch, some of which are given below:

- Add debugging in /packages/misc-files, augment debugging in all other disk packages
- Fix alignment issue in /packages/pc-parts so it works correctly on strictly align archs, e.g. SPARC64
- Fix parsing of [<id>,][filename] arguments to load (in preparation for next patch set)
- Fix byte-swapping issues in /packages/mac-parts (in theory it should now work regardless of endian)

Modified:
   trunk/openbios-devel/fs/grubfs/grubfs_fs.c
   trunk/openbios-devel/include/fs/fs.h
   trunk/openbios-devel/packages/disk-label.c
   trunk/openbios-devel/packages/disk-label.fs
   trunk/openbios-devel/packages/mac-parts.c
   trunk/openbios-devel/packages/mac-parts.h
   trunk/openbios-devel/packages/misc-files.c
   trunk/openbios-devel/packages/pc-parts.c
   trunk/openbios-devel/packages/sun-parts.c

Modified: trunk/openbios-devel/fs/grubfs/grubfs_fs.c
==============================================================================
--- trunk/openbios-devel/fs/grubfs/grubfs_fs.c	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/fs/grubfs/grubfs_fs.c	Tue Jun  8 22:59:08 2010	(r791)
@@ -20,6 +20,7 @@
 #include "filesys.h"
 #include "glue.h"
 #include "libc/diskio.h"
+#include "libc/vsprintf.h"
 
 /************************************************************************/
 /* 	grub GLOBALS (horrible... but difficult to fix)			*/
@@ -97,6 +98,8 @@
 	const struct fsys_entry *fsys;
 	grubfile_t *fd;
 	int		dev_fd;
+	llong	offset;		/* Offset added onto each device read; should only ever be non-zero
+				when probing a partition for a filesystem */
 } grubfs_t;
 
 static grubfs_t dummy_fs;
@@ -199,7 +202,7 @@
 	printk("Path=%s\n",path);
 #endif
 	if (!curfs->fsys->dir_func((char *) path)) {
-		printk("File not found\n");
+		forth_printf("File not found\n");
 		return NULL;
 	}
 	ret=malloc(sizeof(grubfile_t));
@@ -249,6 +252,7 @@
 	curfs=&dummy_fs;
 
 	curfs->dev_fd = fd;
+	curfs->offset = 0;
 
 	for (i = 0; i < sizeof(fsys_table)/sizeof(fsys_table[0]); i++) {
 #ifdef CONFIG_DEBUG_FS
@@ -275,6 +279,31 @@
 	return -1;
 }
 
+/* Probe for filesystem (with partition offset); returns 0 on success */
+int
+fs_grubfs_probe( int fd, llong offs )
+{
+	int i;
+
+	curfs = &dummy_fs;
+
+	curfs->dev_fd = fd;
+	curfs->offset = offs;
+
+	for (i = 0; i < sizeof(fsys_table)/sizeof(fsys_table[0]); i++) {
+#ifdef CONFIG_DEBUG_FS
+		printk("Probing for %s\n", fsys_table[i].name);
+#endif
+		if (fsys_table[i].mount_func())
+			return 0;
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	printk("Unknown filesystem type\n");
+#endif
+	return -1;
+}
+
 
 /************************************************************************/
 /*	I/O glue (called by grub source)				*/
@@ -297,7 +326,7 @@
 		return -1;
 	}
 
-	if( seek_io(curfs->dev_fd, offs) ) {
+	if( seek_io(curfs->dev_fd, offs + curfs->offset) ) {
 #ifdef CONFIG_DEBUG_FS
 		printk("seek failure\n");
 #endif

Modified: trunk/openbios-devel/include/fs/fs.h
==============================================================================
--- trunk/openbios-devel/include/fs/fs.h	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/include/fs/fs.h	Tue Jun  8 22:59:08 2010	(r791)
@@ -77,6 +77,7 @@
 
 #ifdef CONFIG_GRUBFS
 extern int		fs_grubfs_open( int fd, fs_ops_t *fs );
+extern int 		fs_grubfs_probe( int fd, llong offs );
 #else
 static inline int	fs_grubfs_open( int fd, fs_ops_t *fs ) { return -1; }
 #endif

Modified: trunk/openbios-devel/packages/disk-label.c
==============================================================================
--- trunk/openbios-devel/packages/disk-label.c	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/disk-label.c	Tue Jun  8 22:59:08 2010	(r791)
@@ -17,6 +17,7 @@
 #include "config.h"
 #include "libopenbios/bindings.h"
 #include "libc/diskio.h"
+#include "libc/vsprintf.h"
 #include "packages.h"
 
 //#define DEBUG_DISK_LABEL
@@ -29,7 +30,9 @@
 #endif
 
 typedef struct {
-	int		fd;
+	xt_t 		parent_seek_xt;
+	xt_t 		parent_tell_xt;
+	xt_t		parent_read_xt;
 
         ucell	        offs_hi, offs_lo;
         ucell	        size_hi, size_lo;
@@ -44,117 +47,81 @@
 
 /* ( -- ) */
 static void
-dlabel_close( dlabel_info_t *di )
+dlabel_close( __attribute__((unused))dlabel_info_t *di )
 {
-	if( di->part_ih )
-		close_package( di->part_ih );
-
-	if( di->fd )
-		close_io( di->fd );
 }
 
 /* ( -- success? ) */
 static void
 dlabel_open( dlabel_info_t *di )
 {
-	const char *s, *filename;
 	char *path;
 	char block0[512];
 	phandle_t ph;
-	int fd, success=0;
-	xt_t xt;
+	int success=0;
+	cell status;
 
 	path = my_args_copy();
 	if (!path) {
 		path = strdup("");
 	}
-        if (!path) {
-                goto out;
-        }
+
 	DPRINTF("dlabel-open '%s'\n", path );
 
-	/* open disk interface */
+	/* Find parent methods */
+	di->parent_seek_xt = find_parent_method("seek");
+	di->parent_tell_xt = find_parent_method("tell");
+        di->parent_read_xt = find_parent_method("read");	
+
+	/* Read first block from parent device */
+	DPUSH(0);
+	call_package(di->parent_seek_xt, my_parent());
+	POP();
 
-	if( (fd=open_ih(my_parent())) == -1 )
+	PUSH((ucell)block0);
+	PUSH(sizeof(block0));
+	call_package(di->parent_read_xt, my_parent());
+	status = POP();
+	if (status != sizeof(block0))
 		goto out;
-	di->fd = fd;
-
-	/* argument format: parnum,filename */
-
-	s = path;
-	filename = "";
-	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);
 
-	/* find partition handler */
-	seek_io( fd, 0 );
-	if( read_io(fd, block0, sizeof(block0)) != sizeof(block0) )
-		goto out;
+	/* Find partition handler */
 	PUSH( (ucell)block0 );
 	selfword("find-part-handler");
 	ph = POP_ph();
-
-	/* open partition package */
 	if( ph ) {
-		if( !(di->part_ih=open_package(path, ph)) )
-			goto out;
-		if( !(xt=find_ih_method("get-info", di->part_ih)) )
-			goto out;
-		call_package( xt , di->part_ih );
-		di->size_hi = POP();
-		di->size_lo = POP();
-		di->offs_hi = POP();
-		di->offs_lo = POP();
-		di->type = POP();
-		di->block_size = 512;
-		xt = find_ih_method("block-size", di->part_ih);
-		if (xt) {
-			call_package(xt, di->part_ih);
-			di->block_size = POP();
-		}
+		/* We found a suitable partition handler, so interpose it */
+		DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx "\n", ph);
+
+		push_str(path);
+		PUSH_ph(ph);
+		fword("interpose");	
+
+		success = 1;
 	} 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 */
+		DPRINTF("Unknown or missing partition map; trying whole disk\n");
 
-	PUSH_ih( my_self() );
-	selfword("find-filesystem");
-	ph = POP_ph();
-	if( ph ) {
-		push_str( filename );
-		PUSH_ph( ph );
-		fword("interpose");
-	} else if (*filename && strcmp(filename, "%BOOT") != 0) {
-		goto out;
+		/* Probe for filesystem from start of device */
+		DPUSH ( 0 );	
+		PUSH_ih( my_self() );
+		selfword("find-filesystem");
+		ph = POP_ph();
+		if( ph ) {
+			push_str( path );
+			PUSH_ph( ph );
+			fword("interpose");
+		} else if (*path && strcmp(path, "%BOOT") != 0) {
+			goto out;
+		}
+
+		success = 1;
 	}
-	success = 1;
 
- out:
+out:
 	if( path )
 		free( path );
 	if( !success ) {
@@ -168,61 +135,26 @@
 static void
 dlabel_read( dlabel_info_t *di )
 {
-	int ret, len = POP();
-	char *buf = (char*)POP();
-	llong pos = tell( di->fd );
-	ducell offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
-	ducell size = ((ducell)di->size_hi << BITS) | di->size_lo;
-
-	if (size && len > pos - offs + size) {
-		len = size - (pos - offs);
-	}
-
-	ret = read_io( di->fd, buf, len );
-	PUSH( ret );
+	/* Call back up to parent */
+	call_package(di->parent_read_xt, my_parent());
 }
 
 /* ( pos.d -- status ) */
 static void
 dlabel_seek( dlabel_info_t *di )
 {
-	llong pos = DPOP();
-	int ret;
-	ducell offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
-	ducell size = ((ducell)di->size_hi << BITS) | di->size_lo;
-
-	DPRINTF("dlabel_seek %llx [%llx, %llx]\n", pos, offs, size);
-	if( pos != -1 )
-		pos += offs;
-	else if( size ) {
-		DPRINTF("Seek EOF\n");
-		pos = offs + size;
-	} else {
-		/* let parent handle the EOF seek. */
-	}
-	DPRINTF("dlabel_seek: 0x%llx\n", pos );
-	if (size && (pos - offs >= size )) {
-		PUSH(-1);
-		return;
-	}
-
-	ret = seek_io( di->fd, pos );
-	PUSH( ret );
+	/* Call back up to parent */
+	call_package(di->parent_seek_xt, my_parent());
 }
 
 /* ( -- filepos.d ) */
 static void
 dlabel_tell( dlabel_info_t *di )
 {
-	llong pos = tell( di->fd );
-	ducell offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
-	if( pos != -1 )
-		pos -= offs;
-
-	DPUSH( pos );
+	/* Call back up to parent */
+	call_package(di->parent_tell_xt, my_parent());
 }
 
-
 /* ( addr len -- actual ) */
 static void
 dlabel_write( __attribute__((unused)) dlabel_info_t *di )
@@ -231,39 +163,32 @@
 	PUSH( -1 );
 }
 
-/* ( rel.d -- abs.d ) */
-static void
-dlabel_offset( dlabel_info_t *di )
-{
-	ullong rel = DPOP();
-	ducell offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
-	rel += offs;
-	DPUSH( rel );
-}
-
 /* ( addr -- size ) */
 static void
 dlabel_load( __attribute__((unused)) dlabel_info_t *di )
 {
-	/* XXX: try the load method of the part package */
+	/* Try the load method of the part package */
+	char *buf;
+	xt_t xt;
 
-	printk("Can't load from this device!\n");
-	POP();
-	PUSH(0);
-}
+	buf = (char *)POP();
 
-static void
-dlabel_block_size( dlabel_info_t *di )
-{
-	PUSH(di->block_size);
+	DPRINTF("load invoked with address %p\n", buf);
+
+	xt = find_ih_method("load", di->part_ih);
+	if (!xt) {
+		forth_printf("load currently not implemented for /packages/disk-label\n");
+		PUSH(0);
+		return;
+	}
+
+	call_package(xt, di->part_ih);
 }
 
 NODE_METHODS( dlabel ) = {
 	{ "open",	dlabel_open 	},
 	{ "close",	dlabel_close 	},
-	{ "offset",	dlabel_offset 	},
 	{ "load",	dlabel_load 	},
-	{ "block-size", dlabel_block_size },
 	{ "read",	dlabel_read 	},
 	{ "write",	dlabel_write 	},
 	{ "seek",	dlabel_seek 	},

Modified: trunk/openbios-devel/packages/disk-label.fs
==============================================================================
--- trunk/openbios-devel/packages/disk-label.fs	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/disk-label.fs	Tue Jun  8 22:59:08 2010	(r791)
@@ -36,19 +36,32 @@
     r> drop 0
   ;
 
-  : find-filesystem ( ih -- ph | 0 )
-    >r fs-handlers
+  : find-filesystem ( offs.d ih -- ph | 0 )
+    >r fs-handlers	( offs.d listhead )
     begin list-get while
-      ( nextlist dictptr )
-      r@ over @ execute if
-        ( nextlist dictptr )
-        na1+ @ r> rot 2drop exit
-      then
-      drop
+      2over	( offs.d nextlist dictptr offs.d )
+      r@ 	( offs.d nextlist dictptr offs.d ih )
+	3 pick	( offs.d nextlist dictptr offs.d ih dictptr )
+ 	@	( offs.d nextlist dictptr offs.d ih probe-xt )
+	execute ( offs.d nextlist dictptr flag? )
+	if
+        	( offs.d nextlist dictptr )
+        	na1+	( offs.d nextlist dictptr+1 ) 
+		@ 	( offs.d nextlist phandle )
+		r>	( offs.d nextlist phandle ih )
+		rot	( offs.d phandle ih nextlist )
+		2drop	( offs.d phandle )
+ 		-rot	( phandle offs.d )
+		2drop	( phandle )
+		exit
+      	then
+      drop	( offs.d nextlist )
     repeat
+    2drop	( offs.d )
     r> drop 0
   ;
 
+
   : register-part-handler ( handler-ph -- )
     dup " probe" rot find-method
     0= abort" Missing probe method!"

Modified: trunk/openbios-devel/packages/mac-parts.c
==============================================================================
--- trunk/openbios-devel/packages/mac-parts.c	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/mac-parts.c	Tue Jun  8 22:59:08 2010	(r791)
@@ -17,8 +17,12 @@
 #include "config.h"
 #include "libopenbios/bindings.h"
 #include "mac-parts.h"
+#include "libc/byteorder.h"
+#include "libc/vsprintf.h"
 #include "packages.h"
 
+//#define CONFIG_DEBUG_MAC_PARTS
+
 #ifdef CONFIG_DEBUG_MAC_PARTS
 #define DPRINTF(fmt, args...) \
 do { printk("MAC-PARTS: " fmt , ##args); } while (0)
@@ -27,54 +31,77 @@
 #endif
 
 typedef struct {
-	ullong		offs;
-	ullong		size;
+	xt_t		seek_xt, read_xt;
+	ucell	        offs_hi, offs_lo;
+        ucell	        size_hi, size_lo;
 	uint		blocksize;
 } macparts_info_t;
 
 DECLARE_NODE( macparts, INSTALL_OPEN, sizeof(macparts_info_t), "+/packages/mac-parts" );
 
-
-#define SEEK( pos )		({ DPUSH(pos); call_parent(seek_xt); POP(); })
-#define READ( buf, size )	({ PUSH((ucell)buf); PUSH(size); call_parent(read_xt); POP(); })
+#define SEEK( pos )		({ DPUSH(pos); call_parent(di->seek_xt); POP(); })
+#define READ( buf, size )	({ PUSH((ucell)buf); PUSH(size); call_parent(di->read_xt); POP(); })
 
 /* ( open -- flag ) */
 static void
 macparts_open( macparts_info_t *di )
 {
 	char *str = my_args_copy();
-	xt_t seek_xt = find_parent_method("seek");
-	xt_t read_xt = find_parent_method("read");
-	int bs, parnum=0;
+	char *argstr = strdup("");
+	char *parstr = strdup("");
+	int bs, parnum=-1;
 	desc_map_t dmap;
 	part_entry_t par;
 	int ret = 0;
 	int want_bootcode = 0;
+	phandle_t ph;
+	ducell offs, size;
+
+	DPRINTF("macparts_open '%s'\n", str );
+
+	/* 
+		Arguments that we accept:
+		id: [0-7]
+		[(id,)][filespec]
+	*/
 
-	DPRINTF("partition %s\n", str);
 	if( str ) {
-		char *tmp;
-		char *comma = strchr(str, ',');
-		parnum = atol(str);
-		if( *str == 0 || *str == ',' )
+		if ( !strlen(str) )
 			parnum = -1;
-		if (comma) {
-			tmp = comma + 1;
-		} else {
-			if (*str >= '0' && *str <= '9') {
-				tmp = (char*)"";
+		else {
+			/* If end of string, we just have a partition id */
+			if (str[1] == '\0') {
+				parstr = str;
 			} else {
-				tmp = str;
-				parnum = -1;
+				/* If a comma, then we have a partition id plus argument */
+				if (str[1] == ',') {
+					str[1] = '\0';
+					parstr = str;
+					argstr = &str[2];
+				} else {
+					/* Otherwise we have just an argument */
+					argstr = str;
+				}
 			}
+		
+			/* Convert the id to a partition number */
+			if (strlen(parstr))
+				parnum = atol(parstr);
+
+			/* Detect if we are looking for the bootcode */
+			if (strcmp(argstr, "%BOOT") == 0)
+				want_bootcode = 1;
 		}
-		if (strcmp(tmp, "%BOOT") == 0)
-			want_bootcode = 1;
-		free(str);
 	}
 
+	DPRINTF("parstr: %s  argstr: %s  parnum: %d\n", parstr, argstr, parnum);
+
 	DPRINTF("want_bootcode %d\n", want_bootcode);
 	DPRINTF("macparts_open %d\n", parnum);
+
+	di->read_xt = find_parent_method("read");
+	di->seek_xt = find_parent_method("seek");
+
 	SEEK( 0 );
 	if( READ(&dmap, sizeof(dmap)) != sizeof(dmap) )
 		goto out;
@@ -82,17 +109,17 @@
 	/* partition maps might support multiple block sizes; in this case,
 	 * pmPyPartStart is typically given in terms of 512 byte blocks.
 	 */
-	bs = dmap.sbBlockSize;
+	bs = __be16_to_cpu(dmap.sbBlockSize);
 	if( bs != 512 ) {
 		SEEK( 512 );
 		READ( &par, sizeof(par) );
-		if( par.pmSig == DESC_PART_SIGNATURE )
+		if( __be16_to_cpu(par.pmSig) == DESC_PART_SIGNATURE )
 			bs = 512;
 	}
 	SEEK( bs );
 	if( READ(&par, sizeof(par)) != sizeof(par) )
 		goto out;
-        if (par.pmSig != DESC_PART_SIGNATURE)
+        if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE)
 		goto out;
 
         if (parnum == -1) {
@@ -101,28 +128,42 @@
 		/* see PowerPC Microprocessor CHRP bindings */
 
 		parnum = 1;
-		while (parnum <= par.pmMapBlkCnt) {
+		while (parnum <= __be32_to_cpu(par.pmMapBlkCnt)) {
 			SEEK( (bs * parnum) );
 			READ( &par, sizeof(par) );
-			if( par.pmSig != DESC_PART_SIGNATURE ||
-                            !par.pmPartBlkCnt )
+			if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE ||
+                            !__be16_to_cpu(par.pmPartBlkCnt) )
 				goto out;
 
+			DPRINTF("found partition type: %s\n", par.pmPartType);
+
 			if (firstHFS == -1 &&
 			    strcmp(par.pmPartType, "Apple_HFS") == 0)
 				firstHFS = parnum;
 
-			if( (par.pmPartStatus & kPartitionAUXIsBootValid) &&
-			    (par.pmPartStatus & kPartitionAUXIsValid) &&
-			    (par.pmPartStatus & kPartitionAUXIsAllocated) &&
-			    (par.pmPartStatus & kPartitionAUXIsReadable) &&
+			if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsBootValid) &&
+			    (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) &&
+			    (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) &&
+			    (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) &&
 			    (strcmp(par.pmProcessor, "PowerPC") == 0) ) {
 				di->blocksize =(uint)bs;
-				di->offs = (llong)par.pmPyPartStart * bs;
-				di->size = (llong)par.pmPartBlkCnt * bs;
+
+				offs = (llong)(__be32_to_cpu(par.pmPyPartStart)) * bs;
+				di->offs_hi = offs >> BITS;
+				di->offs_lo = offs & (ucell) -1;
+
+				size = (llong)(__be32_to_cpu(par.pmPartBlkCnt)) * bs;
+				di->size_hi = size >> BITS;
+				di->size_lo = size & (ucell) -1;
+
 				if (want_bootcode) {
-					di->offs += (llong)par.pmLgBootStart*bs;
-					di->size = (llong)par.pmBootSize;
+					offs = (llong)(__be32_to_cpu(par.pmLgBootStart)) * bs;
+					di->offs_hi = offs >> BITS;
+					di->offs_lo = offs & (ucell) -1;
+
+					size = (llong)(__be32_to_cpu(par.pmBootSize)) * bs;
+					di->size_hi = size >> BITS;
+					di->size_lo = size & (ucell) -1;
 				}
 				ret = -1;
 				goto out;
@@ -141,37 +182,70 @@
 
 	if (parnum == 0) {
 		di->blocksize =(uint)bs;
-		di->offs = (llong)0;
-		di->size = (llong)dmap.sbBlkCount * bs;
+
+		offs = (llong)0;
+		di->offs_hi = offs >> BITS;
+		di->offs_lo = offs & (ucell) -1;
+
+		size = (llong)__be32_to_cpu(dmap.sbBlkCount) * bs;
+		di->size_hi = size >> BITS;
+		di->size_lo = size & (ucell) -1;
+
 		ret = -1;
 		goto out;
 	}
 
-	if( parnum > par.pmMapBlkCnt)
+	if( parnum > __be32_to_cpu(par.pmMapBlkCnt))
 		goto out;
 
 found:
 	SEEK( (bs * parnum) );
 	READ( &par, sizeof(par) );
-	if( par.pmSig != DESC_PART_SIGNATURE || !par.pmPartBlkCnt )
+	if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE || !__be32_to_cpu(par.pmPartBlkCnt) )
 		goto out;
-	if( !(par.pmPartStatus & kPartitionAUXIsValid) ||
-	    !(par.pmPartStatus & kPartitionAUXIsAllocated) ||
-	    !(par.pmPartStatus & kPartitionAUXIsReadable) )
+	if( !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) ||
+	    !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) ||
+	    !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) )
 		goto out;
 
 	ret = -1;
-	di->blocksize =(uint)bs;
-	di->offs = (llong)par.pmPyPartStart * bs;
-	di->size = (llong)par.pmPartBlkCnt * bs;
+	di->blocksize = (uint)bs;
+
+	offs = (llong)__be32_to_cpu(par.pmPyPartStart) * bs;
+	size = (llong)__be32_to_cpu(par.pmPartBlkCnt) * bs;
+
 	if (want_bootcode) {
-		di->offs += (llong)par.pmLgBootStart * bs;
-		di->size = (llong)par.pmBootSize;
+		offs += (llong)__be32_to_cpu(par.pmLgBootStart) * bs;
+		size = (llong)__be32_to_cpu(par.pmBootSize);
+	}
+
+	di->offs_hi = offs >> BITS;
+	di->offs_lo = offs & (ucell) -1;
+
+	di->size_hi = size >> BITS;
+	di->size_lo = size & (ucell) -1;
+
+	/* We have a valid partition - so probe for a filesystem at the current offset */
+	DPRINTF("mac-parts: about to probe for fs\n");
+	DPUSH( offs );
+	PUSH_ih( my_parent() );
+	parword("find-filesystem");
+	DPRINTF("mac-parts: done fs probe\n");
+
+	ph = POP_ph();
+	if( ph ) {
+		DPRINTF("mac-parts: filesystem found with ph " FMT_ucellx " and args %s\n", ph, str);
+		push_str( argstr );
+		PUSH_ph( ph );
+		fword("interpose");
+	} else {
+		DPRINTF("mac-parts: no filesystem found; bypassing misc-files interpose\n");
 	}
 
+	free( str );
+
 out:
-	DPRINTF("offset 0x%llx size 0x%llx\n", di->offs, di->size);
-	PUSH( ret);
+	PUSH( ret );
 }
 
 /* ( block0 -- flag? ) */
@@ -181,7 +255,7 @@
 	desc_map_t *dmap = (desc_map_t*)POP();
 
 	DPRINTF("macparts_probe %x ?= %x\n", dmap->sbSig, DESC_MAP_SIGNATURE);
-	if( dmap->sbSig != DESC_MAP_SIGNATURE )
+	if( __be16_to_cpu(dmap->sbSig) != DESC_MAP_SIGNATURE )
 		RET(0);
 	RET(-1);
 }
@@ -190,10 +264,13 @@
 static void
 macparts_get_info( macparts_info_t *di )
 {
+	DPRINTF("macparts_get_info");
+
 	PUSH( -1 );		/* no type */
-	DPUSH( di->offs );
-	DPUSH( di->size );
-	DPRINTF("macparts_get_info %lld %lld\n", di->offs, di->size);
+	PUSH( di->offs_lo );
+	PUSH( di->offs_hi );
+	PUSH( di->size_lo );
+	PUSH( di->size_hi );
 }
 
 static void
@@ -209,9 +286,49 @@
 	fword("register-partition-package");
 }
 
+/* ( pos.d -- status ) */
+static void
+macparts_seek(macparts_info_t *di )
+{
+	llong pos = DPOP();
+	llong offs;
+
+	DPRINTF("macparts_seek %llx:\n", pos);
+
+	/* Calculate the seek offset for the parent */
+	offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
+	offs += pos;
+	DPUSH(offs);
+
+	DPRINTF("macparts_seek parent offset %llx:\n", offs);
+
+	call_package(di->seek_xt, my_parent());
+}
+
+/* ( buf len -- actlen ) */
+static void
+macparts_read(macparts_info_t *di )
+{
+	DPRINTF("macparts_read\n");
+
+	/* Pass the read back up to the parent */
+	call_package(di->read_xt, my_parent());
+}
+
+/* ( addr -- size ) */
+static void
+macparts_load( __attribute__((unused))macparts_info_t *di )
+{
+	forth_printf("load currently not implemented for /packages/mac-parts\n");
+	PUSH(0);
+}
+
 NODE_METHODS( macparts ) = {
 	{ "probe",	macparts_probe 		},
 	{ "open",	macparts_open 		},
+	{ "seek",	macparts_seek 		},
+	{ "read",	macparts_read 		},
+	{ "load",	macparts_load 		},
 	{ "get-info",	macparts_get_info 	},
 	{ "block-size",	macparts_block_size 	},
 	{ NULL,		macparts_initialize	},

Modified: trunk/openbios-devel/packages/mac-parts.h
==============================================================================
--- trunk/openbios-devel/packages/mac-parts.h	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/mac-parts.h	Tue Jun  8 22:59:08 2010	(r791)
@@ -38,47 +38,47 @@
 };
 
 typedef struct {
-	long		ddBlock;		/* first block of driver */
-	short		ddSize;			/* driver size in blocks */
-	short		ddType;			/* 1 & -1 for SCSI */
+	u32		ddBlock;		/* first block of driver */
+	u16		ddSize;			/* driver size in blocks */
+	s16		ddType;			/* 1 & -1 for SCSI */
 } driver_entry_t;
 
 typedef struct { /* Block 0 of a device */
-	short		sbSig;			/* always 0x4552 */
-	short		sbBlockSize;		/* 512 */
-	long		sbBlkCount;		/* #blocks on device */
-	short		sbDevType;    		/* 0 */
-	short		sbDevID;      		/* 0 */
-	long		sbData;      		/* 0 */
-	short		sbDrvrCount;		/* #driver descriptors */
+	u16		sbSig;			/* always 0x4552 */
+	u16		sbBlockSize;		/* 512 */
+	s32		sbBlkCount;		/* #blocks on device */
+	u16		sbDevType;    		/* 0 */
+	u16		sbDevID;      		/* 0 */
+	u32		sbData;      		/* 0 */
+	s16		sbDrvrCount;		/* #driver descriptors */
 
 	/* driver entries goes here */
 	driver_entry_t	drivers[61] __attribute__ ((packed));
 
-	short		filler1;
-	long		filler2;
+	u16		filler1;
+	u32		filler2;
 } desc_map_t;
 
 typedef struct { /* Partition descriptor */
-	short		pmSig;			/* always 0x504d 'PM' */
-	short		pmSigPad;		/* 0 */
-	ulong		pmMapBlkCnt;		/* #blocks in partition map */
-	ulong		pmPyPartStart;		/* first physical block of part. */
-	ulong		pmPartBlkCnt;		/* #blocks in partition */
+	u16		pmSig;			/* always 0x504d 'PM' */
+	u16		pmSigPad;		/* 0 */
+	u32		pmMapBlkCnt;		/* #blocks in partition map */
+	u32		pmPyPartStart;		/* first physical block of part. */
+	u32		pmPartBlkCnt;		/* #blocks in partition */
 	char		pmPartName[32];		/* partition name */
 	char		pmPartType[32];		/* partition type */
 
 	/* these fields may or may not be used */
-	ulong		pmLgDataStart;
-	ulong		pmDataCnt;
-	ulong		pmPartStatus;
-	ulong		pmLgBootStart;
-	ulong		pmBootSize;
-	ulong		pmBootLoad;
-	ulong		pmBootLoad2;
-	ulong		pmBootEntry;
-	ulong		pmBootEntry2;
-	ulong		pmBootCksum;
+	u32		pmLgDataStart;
+	u32		pmDataCnt;
+	u32		pmPartStatus;
+	u32		pmLgBootStart;
+	u32		pmBootSize;
+	u32		pmBootLoad;
+	u32		pmBootLoad2;
+	u32		pmBootEntry;
+	u32		pmBootEntry2;
+	u32		pmBootCksum;
 	char		pmProcessor[16];
 
 	char		filler[376];		/* might contain extra information */

Modified: trunk/openbios-devel/packages/misc-files.c
==============================================================================
--- trunk/openbios-devel/packages/misc-files.c	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/misc-files.c	Tue Jun  8 22:59:08 2010	(r791)
@@ -19,8 +19,18 @@
 #include "libopenbios/bindings.h"
 #include "fs/fs.h"
 #include "libc/diskio.h"
+#include "libc/vsprintf.h"
 #include "packages.h"
 
+//#define CONFIG_DEBUG_MISC_FILES
+
+#ifdef CONFIG_DEBUG_MISC_FILES
+#define DPRINTF(fmt, args...)                   \
+    do { printk(fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
 #define PATHBUF_SIZE	256
 #define VOLNAME_SIZE	64
 
@@ -42,17 +52,36 @@
 	fs_ops_t *fs = malloc( sizeof(*fs) );
 	int err, fd;
 
-	err = (fd=open_ih(ih)) == -1;
+	DPRINTF("misc-files doing open with ih " FMT_ucellX "\n", ih);
+
+	err = (fd = open_ih(ih)) == -1;
 
 	if( !err ) {
-		err=fs_hfsp_open(fd, fs);
-		if( err ) err = fs_hfs_open(fd, fs);
-		if( err ) err = fs_iso9660_open(fd, fs);
-		if( err ) err = fs_ext2_open(fd, fs);
-		if( err ) err = fs_grubfs_open(fd, fs);
-	}
+		err = fs_hfsp_open(fd, fs);
+		DPRINTF("--- HFSP returned %d\n", err);
 
-	fs->fd = fd;
+		if( err ) {
+			err = fs_hfs_open(fd, fs);
+			DPRINTF("--- HFS returned %d\n", err);
+		}
+
+		if( err ) {
+			err = fs_iso9660_open(fd, fs);
+			DPRINTF("--- ISO9660 returned %d\n", err);
+		}
+
+		if( err ) {
+			err = fs_ext2_open(fd, fs);
+			DPRINTF("--- ext2 returned %d\n", err);
+		}
+
+		if( err ) {
+			err = fs_grubfs_open(fd, fs);
+			DPRINTF("--- grubfs returned %d\n", err);
+		}
+
+		fs->fd = fd;
+	}
 
 	if( err ) {
 		if( fd != -1 )
@@ -61,6 +90,8 @@
 		return NULL;
 	}
 
+	DPRINTF("misc-files open returns %p\n", fs);
+
 	return fs;
 }
 
@@ -83,15 +114,29 @@
 		RET( 0 );
 
 	name = my_args_copy();
+
+	mi->fs = fs;
+
+	DPRINTF("misc-files open arguments: %s\n", name);
+
+	/* If we have been passed a specific file, open it */
 	if( name ) {
-		if( !(mi->file=fs_open_path(fs, name)) ) {
+		if( !(mi->file = fs_open_path(fs, name)) ) {
+			forth_printf("Unable to open path %s\n", name);
 			free( name );
 			do_close( fs );
 			RET(0);
 		}
-		/* printk("PATH: %s\n", fs->get_path(mi->file, mi->pathbuf, PATHBUF_SIZE) ); */
+
+		DPRINTF("Successfully opened %s\n", name);
+		// printk("PATH: %s\n", fs->get_path(mi->file, mi->pathbuf, PATHBUF_SIZE) );
+	} else {
+		/* No file was specified, but return success so that we can read
+		the filesystem. If mi->file is not set, routines simply call their
+		parent which in this case is the partition handler. */
+
+		RET(-1);
 	}
-	mi->fs = fs;
 
 	if( name )
 		free( name );
@@ -183,17 +228,23 @@
 static void
 files_read( files_info_t *mi )
 {
-	int len = POP();
-	char *buf = (char*)POP();
+	int len;
+	char *buf;
 	int ret;
 
 	if( mi->file ) {
+		len = POP();
+		buf = (char*)POP();
+
 		ret = mi->fs->read( mi->file, buf, len );
 		mi->filepos += ret;
+
+		PUSH( ret );
 	} else {
-		ret = read_io( mi->fs->fd, buf, len );
+		DPRINTF("misc-files read: no valid FS so calling parent\n");
+
+		call_parent_method("read");
 	}
-	PUSH( ret );
 }
 
 /* ( buf len -- actlen ) */
@@ -208,23 +259,27 @@
 static void
 files_seek( files_info_t *mi )
 {
-	llong pos = DPOP();
-	cell ret;
-
 	if( mi->file ) {
+		llong pos = DPOP();
+		cell ret;
 		int offs = (int)pos;
 		int whence = SEEK_SET;
 
+		DPRINTF("misc-files seek: using FS handle\n");
+
 		if( offs == -1 ) {
 			offs = 0;
 			whence = SEEK_END;
 		}
 		mi->filepos = mi->fs->lseek( mi->file, offs, whence );
 		ret = (mi->filepos < 0)? -1 : 0;
+
+		PUSH( ret );
 	} else {
-		ret = seek_io( mi->fs->fd, pos );
+		DPRINTF("misc-files seek: no valid FS so calling parent\n");
+
+		call_parent_method("seek");
 	}
-	PUSH( ret );
 }
 
 /* ( -- filepos.d ) */
@@ -250,42 +305,89 @@
 static void
 files_load( files_info_t *mi)
 {
-	char *buf = (char*)POP();
+	char *buf;
 	int ret, size;
 
-	if (!mi->file) {
-		PUSH(0);
-		return;
-	}
+	if (mi->file) {
+		buf = (char*)POP();
+		size = 0;
+
+		DPRINTF("misc-files load at address %p\n", buf);
+
+		while (1) {
+			ret = mi->fs->read( mi->file, buf, 8192 );
+			if (ret <= 0)
+				break;
+			buf += ret;
+			mi->filepos += ret;
+			size += ret;
+	
+			if (size % 0x100000 == 0)
+				DPRINTF("----> size is %dM\n", size / 0x100000);
+	
+			if (ret != 8192)
+				break;
+		}
+	
+		DPRINTF("load complete with size: %d\n", size);
+		PUSH( size );
+	} else {
 
-	size = 0;
-	while(1) {
-		ret = mi->fs->read( mi->file, buf, 512 );
-		if (ret <= 0)
-			break;
-		buf += ret;
-		mi->filepos += ret;
-		size += ret;
-		if (ret != 512)
-			break;
+		DPRINTF("misc-files load: no valid FS so calling parent\n");
+
+		call_parent_method("load");
 	}
-	PUSH( size );
 }
 
-/* static method, ( ih -- flag? ) */
+/* static method, ( pos.d ih -- flag? ) */
 static void
-files_probe( files_info_t *dummy )
+files_probe( files_info_t *mi )
 {
 	ihandle_t ih = POP_ih();
-	fs_ops_t *fs;
-	int ret = 0;
+	llong offs = DPOP();
+	int fd, err = 0;
+
+	DPRINTF("misc-files probe with offset %llx\n", offs);
 
-	if( (fs=do_open(ih)) != NULL ) {
-		/* printk("HFS[+] filesystem found\n"); */
-		do_close( fs );
-		ret = -1;
+	err = (fd = open_ih(ih)) == -1;
+	if( !err ) {
+		/*
+		err = fs_hfsp_open(fd, fs);
+		DPRINTF("--- HFSP returned %d\n", err);
+
+		if( err ) {
+			err = fs_hfs_open(fd, fs);
+			DPRINTF("--- HFS returned %d\n", err);
+		}
+
+		if( err ) {
+			err = fs_iso9660_open(fd, fs);
+			DPRINTF("--- ISO9660 returned %d\n", err);
+		}
+
+		if( err ) {
+			err = fs_ext2_open(fd, fs);
+			DPRINTF("--- ext2 returned %d\n", err);
+		}
+		*/
+
+		if( err ) {
+			err = fs_grubfs_probe(fd, offs);
+			DPRINTF("--- grubfs returned %d\n", err);
+		}
+	}
+
+	if (fd)
+		close_io(fd);
+
+	/* If no errors occurred, indicate success */
+	if (!err) {
+		DPRINTF("misc-files probe found filesystem\n");
+		PUSH(-1);
+	} else {
+		DPRINTF("misc-files probe could not find filesystem\n");
+		PUSH(0);
 	}
-	PUSH( ret );
 }
 
 static void

Modified: trunk/openbios-devel/packages/pc-parts.c
==============================================================================
--- trunk/openbios-devel/packages/pc-parts.c	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/pc-parts.c	Tue Jun  8 22:59:08 2010	(r791)
@@ -15,24 +15,40 @@
 #include "config.h"
 #include "libopenbios/bindings.h"
 #include "libc/byteorder.h"
+#include "libc/vsprintf.h"
 #include "packages.h"
 
+//#define DEBUG_PC_PARTS
+
+#ifdef DEBUG_PC_PARTS
+#define DPRINTF(fmt, args...)                   \
+    do { printk(fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
 typedef struct {
-	ullong		offs;
-	ullong		size;
+	xt_t		seek_xt, read_xt;
+	ucell	        offs_hi, offs_lo;
+        ucell	        size_hi, size_lo;
 } pcparts_info_t;
 
 DECLARE_NODE( pcparts, INSTALL_OPEN, sizeof(pcparts_info_t), "+/packages/pc-parts" );
 
+#define SEEK( pos )		({ DPUSH(pos); call_parent(di->seek_xt); POP(); })
+#define READ( buf, size )	({ PUSH((ucell)buf); PUSH(size); call_parent(di->read_xt); POP(); })
 
-#define SEEK( pos )		({ DPUSH(pos); call_parent(seek_xt); POP(); })
-#define READ( buf, size )	({ PUSH((ucell)buf); PUSH(size); call_parent(read_xt); POP(); })
+/* three helper functions */
 
-/* two helper functions */
+static inline int has_pc_valid_partition(unsigned char *sect)
+{
+	/* Make sure the partition table contains at least one valid entry */
+	return (sect[0x1c2] != 0 || sect[0x1d2] != 0 || sect[0x1e2] != 0);
+}
 
 static inline int has_pc_part_magic(unsigned char *sect)
 {
-	return sect[510]==0x55 && sect[511]==0xAA;
+	return sect[0x1fe]==0x55 && sect[0x1ff]==0xAA;
 }
 
 static inline int is_pc_extended_part(unsigned char type)
@@ -45,9 +61,13 @@
 pcparts_open( pcparts_info_t *di )
 {
 	char *str = my_args_copy();
-	xt_t seek_xt = find_parent_method("seek");
-	xt_t read_xt = find_parent_method("read");
+	char *argstr = strdup("");
+	char *parstr = strdup("");
 	int bs, parnum=-1;
+	int found = 0;
+	phandle_t ph;
+	ducell offs, size;
+
 	/* Layout of PC partition table */
 	struct pc_partition {
 		unsigned char boot;
@@ -60,19 +80,50 @@
 		unsigned char e_cyl;
 		u32 start_sect; /* unaligned little endian */
 		u32 nr_sects; /* ditto */
-	} *p;
+	} *p, *partition;
+
 	unsigned char buf[512];
 
-	/* printk("pcparts_open '%s'\n", str ); */
+	DPRINTF("pcparts_open '%s'\n", str );
+
+	/* 
+		Arguments that we accept:
+		id: [0-7]
+		[(id,)][filespec]
+	*/
 
 	if( str ) {
-		parnum = atol(str);
-		if( !strlen(str) )
-			parnum = 1;
-		free( str );
+		if ( !strlen(str) )
+			parnum = -1;
+		else {
+			/* If end of string, we just have a partition id */
+			if (str[1] == '\0') {
+				parstr = str;
+			} else {
+				/* If a comma, then we have a partition id plus argument */
+				if (str[1] == ',') {
+					str[1] = '\0';
+					parstr = str;
+					argstr = &str[2];
+				} else {
+					/* Otherwise we have just an argument */
+					argstr = str;
+				}
+			}
+		
+			/* Convert the id to a partition number */
+			if (strlen(parstr))
+				parnum = atol(parstr);
+		}
 	}
+
+	DPRINTF("parstr: %s  argstr: %s  parnum: %d\n", parstr, argstr, parnum);
+
 	if( parnum < 0 )
-		parnum = 1;
+		parnum = 0;
+
+	di->read_xt = find_parent_method("read");
+	di->seek_xt = find_parent_method("seek");
 
 	SEEK( 0 );
 	if( READ(buf, 512) != 512 )
@@ -80,29 +131,40 @@
 
 	/* Check Magic */
 	if (!has_pc_part_magic(buf)) {
-		printk("pc partition magic not found.\n");
+		DPRINTF("pc partition magic not found.\n");
 		RET(0);
 	}
 
-	/* get partition data */
-	p = (struct pc_partition *) (buf + 0x1be);
+	/* Actual partition data */
+	partition = (struct pc_partition *) (buf + 0x1be);
 
-	bs=512;
+	/* Make sure we use a copy accessible from an aligned pointer (some archs
+	   e.g. SPARC will crash otherwise) */
+	p = malloc(sizeof(struct pc_partition));
+
+	bs = 512;
 
 	if (parnum < 4) {
 		/* primary partition */
-		p += parnum;
-		if (p->type==0 || is_pc_extended_part(p->type)) {
-			printk("partition %d does not exist\n", parnum+1 );
+		partition += parnum;
+		memcpy(p, partition, sizeof(struct pc_partition));
+
+		if (p->type == 0 || is_pc_extended_part(p->type)) {
+			DPRINTF("partition %d does not exist\n", parnum+1 );
 			RET( 0 );
 		}
-		di->offs = (llong)(__le32_to_cpu(p->start_sect)) * bs;
-		di->size = (llong)(__le32_to_cpu(p->nr_sects)) * bs;
 
-		/* printk("Primary partition at sector %x\n",
-				__le32_to_cpu(p->start_sect)); */
+		offs = (llong)(__le32_to_cpu(p->start_sect)) * bs;
+		di->offs_hi = offs >> BITS;
+		di->offs_lo = offs & (ucell) -1;
 
-		RET( -1 );
+		size = (llong)(__le32_to_cpu(p->nr_sects)) * bs;
+        	di->size_hi = size >> BITS;
+        	di->size_lo = size & (ucell) -1;
+
+		DPRINTF("Primary partition at sector %x\n", __le32_to_cpu(p->start_sect));
+
+		found = 1;
 	} else {
 		/* Extended partition */
 		int i, cur_part;
@@ -116,55 +178,96 @@
 		}
 
 		if (i >= 4) {
-			printk("Extended partition not found\n");
+			DPRINTF("Extended partition not found\n");
 			RET( 0 );
 		}
 
-		printk("Extended partition at %d\n", i+1);
+		DPRINTF("Extended partition at %d\n", i+1);
 
 		/* Visit each logical partition labels */
 		ext_start = __le32_to_cpu(p[i].start_sect);
 		cur_table = ext_start;
 		cur_part = 4;
 
-		for (;;) {
-			/* printk("cur_part=%d at %x\n", cur_part, cur_table); */
+		while (cur_part <= parnum) {
+			DPRINTF("cur_part=%d at %lx\n", cur_part, cur_table);
 
-			SEEK( cur_table*bs );
+			SEEK( cur_table * bs );
 			if( READ(buf, sizeof(512)) != sizeof(512) )
 				RET( 0 );
 
 			if (!has_pc_part_magic(buf)) {
-				printk("Extended partition has no magic\n");
+				DPRINTF("Extended partition has no magic\n");
 				break;
 			}
 
-			p = (struct pc_partition *) (buf + 0x1be);
+			/* Read the extended partition, making sure we are aligned again */
+			partition = (struct pc_partition *) (buf + 0x1be);
+			memcpy(p, partition, sizeof(struct pc_partition));
+
 			/* First entry is the logical partition */
 			if (cur_part == parnum) {
-				if (p->type==0) {
-					printk("Partition %d is empty\n", parnum+1);
+				if (p->type == 0) {
+					DPRINTF("Partition %d is empty\n", parnum+1);
 					RET( 0 );
 				}
-				di->offs =
-					(llong)(cur_table+__le32_to_cpu(p->start_sect)) * bs;
-				di->size = (llong)__le32_to_cpu(p->nr_sects) * bs;
-				RET ( -1 );
+
+				offs = (llong)(cur_table+__le32_to_cpu(p->start_sect)) * bs;
+				di->offs_hi = offs >> BITS;
+				di->offs_lo = offs & (ucell) -1;
+
+				size = (llong)__le32_to_cpu(p->nr_sects) * bs;
+				di->size_hi = size >> BITS;
+				di->size_lo = size & (ucell) -1;
+
+				found = 1;
+				break;
 			}
 
 			/* Second entry is link to next partition */
 			if (!is_pc_extended_part(p[1].type)) {
-				printk("no link\n");
+				DPRINTF("no link\n");
 				break;
 			}
-			cur_table = ext_start + __le32_to_cpu(p[1].start_sect);
 
+			cur_table = ext_start + __le32_to_cpu(p[1].start_sect);
 			cur_part++;
 		}
-		printk("Logical partition %d does not exist\n", parnum+1);
+
+		if (!found) {
+			DPRINTF("Logical partition %d does not exist\n", parnum+1);
+			RET( 0 );
+		}
+	}
+	
+	free(p);
+
+	if (found) {
+		/* We have a valid partition - so probe for a filesystem at the current offset */
+		DPRINTF("pc-parts: about to probe for fs\n");
+		DPUSH( offs );
+		PUSH_ih( my_parent() );
+		parword("find-filesystem");
+		DPRINTF("pc-parts: done fs probe\n");
+	
+		ph = POP_ph();
+		if( ph ) {
+			DPRINTF("pc-parts: filesystem found with ph " FMT_ucellx " and args %s\n", ph, str);
+			push_str( argstr );
+			PUSH_ph( ph );
+			fword("interpose");
+		} else {
+			DPRINTF("pc-parts: no filesystem found; bypassing misc-files interpose\n");
+		}
+	
+		free( str );
+		RET( -1 );
+	} else {
+		DPRINTF("pc-parts: unable to locate partition\n");
+
+		free( str );
 		RET( 0 );
 	}
-	/* we should never reach this point */
 }
 
 /* ( block0 -- flag? ) */
@@ -173,16 +276,24 @@
 {
 	unsigned char *buf = (unsigned char *)POP();
 
-	RET ( has_pc_part_magic(buf) );
+	DPRINTF("probing for PC partitions\n");
+
+	/* We also check that at least one valid partition exists; this is because
+	some CDs seem broken in that they have a partition table but it is empty
+	e.g. MorphOS. */
+	RET ( has_pc_part_magic(buf) && has_pc_valid_partition(buf) );
 }
 
 /* ( -- type offset.d size.d ) */
 static void
 pcparts_get_info( pcparts_info_t *di )
 {
+	DPRINTF("PC get_info\n");
 	PUSH( -1 );		/* no type */
-	DPUSH( di->offs );
-	DPUSH( di->size );
+	PUSH( di->offs_lo );
+	PUSH( di->offs_hi );
+	PUSH( di->size_lo );
+	PUSH( di->size_hi );
 }
 
 static void
@@ -197,9 +308,50 @@
 	fword("register-partition-package");
 }
 
+/* ( pos.d -- status ) */
+static void
+pcparts_seek(pcparts_info_t *di )
+{
+	llong pos = DPOP();
+	llong offs;
+
+	DPRINTF("pcparts_seek %llx:\n", pos);
+
+	/* Calculate the seek offset for the parent */
+	offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
+	offs += pos;
+	DPUSH(offs);
+
+	DPRINTF("pcparts_seek parent offset %llx:\n", offs);
+
+	call_package(di->seek_xt, my_parent());
+}
+
+/* ( buf len -- actlen ) */
+static void
+pcparts_read(pcparts_info_t *di )
+{
+	DPRINTF("pcparts_read\n");
+
+	/* Pass the read back up to the parent */
+	call_package(di->read_xt, my_parent());
+}
+
+/* ( addr -- size ) */
+static void
+pcparts_load( __attribute__((unused))pcparts_info_t *di )
+{
+	forth_printf("load currently not implemented for /packages/pc-parts\n");
+	PUSH(0);
+}
+
+
 NODE_METHODS( pcparts ) = {
 	{ "probe",	pcparts_probe 		},
 	{ "open",	pcparts_open 		},
+	{ "seek",	pcparts_seek 		},
+	{ "read",	pcparts_read 		},
+	{ "load",	pcparts_load 		},
 	{ "get-info",	pcparts_get_info 	},
 	{ "block-size",	pcparts_block_size 	},
 	{ NULL,		pcparts_initialize	},

Modified: trunk/openbios-devel/packages/sun-parts.c
==============================================================================
--- trunk/openbios-devel/packages/sun-parts.c	Thu May 27 22:12:26 2010	(r790)
+++ trunk/openbios-devel/packages/sun-parts.c	Tue Jun  8 22:59:08 2010	(r791)
@@ -15,9 +15,12 @@
 #include "config.h"
 #include "libopenbios/bindings.h"
 #include "libc/byteorder.h"
+#include "libc/vsprintf.h"
 #include "packages.h"
 
-#ifdef CONFIG_DEBUG_SUN_PARTS
+//#define DEBUG_SUN_PARTS
+
+#ifdef DEBUG_SUN_PARTS
 #define DPRINTF(fmt, args...)                   \
     do { printk(fmt , ##args); } while (0)
 #else
@@ -25,6 +28,7 @@
 #endif
 
 typedef struct {
+	xt_t		seek_xt, read_xt;
         ucell	        offs_hi, offs_lo;
         ucell	        size_hi, size_lo;
 	int		type;
@@ -32,9 +36,8 @@
 
 DECLARE_NODE( sunparts, INSTALL_OPEN, sizeof(sunparts_info_t), "+/packages/sun-parts" );
 
-
-#define SEEK( pos )		({ DPUSH(pos); call_parent(seek_xt); POP(); })
-#define READ( buf, size )	({ PUSH((ucell)buf); PUSH(size); call_parent(read_xt); POP(); })
+#define SEEK( pos )		({ DPUSH(pos); call_parent(di->seek_xt); POP(); })
+#define READ( buf, size )	({ PUSH((ucell)buf); PUSH(size); call_parent(di->read_xt); POP(); })
 
 /* Layout of SUN partition table */
 struct sun_disklabel {
@@ -89,27 +92,57 @@
 sunparts_open( sunparts_info_t *di )
 {
 	char *str = my_args_copy();
-	xt_t seek_xt = find_parent_method("seek");
-	xt_t read_xt = find_parent_method("read");
+	char *argstr = strdup("");
+	char *parstr = strdup("");
 	int parnum = -1;
 	unsigned char buf[512];
         struct sun_disklabel *p;
         unsigned int i, bs;
         ducell offs, size;
+	phandle_t ph;
 
 	DPRINTF("sunparts_open '%s'\n", str );
 
-	if( str ) {
-            if( !strlen(str) )
-                parnum = -1;
-            else if (str[0] >= 'a' && str[0] < ('a' + 8))
-                parnum = str[0] - 'a';
-            else
-                parnum = atol(str);
+	/* 
+		Arguments that we accept:
+		id: [0-7] | [a-h]
+		[(id,)][filespec]
+	*/
 
-            free( str );
+	if( str ) {
+		if ( !strlen(str) )
+			parnum = -1;
+		else {
+			/* If end of string, we just have a partition id */
+			if (str[1] == '\0') {
+				parstr = str;
+			} else {
+				/* If a comma, then we have a partition id plus argument */
+				if (str[1] == ',') {
+					str[1] = '\0';
+					parstr = str;
+					argstr = &str[2];
+				} else {
+					/* Otherwise we have just an argument */
+					argstr = str;
+				}
+			}
+		
+			/* Convert the id to a partition number */
+			if (strlen(parstr)) {
+				if (parstr[0] >= 'a' && parstr[0] < ('a' + 8))
+					parnum = parstr[0] - 'a';
+				else
+					parnum = atol(parstr);
+			}	
+		}
 	}
 
+	DPRINTF("parstr: %s  argstr: %s  parnum: %d\n", parstr, argstr, parnum);
+
+	di->read_xt = find_parent_method("read");
+	di->seek_xt = find_parent_method("seek");
+
 	SEEK( 0 );
 	if( READ(buf, 512) != 512 )
 		RET(0);
@@ -137,6 +170,7 @@
             parnum = 0;
 
 	DPRINTF("Selected partition %d\n", parnum);
+
         offs = (llong)__be32_to_cpu(p->partitions[parnum].start_cylinder) *
             __be16_to_cpu(p->ntrks) * __be16_to_cpu(p->nsect) * bs;
 
@@ -146,9 +180,28 @@
         di->size_hi = size >> BITS;
         di->size_lo = size & (ucell) -1;
         di->type = __be32_to_cpu(p->infos[parnum].id);
-        DPRINTF("Found Sun partition table, offs %lld size %lld\n",
+
+        DPRINTF("Found Sun partition, offs %lld size %lld\n",
                 (llong)offs, (llong)size);
 
+	/* Probe for filesystem at current offset */
+	DPRINTF("sun-parts: about to probe for fs\n");
+	DPUSH( offs );
+	PUSH_ih( my_parent() );
+	parword("find-filesystem");
+	DPRINTF("sun-parts: done fs probe\n");
+
+	ph = POP_ph();
+	if( ph ) {
+		DPRINTF("sun-parts: filesystem found with ph " FMT_ucellx " and args %s\n", ph, str);
+		push_str( argstr );
+		PUSH_ph( ph );
+		fword("interpose");
+	} else {
+		DPRINTF("sun-parts: no filesystem found; bypassing misc-files interpose\n");
+	}
+
+	free( str );
         RET( -1 );
 }
 
@@ -158,6 +211,8 @@
 {
 	unsigned char *buf = (unsigned char *)POP();
 
+	DPRINTF("probing for Sun partitions\n");
+
 	RET ( has_sun_part_magic(buf) );
 }
 
@@ -185,11 +240,52 @@
 	fword("register-partition-package");
 }
 
+/* ( pos.d -- status ) */
+static void
+sunparts_seek(sunparts_info_t *di )
+{
+	llong pos = DPOP();
+	llong offs;
+
+	DPRINTF("sunparts_seek %llx:\n", pos);
+
+	/* Calculate the seek offset for the parent */
+	offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
+	offs += pos;
+	DPUSH(offs);
+
+	DPRINTF("sunparts_seek parent offset %llx:\n", offs);
+
+	call_package(di->seek_xt, my_parent());
+}
+
+/* ( buf len -- actlen ) */
+static void
+sunparts_read(sunparts_info_t *di )
+{
+	DPRINTF("sunparts_read\n");
+
+	/* Pass the read back up to the parent */
+	call_package(di->read_xt, my_parent());
+}
+
+/* ( addr -- size ) */
+static void
+sunparts_load( __attribute__((unused))sunparts_info_t *di )
+{
+	forth_printf("load currently not implemented for /packages/sun-parts\n");
+	PUSH(0);
+}
+
+
 NODE_METHODS( sunparts ) = {
 	{ "probe",	sunparts_probe 		},
 	{ "open",	sunparts_open 		},
 	{ "get-info",	sunparts_get_info 	},
 	{ "block-size",	sunparts_block_size 	},
+	{ "seek",	sunparts_seek 		},
+	{ "read",	sunparts_read 		},
+	{ "load",	sunparts_load	 	},
 	{ NULL,		sunparts_initialize	},
 };
 



More information about the OpenBIOS mailing list