diff options
Diffstat (limited to 'qemu/roms/openbios/packages/mac-parts.c')
-rw-r--r-- | qemu/roms/openbios/packages/mac-parts.c | 447 |
1 files changed, 0 insertions, 447 deletions
diff --git a/qemu/roms/openbios/packages/mac-parts.c b/qemu/roms/openbios/packages/mac-parts.c deleted file mode 100644 index 16c87caf8..000000000 --- a/qemu/roms/openbios/packages/mac-parts.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Creation Date: <2003/12/04 17:07:05 samuel> - * Time-stamp: <2004/01/07 19:36:09 samuel> - * - * <mac-parts.c> - * - * macintosh partition support - * - * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "libopenbios/load.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) -#else -#define DPRINTF(fmt, args...) do {} while(0) -#endif - -typedef struct { - xt_t seek_xt, read_xt; - ucell offs_hi, offs_lo; - ucell size_hi, size_lo; - ucell bootcode_addr, bootcode_entry; - unsigned int blocksize; - phandle_t filesystem_ph; -} macparts_info_t; - -DECLARE_NODE( macparts, INSTALL_OPEN, sizeof(macparts_info_t), "+/packages/mac-parts" ); - -#define SEEK( pos ) ({ DPUSH(pos); call_parent(di->seek_xt); POP(); }) -#define READ( buf, size ) ({ PUSH(pointer2cell(buf)); PUSH(size); call_parent(di->read_xt); POP(); }) - -/* ( open -- flag ) */ -static void -macparts_open( macparts_info_t *di ) -{ - char *str = my_args_copy(); - char *parstr = NULL, *argstr = NULL; - char *tmpstr; - int bs, parnum=-1, apple_parnum=-1; - int parlist[2], parlist_size = 0; - desc_map_t dmap; - part_entry_t par; - int ret = 0, i = 0, j = 0; - int want_bootcode = 0; - phandle_t ph; - ducell offs = 0, size = -1; - - DPRINTF("macparts_open '%s'\n", str ); - - /* - Arguments that we accept: - id: [0-7] - [(id)][,][filespec] - */ - - if ( str && strlen(str) ) { - /* Detect the arguments */ - if ((*str >= '0' && *str <= '9') || (*str == ',')) { - push_str(str); - PUSH(','); - fword("left-parse-string"); - parstr = pop_fstr_copy(); - argstr = pop_fstr_copy(); - } else { - argstr = str; - } - - /* Make sure argstr is not null */ - if (argstr == NULL) - argstr = strdup(""); - - /* Convert the id to a partition number */ - if (parstr && strlen(parstr)) - parnum = atol(parstr); - - /* Detect if we are looking for the bootcode */ - if (strcmp(argstr, "%BOOT") == 0) { - want_bootcode = 1; - } - } - - 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->filesystem_ph = 0; - 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; - - /* partition maps might support multiple block sizes; in this case, - * pmPyPartStart is typically given in terms of 512 byte blocks. - */ - bs = __be16_to_cpu(dmap.sbBlockSize); - if( bs != 512 ) { - SEEK( 512 ); - READ( &par, sizeof(par) ); - if( __be16_to_cpu(par.pmSig) == DESC_PART_SIGNATURE ) - bs = 512; - } - SEEK( bs ); - if( READ(&par, sizeof(par)) != sizeof(par) ) - goto out; - if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE) - goto out; - - /* - * Implement partition selection as per the PowerPC Microprocessor CHRP bindings - */ - - if (argstr == NULL || parnum == 0) { - /* According to the spec, partition 0 as well as no arguments means the whole disk */ - offs = (long long)0; - size = (long long)__be32_to_cpu(dmap.sbBlkCount) * bs; - - di->blocksize = (unsigned int)bs; - - di->offs_hi = offs >> BITS; - di->offs_lo = offs & (ucell) -1; - - di->size_hi = size >> BITS; - di->size_lo = size & (ucell) -1; - - ret = -1; - goto out; - - } else if (parnum == -1) { - - DPRINTF("mac-parts: counted %d partitions\n", __be32_to_cpu(par.pmMapBlkCnt)); - - /* No partition was explicitly requested so let's find a suitable partition... */ - for (i = 1; i <= __be32_to_cpu(par.pmMapBlkCnt); i++) { - SEEK( bs * i ); - READ( &par, sizeof(par) ); - if ( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE || - !__be32_to_cpu(par.pmPartBlkCnt) ) - continue; - - DPRINTF("found partition %d type: %s with status %x\n", i, par.pmPartType, __be32_to_cpu(par.pmPartStatus)); - - /* If we have a valid, allocated and readable partition... */ - if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) { - - /* Unfortunately Apple's OF implementation doesn't follow the OF PowerPC CHRP bindings - * and instead will brute-force boot the first valid partition it finds with a - * type of either "Apple_Boot", "Apple_HFS" or "DOS_FAT_". Here we store the id - * of the first partition that matches these criteria to use as a fallback later - * if required. */ - - if (apple_parnum == -1 && - (strcmp(par.pmPartType, "Apple_Boot") == 0 || - strcmp(par.pmPartType, "Apple_Bootstrap") == 0 || - strcmp(par.pmPartType, "Apple_HFS") == 0 || - strcmp(par.pmPartType, "DOS_FAT_") == 0)) { - apple_parnum = i; - - DPRINTF("Located Apple OF fallback partition %d\n", apple_parnum); - } - - /* If the partition is also bootable and the pmProcessor field matches "PowerPC" (insensitive - * match), then according to the CHRP bindings this is our chosen partition */ - for (j = 0; j < strlen(par.pmProcessor); j++) { - par.pmProcessor[j] = tolower(par.pmProcessor[j]); - } - - if ((__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsBootValid) && - strcmp(par.pmProcessor, "powerpc") == 0) { - parnum = i; - - DPRINTF("Located CHRP-compliant boot partition %d\n", parnum); - } - } - } - - /* If we found a valid CHRP partition, add it to the list */ - if (parnum > 0) { - parlist[parlist_size++] = parnum; - } - - /* If we found an Apple OF fallback partition, add it to the list */ - if (apple_parnum > 0 && apple_parnum != parnum) { - parlist[parlist_size++] = apple_parnum; - } - - } else { - /* Another partition was explicitly requested */ - parlist[parlist_size++] = parnum; - - DPRINTF("Partition %d explicitly requested\n", parnum); - } - - /* Attempt to use our CHRP partition, optionally followed by our Apple OF fallback partition */ - for (j = 0; j < parlist_size; j++) { - - /* Make sure our partition is valid */ - parnum = parlist[j]; - - DPRINTF("Selected partition %d\n", parnum); - - SEEK( bs * parnum ); - READ( &par, sizeof(par) ); - - if(! ((__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable)) ) { - DPRINTF("Partition %d is not valid, allocated and readable\n", parnum); - goto out; - } - - ret = -1; - - offs = (long long)__be32_to_cpu(par.pmPyPartStart) * bs; - size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs; - - if (want_bootcode) { - - /* If size == 0 then fail because we requested bootcode but it doesn't exist */ - size = (long long)__be32_to_cpu(par.pmBootSize); - if (!size) { - ret = 0; - goto out; - } - - /* Adjust seek position so 0 = start of bootcode */ - offs += (long long)__be32_to_cpu(par.pmLgBootStart) * bs; - - di->bootcode_addr = __be32_to_cpu(par.pmBootLoad); - di->bootcode_entry = __be32_to_cpu(par.pmBootEntry); - } - - di->blocksize = (unsigned int)bs; - - di->offs_hi = offs >> BITS; - di->offs_lo = offs & (ucell) -1; - - di->size_hi = size >> BITS; - di->size_lo = size & (ucell) -1; - - /* If we're trying to execute bootcode then we're all done */ - if (want_bootcode) { - goto out; - } - - /* 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 on partition %d with ph " FMT_ucellx " and args %s\n", parnum, ph, argstr); - di->filesystem_ph = ph; - - /* In case no partition was specified, set a special selected-partition-args property - giving the device parameters that we can use to generate bootpath */ - tmpstr = malloc(strlen(argstr) + 2 + 1); - if (strlen(argstr)) { - sprintf(tmpstr, "%d,%s", parnum, argstr); - } else { - sprintf(tmpstr, "%d", parnum); - } - - push_str(tmpstr); - feval("strdup encode-string \" selected-partition-args\" property"); - - free(tmpstr); - - /* If we have been asked to open a particular file, interpose the filesystem package with - the passed filename as an argument */ - if (strlen(argstr)) { - push_str( argstr ); - PUSH_ph( ph ); - fword("interpose"); - } - - goto out; - } else { - DPRINTF("mac-parts: no filesystem found on partition %d; bypassing misc-files interpose\n", parnum); - - /* Here we have a valid partition; however if we tried to pass in a file argument for a - partition that doesn't contain a filesystem, then we must fail */ - if (strlen(argstr)) { - ret = 0; - } - } - } - - free( str ); - -out: - PUSH( ret ); -} - -/* ( block0 -- flag? ) */ -static void -macparts_probe( macparts_info_t *dummy ) -{ - desc_map_t *dmap = (desc_map_t*)cell2pointer(POP()); - - DPRINTF("macparts_probe %x ?= %x\n", dmap->sbSig, DESC_MAP_SIGNATURE); - if( __be16_to_cpu(dmap->sbSig) != DESC_MAP_SIGNATURE ) - RET(0); - RET(-1); -} - -/* ( -- type offset.d size.d ) */ -static void -macparts_get_info( macparts_info_t *di ) -{ - DPRINTF("macparts_get_info"); - - PUSH( -1 ); /* no type */ - PUSH( di->offs_lo ); - PUSH( di->offs_hi ); - PUSH( di->size_lo ); - PUSH( di->size_hi ); -} - -/* ( -- size entry addr ) */ -static void -macparts_get_bootcode_info( macparts_info_t *di ) -{ - DPRINTF("macparts_get_bootcode_info"); - - PUSH( di->size_lo ); - PUSH( di->bootcode_entry ); - PUSH( di->bootcode_addr ); -} - -static void -macparts_block_size( macparts_info_t *di ) -{ - DPRINTF("macparts_block_size = %x\n", di->blocksize); - PUSH(di->blocksize); -} - -static void -macparts_initialize( macparts_info_t *di ) -{ - fword("register-partition-package"); -} - -/* ( pos.d -- status ) */ -static void -macparts_seek(macparts_info_t *di ) -{ - long long pos = DPOP(); - long long offs, size; - - DPRINTF("macparts_seek %llx:\n", pos); - - /* Seek is invalid if we reach the end of the device */ - size = ((ducell)di->size_hi << BITS) | di->size_lo; - if (pos > size) - RET( -1 ); - - /* 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 ) -{ - /* Invoke the loader */ - load(my_self()); -} - -/* ( pathstr len -- ) */ -static void -macparts_dir( macparts_info_t *di ) -{ - /* On PPC Mac, the first partition chosen according to the CHRP boot - specification (i.e. marked as bootable) may not necessarily contain - a valid FS */ - if ( di->filesystem_ph ) { - PUSH( my_self() ); - push_str("dir"); - PUSH( di->filesystem_ph ); - fword("find-method"); - POP(); - fword("execute"); - } else { - forth_printf("mac-parts: Unable to determine filesystem\n"); - POP(); - POP(); - } -} - -NODE_METHODS( macparts ) = { - { "probe", macparts_probe }, - { "open", macparts_open }, - { "seek", macparts_seek }, - { "read", macparts_read }, - { "load", macparts_load }, - { "dir", macparts_dir }, - { "get-info", macparts_get_info }, - { "get-bootcode-info", macparts_get_bootcode_info }, - { "block-size", macparts_block_size }, - { NULL, macparts_initialize }, -}; - -void -macparts_init( void ) -{ - REGISTER_NODE( macparts ); -} |