mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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) git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@791 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
committed by
Mark Cave-Ayland
parent
1e5c4a8173
commit
7fc4e304c3
@@ -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 @@ do { printk("MAC-PARTS: " fmt , ##args); } while (0)
|
||||
#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 @@ macparts_open( macparts_info_t *di )
|
||||
/* 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 @@ macparts_open( macparts_info_t *di )
|
||||
/* 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 @@ macparts_open( macparts_info_t *di )
|
||||
|
||||
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 @@ macparts_probe( macparts_info_t *dummy )
|
||||
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 @@ macparts_probe( macparts_info_t *dummy )
|
||||
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 @@ macparts_initialize( macparts_info_t *di )
|
||||
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 },
|
||||
|
||||
Reference in New Issue
Block a user