2008-12-11 20:30:53 +00:00
|
|
|
/*
|
2006-04-26 15:08:19 +00:00
|
|
|
* Creation Date: <2003/12/04 17:07:05 samuel>
|
|
|
|
|
* Time-stamp: <2004/01/07 19:36:09 samuel>
|
2008-12-11 20:30:53 +00:00
|
|
|
*
|
2006-04-26 15:08:19 +00:00
|
|
|
* <mac-parts.c>
|
2008-12-11 20:30:53 +00:00
|
|
|
*
|
2006-04-26 15:08:19 +00:00
|
|
|
* macintosh partition support
|
2008-12-11 20:30:53 +00:00
|
|
|
*
|
2006-04-26 15:08:19 +00:00
|
|
|
* Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
|
2008-12-11 20:30:53 +00:00
|
|
|
*
|
2006-04-26 15:08:19 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* version 2
|
2008-12-11 20:30:53 +00:00
|
|
|
*
|
2006-04-26 15:08:19 +00:00
|
|
|
*/
|
|
|
|
|
|
2010-03-14 17:19:58 +00:00
|
|
|
#include "config.h"
|
2010-03-14 15:05:53 +00:00
|
|
|
#include "libopenbios/bindings.h"
|
2006-04-26 15:08:19 +00:00
|
|
|
#include "mac-parts.h"
|
2010-06-08 20:59:08 +00:00
|
|
|
#include "libc/byteorder.h"
|
|
|
|
|
#include "libc/vsprintf.h"
|
2010-03-13 10:58:19 +00:00
|
|
|
#include "packages.h"
|
2006-04-26 15:08:19 +00:00
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
//#define CONFIG_DEBUG_MAC_PARTS
|
|
|
|
|
|
2008-11-25 19:54:01 +00:00
|
|
|
#ifdef CONFIG_DEBUG_MAC_PARTS
|
|
|
|
|
#define DPRINTF(fmt, args...) \
|
|
|
|
|
do { printk("MAC-PARTS: " fmt , ##args); } while (0)
|
|
|
|
|
#else
|
|
|
|
|
#define DPRINTF(fmt, args...) do {} while(0)
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-04-26 15:08:19 +00:00
|
|
|
typedef struct {
|
2010-06-08 20:59:08 +00:00
|
|
|
xt_t seek_xt, read_xt;
|
|
|
|
|
ucell offs_hi, offs_lo;
|
|
|
|
|
ucell size_hi, size_lo;
|
2009-02-03 20:33:37 +00:00
|
|
|
uint blocksize;
|
2006-04-26 15:08:19 +00:00
|
|
|
} macparts_info_t;
|
|
|
|
|
|
|
|
|
|
DECLARE_NODE( macparts, INSTALL_OPEN, sizeof(macparts_info_t), "+/packages/mac-parts" );
|
|
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
#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(); })
|
2006-04-26 15:08:19 +00:00
|
|
|
|
|
|
|
|
/* ( open -- flag ) */
|
|
|
|
|
static void
|
|
|
|
|
macparts_open( macparts_info_t *di )
|
|
|
|
|
{
|
|
|
|
|
char *str = my_args_copy();
|
2010-06-08 20:59:08 +00:00
|
|
|
char *argstr = strdup("");
|
|
|
|
|
char *parstr = strdup("");
|
|
|
|
|
int bs, parnum=-1;
|
2006-04-26 15:08:19 +00:00
|
|
|
desc_map_t dmap;
|
|
|
|
|
part_entry_t par;
|
2009-08-08 22:00:10 +00:00
|
|
|
int ret = 0;
|
2009-08-12 19:55:31 +00:00
|
|
|
int want_bootcode = 0;
|
2010-06-08 20:59:08 +00:00
|
|
|
phandle_t ph;
|
|
|
|
|
ducell offs, size;
|
|
|
|
|
|
|
|
|
|
DPRINTF("macparts_open '%s'\n", str );
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Arguments that we accept:
|
|
|
|
|
id: [0-7]
|
2010-06-15 19:59:47 +00:00
|
|
|
[(id)][,][filespec]
|
2010-06-08 20:59:08 +00:00
|
|
|
*/
|
2006-04-26 15:08:19 +00:00
|
|
|
|
|
|
|
|
if( str ) {
|
2010-06-08 20:59:08 +00:00
|
|
|
if ( !strlen(str) )
|
2009-08-08 22:00:10 +00:00
|
|
|
parnum = -1;
|
2010-06-08 20:59:08 +00:00
|
|
|
else {
|
2010-06-15 19:59:47 +00:00
|
|
|
/* Detect the boot parameters */
|
|
|
|
|
char *ptr;
|
|
|
|
|
ptr = str;
|
|
|
|
|
|
|
|
|
|
/* <id>,<file> */
|
|
|
|
|
if (*ptr >= '0' && *ptr <= '9' && *(ptr + 1) == ',') {
|
|
|
|
|
parstr = ptr;
|
|
|
|
|
*(ptr + 1) = '\0';
|
|
|
|
|
argstr = ptr + 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* <id> */
|
|
|
|
|
else if (*ptr >= '0' && *ptr <='9' && *(ptr + 1) == '\0') {
|
|
|
|
|
parstr = ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ,<file> */
|
|
|
|
|
else if (*ptr == ',') {
|
|
|
|
|
argstr = ptr + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* <file> */
|
|
|
|
|
else {
|
|
|
|
|
argstr = str;
|
2009-09-21 23:00:42 +00:00
|
|
|
}
|
2010-06-08 20:59:08 +00:00
|
|
|
|
|
|
|
|
/* 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;
|
2009-09-21 23:00:42 +00:00
|
|
|
}
|
2006-04-26 15:08:19 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
DPRINTF("parstr: %s argstr: %s parnum: %d\n", parstr, argstr, parnum);
|
|
|
|
|
|
2009-08-12 19:55:31 +00:00
|
|
|
DPRINTF("want_bootcode %d\n", want_bootcode);
|
2008-11-25 19:54:01 +00:00
|
|
|
DPRINTF("macparts_open %d\n", parnum);
|
2010-06-08 20:59:08 +00:00
|
|
|
|
|
|
|
|
di->read_xt = find_parent_method("read");
|
|
|
|
|
di->seek_xt = find_parent_method("seek");
|
|
|
|
|
|
2006-04-26 15:08:19 +00:00
|
|
|
SEEK( 0 );
|
|
|
|
|
if( READ(&dmap, sizeof(dmap)) != sizeof(dmap) )
|
2009-08-08 22:00:10 +00:00
|
|
|
goto out;
|
2006-04-26 15:08:19 +00:00
|
|
|
|
|
|
|
|
/* partition maps might support multiple block sizes; in this case,
|
|
|
|
|
* pmPyPartStart is typically given in terms of 512 byte blocks.
|
|
|
|
|
*/
|
2010-06-08 20:59:08 +00:00
|
|
|
bs = __be16_to_cpu(dmap.sbBlockSize);
|
2006-04-26 15:08:19 +00:00
|
|
|
if( bs != 512 ) {
|
|
|
|
|
SEEK( 512 );
|
|
|
|
|
READ( &par, sizeof(par) );
|
2010-06-08 20:59:08 +00:00
|
|
|
if( __be16_to_cpu(par.pmSig) == DESC_PART_SIGNATURE )
|
2006-04-26 15:08:19 +00:00
|
|
|
bs = 512;
|
|
|
|
|
}
|
2009-08-08 22:00:10 +00:00
|
|
|
SEEK( bs );
|
|
|
|
|
if( READ(&par, sizeof(par)) != sizeof(par) )
|
|
|
|
|
goto out;
|
2010-06-08 20:59:08 +00:00
|
|
|
if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE)
|
2009-08-08 22:00:10 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
if (parnum == -1) {
|
2009-08-29 15:24:49 +00:00
|
|
|
int firstHFS = -1;
|
2009-08-08 22:00:10 +00:00
|
|
|
/* search a bootable partition */
|
|
|
|
|
/* see PowerPC Microprocessor CHRP bindings */
|
|
|
|
|
|
2010-06-15 16:31:54 +00:00
|
|
|
for (parnum = 0; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) {
|
|
|
|
|
SEEK( (bs * (parnum + 1)) );
|
2009-08-08 22:00:10 +00:00
|
|
|
READ( &par, sizeof(par) );
|
2010-06-08 20:59:08 +00:00
|
|
|
if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE ||
|
|
|
|
|
!__be16_to_cpu(par.pmPartBlkCnt) )
|
2010-06-15 16:31:54 +00:00
|
|
|
break;
|
2009-08-08 22:00:10 +00:00
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
DPRINTF("found partition type: %s\n", par.pmPartType);
|
|
|
|
|
|
2009-08-29 15:24:49 +00:00
|
|
|
if (firstHFS == -1 &&
|
|
|
|
|
strcmp(par.pmPartType, "Apple_HFS") == 0)
|
|
|
|
|
firstHFS = parnum;
|
|
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
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) &&
|
2009-08-08 22:00:10 +00:00
|
|
|
(strcmp(par.pmProcessor, "PowerPC") == 0) ) {
|
|
|
|
|
di->blocksize =(uint)bs;
|
2010-06-08 20:59:08 +00:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2009-08-12 19:55:31 +00:00
|
|
|
if (want_bootcode) {
|
2010-06-08 20:59:08 +00:00
|
|
|
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;
|
2009-08-12 19:55:31 +00:00
|
|
|
}
|
2009-08-08 22:00:10 +00:00
|
|
|
ret = -1;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/* not found */
|
2009-08-29 15:24:49 +00:00
|
|
|
if (firstHFS != -1) {
|
|
|
|
|
parnum = firstHFS;
|
|
|
|
|
goto found;
|
|
|
|
|
}
|
2009-08-08 22:00:10 +00:00
|
|
|
ret = 0;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-25 19:54:01 +00:00
|
|
|
if (parnum == 0) {
|
2009-02-05 20:19:50 +00:00
|
|
|
di->blocksize =(uint)bs;
|
2010-06-08 20:59:08 +00:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2009-08-08 22:00:10 +00:00
|
|
|
ret = -1;
|
|
|
|
|
goto out;
|
2008-11-25 19:54:01 +00:00
|
|
|
}
|
2009-08-08 22:00:10 +00:00
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
if( parnum > __be32_to_cpu(par.pmMapBlkCnt))
|
2009-08-08 22:00:10 +00:00
|
|
|
goto out;
|
2006-04-26 15:08:19 +00:00
|
|
|
|
2009-08-29 15:24:49 +00:00
|
|
|
found:
|
2010-06-15 16:31:54 +00:00
|
|
|
SEEK( (bs * (parnum + 1)) );
|
2006-04-26 15:08:19 +00:00
|
|
|
READ( &par, sizeof(par) );
|
2010-06-08 20:59:08 +00:00
|
|
|
if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE || !__be32_to_cpu(par.pmPartBlkCnt) )
|
2009-08-08 22:00:10 +00:00
|
|
|
goto out;
|
2010-06-08 20:59:08 +00:00
|
|
|
if( !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) ||
|
|
|
|
|
!(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) ||
|
|
|
|
|
!(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) )
|
2009-08-08 22:00:10 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
ret = -1;
|
2010-06-08 20:59:08 +00:00
|
|
|
di->blocksize = (uint)bs;
|
|
|
|
|
|
|
|
|
|
offs = (llong)__be32_to_cpu(par.pmPyPartStart) * bs;
|
|
|
|
|
size = (llong)__be32_to_cpu(par.pmPartBlkCnt) * bs;
|
|
|
|
|
|
2009-08-12 19:55:31 +00:00
|
|
|
if (want_bootcode) {
|
2010-06-08 20:59:08 +00:00
|
|
|
offs += (llong)__be32_to_cpu(par.pmLgBootStart) * bs;
|
|
|
|
|
size = (llong)__be32_to_cpu(par.pmBootSize);
|
2009-08-12 19:55:31 +00:00
|
|
|
}
|
2006-04-26 15:08:19 +00:00
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
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 );
|
|
|
|
|
|
2009-08-08 22:00:10 +00:00
|
|
|
out:
|
2010-06-08 20:59:08 +00:00
|
|
|
PUSH( ret );
|
2006-04-26 15:08:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ( block0 -- flag? ) */
|
|
|
|
|
static void
|
|
|
|
|
macparts_probe( macparts_info_t *dummy )
|
|
|
|
|
{
|
|
|
|
|
desc_map_t *dmap = (desc_map_t*)POP();
|
2008-11-25 19:54:01 +00:00
|
|
|
|
|
|
|
|
DPRINTF("macparts_probe %x ?= %x\n", dmap->sbSig, DESC_MAP_SIGNATURE);
|
2010-06-08 20:59:08 +00:00
|
|
|
if( __be16_to_cpu(dmap->sbSig) != DESC_MAP_SIGNATURE )
|
2006-04-26 15:08:19 +00:00
|
|
|
RET(0);
|
|
|
|
|
RET(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ( -- type offset.d size.d ) */
|
|
|
|
|
static void
|
|
|
|
|
macparts_get_info( macparts_info_t *di )
|
|
|
|
|
{
|
2010-06-08 20:59:08 +00:00
|
|
|
DPRINTF("macparts_get_info");
|
|
|
|
|
|
2006-04-26 15:08:19 +00:00
|
|
|
PUSH( -1 ); /* no type */
|
2010-06-08 20:59:08 +00:00
|
|
|
PUSH( di->offs_lo );
|
|
|
|
|
PUSH( di->offs_hi );
|
|
|
|
|
PUSH( di->size_lo );
|
|
|
|
|
PUSH( di->size_hi );
|
2006-04-26 15:08:19 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-18 20:44:20 +00:00
|
|
|
static void
|
2009-02-03 20:33:37 +00:00
|
|
|
macparts_block_size( macparts_info_t *di )
|
2008-12-18 20:44:20 +00:00
|
|
|
{
|
2009-02-03 20:33:37 +00:00
|
|
|
DPRINTF("macparts_block_size = %x\n", di->blocksize);
|
|
|
|
|
PUSH(di->blocksize);
|
2008-12-18 20:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
2006-04-26 15:08:19 +00:00
|
|
|
static void
|
|
|
|
|
macparts_initialize( macparts_info_t *di )
|
|
|
|
|
{
|
|
|
|
|
fword("register-partition-package");
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-08 20:59:08 +00:00
|
|
|
/* ( 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);
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-26 15:08:19 +00:00
|
|
|
NODE_METHODS( macparts ) = {
|
|
|
|
|
{ "probe", macparts_probe },
|
|
|
|
|
{ "open", macparts_open },
|
2010-06-08 20:59:08 +00:00
|
|
|
{ "seek", macparts_seek },
|
|
|
|
|
{ "read", macparts_read },
|
|
|
|
|
{ "load", macparts_load },
|
2006-04-26 15:08:19 +00:00
|
|
|
{ "get-info", macparts_get_info },
|
2008-12-18 20:44:20 +00:00
|
|
|
{ "block-size", macparts_block_size },
|
2006-04-26 15:08:19 +00:00
|
|
|
{ NULL, macparts_initialize },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
macparts_init( void )
|
|
|
|
|
{
|
|
|
|
|
REGISTER_NODE( macparts );
|
|
|
|
|
}
|