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
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "openbios/config.h"
|
|
|
|
|
#include "openbios/bindings.h"
|
|
|
|
|
#include "mac-parts.h"
|
|
|
|
|
#include "modules.h"
|
|
|
|
|
|
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 {
|
|
|
|
|
ullong offs;
|
|
|
|
|
ullong size;
|
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" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define SEEK( pos ) ({ DPUSH(pos); call_parent(seek_xt); POP(); })
|
|
|
|
|
#define READ( buf, size ) ({ PUSH((ucell)buf); PUSH(size); call_parent(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");
|
2009-08-08 22:00:10 +00:00
|
|
|
int bs, parnum=0;
|
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;
|
2006-04-26 15:08:19 +00:00
|
|
|
|
2009-08-12 19:55:31 +00:00
|
|
|
DPRINTF("partition %s\n", str);
|
2006-04-26 15:08:19 +00:00
|
|
|
if( str ) {
|
2009-08-12 19:55:31 +00:00
|
|
|
char *tmp;
|
2006-04-26 15:08:19 +00:00
|
|
|
parnum = atol(str);
|
2009-08-08 22:00:10 +00:00
|
|
|
if( *str == 0 || *str == ',' )
|
|
|
|
|
parnum = -1;
|
2009-08-12 19:55:31 +00:00
|
|
|
tmp = str;
|
|
|
|
|
while (*tmp && *tmp != ',')
|
|
|
|
|
tmp++;
|
|
|
|
|
if (*tmp == ',')
|
|
|
|
|
tmp++;
|
|
|
|
|
if (strcmp(tmp, "%BOOT") == 0)
|
|
|
|
|
want_bootcode = 1;
|
|
|
|
|
free(str);
|
2006-04-26 15:08:19 +00:00
|
|
|
}
|
|
|
|
|
|
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);
|
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.
|
|
|
|
|
*/
|
|
|
|
|
bs = dmap.sbBlockSize;
|
|
|
|
|
if( bs != 512 ) {
|
|
|
|
|
SEEK( 512 );
|
|
|
|
|
READ( &par, sizeof(par) );
|
2009-08-08 22:00:10 +00:00
|
|
|
if( 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;
|
|
|
|
|
if (par.pmSig != DESC_PART_SIGNATURE)
|
|
|
|
|
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 */
|
|
|
|
|
|
|
|
|
|
parnum = 1;
|
|
|
|
|
while (parnum <= par.pmMapBlkCnt) {
|
|
|
|
|
SEEK( (bs * parnum) );
|
|
|
|
|
READ( &par, sizeof(par) );
|
|
|
|
|
if( par.pmSig != DESC_PART_SIGNATURE ||
|
|
|
|
|
!par.pmPartBlkCnt )
|
|
|
|
|
goto out;
|
|
|
|
|
|
2009-08-29 15:24:49 +00:00
|
|
|
if (firstHFS == -1 &&
|
|
|
|
|
strcmp(par.pmPartType, "Apple_HFS") == 0)
|
|
|
|
|
firstHFS = parnum;
|
|
|
|
|
|
2009-08-08 22:00:10 +00:00
|
|
|
if( (par.pmPartStatus & kPartitionAUXIsBootValid) &&
|
|
|
|
|
(par.pmPartStatus & kPartitionAUXIsValid) &&
|
|
|
|
|
(par.pmPartStatus & kPartitionAUXIsAllocated) &&
|
|
|
|
|
(par.pmPartStatus & kPartitionAUXIsReadable) &&
|
|
|
|
|
(strcmp(par.pmProcessor, "PowerPC") == 0) ) {
|
|
|
|
|
di->blocksize =(uint)bs;
|
|
|
|
|
di->offs = (llong)par.pmPyPartStart * bs;
|
|
|
|
|
di->size = (llong)par.pmPartBlkCnt * bs;
|
2009-08-12 19:55:31 +00:00
|
|
|
if (want_bootcode) {
|
|
|
|
|
di->offs += (llong)par.pmLgBootStart*bs;
|
|
|
|
|
di->size = (llong)par.pmBootSize;
|
|
|
|
|
}
|
2009-08-08 22:00:10 +00:00
|
|
|
ret = -1;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parnum++;
|
|
|
|
|
}
|
|
|
|
|
/* 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;
|
2008-11-25 19:54:01 +00:00
|
|
|
di->offs = (llong)0;
|
|
|
|
|
di->size = (llong)dmap.sbBlkCount * bs;
|
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
|
|
|
|
|
|
|
|
if( parnum > par.pmMapBlkCnt)
|
|
|
|
|
goto out;
|
2006-04-26 15:08:19 +00:00
|
|
|
|
2009-08-29 15:24:49 +00:00
|
|
|
found:
|
2006-04-26 15:08:19 +00:00
|
|
|
SEEK( (bs * parnum) );
|
|
|
|
|
READ( &par, sizeof(par) );
|
2009-08-08 22:00:10 +00:00
|
|
|
if( par.pmSig != DESC_PART_SIGNATURE || !par.pmPartBlkCnt )
|
|
|
|
|
goto out;
|
|
|
|
|
if( !(par.pmPartStatus & kPartitionAUXIsValid) ||
|
|
|
|
|
!(par.pmPartStatus & kPartitionAUXIsAllocated) ||
|
|
|
|
|
!(par.pmPartStatus & kPartitionAUXIsReadable) )
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
ret = -1;
|
2009-02-03 20:33:37 +00:00
|
|
|
di->blocksize =(uint)bs;
|
2006-04-26 15:08:19 +00:00
|
|
|
di->offs = (llong)par.pmPyPartStart * bs;
|
|
|
|
|
di->size = (llong)par.pmPartBlkCnt * bs;
|
2009-08-12 19:55:31 +00:00
|
|
|
if (want_bootcode) {
|
|
|
|
|
di->offs += (llong)par.pmLgBootStart * bs;
|
|
|
|
|
di->size = (llong)par.pmBootSize;
|
|
|
|
|
}
|
2006-04-26 15:08:19 +00:00
|
|
|
|
2009-08-08 22:00:10 +00:00
|
|
|
out:
|
2009-08-12 19:55:31 +00:00
|
|
|
DPRINTF("offset 0x%llx size 0x%llx\n", di->offs, di->size);
|
2009-08-08 22:00:10 +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);
|
2006-04-26 15:08:19 +00:00
|
|
|
if( dmap->sbSig != DESC_MAP_SIGNATURE )
|
|
|
|
|
RET(0);
|
|
|
|
|
RET(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ( -- type offset.d size.d ) */
|
|
|
|
|
static void
|
|
|
|
|
macparts_get_info( macparts_info_t *di )
|
|
|
|
|
{
|
|
|
|
|
PUSH( -1 ); /* no type */
|
|
|
|
|
DPUSH( di->offs );
|
|
|
|
|
DPUSH( di->size );
|
2008-11-25 19:54:01 +00:00
|
|
|
DPRINTF("macparts_get_info %lld %lld\n", di->offs, di->size);
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NODE_METHODS( macparts ) = {
|
|
|
|
|
{ "probe", macparts_probe },
|
|
|
|
|
{ "open", macparts_open },
|
|
|
|
|
{ "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 );
|
|
|
|
|
}
|