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 }, };