summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/packages/pc-parts.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/packages/pc-parts.c')
-rw-r--r--qemu/roms/openbios/packages/pc-parts.c393
1 files changed, 0 insertions, 393 deletions
diff --git a/qemu/roms/openbios/packages/pc-parts.c b/qemu/roms/openbios/packages/pc-parts.c
deleted file mode 100644
index 771923efe..000000000
--- a/qemu/roms/openbios/packages/pc-parts.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * pc partition support
- *
- * Copyright (C) 2004 Stefan Reinauer
- *
- * This code is based (and copied in many places) from
- * mac partition support by 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 "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 {
- xt_t seek_xt, read_xt;
- ucell offs_hi, offs_lo;
- ucell size_hi, size_lo;
- phandle_t filesystem_ph;
-} 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(pointer2cell(buf)); PUSH(size); call_parent(di->read_xt); POP(); })
-
-/* three 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[0x1fe]==0x55 && sect[0x1ff]==0xAA;
-}
-
-static inline int is_pc_extended_part(unsigned char type)
-{
- return type==5 || type==0xf || type==0x85;
-}
-
-/* ( open -- flag ) */
-static void
-pcparts_open( pcparts_info_t *di )
-{
- char *str = my_args_copy();
- 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;
- unsigned char head;
- unsigned char sector;
- unsigned char cyl;
- unsigned char type;
- unsigned char e_head;
- unsigned char e_sector;
- unsigned char e_cyl;
- u32 start_sect; /* unaligned little endian */
- u32 nr_sects; /* ditto */
- } *p, *partition;
-
- unsigned char buf[512];
-
- DPRINTF("pcparts_open '%s'\n", str );
-
- /*
- Arguments that we accept:
- id: [0-7]
- [(id)][,][filespec]
- */
-
- if ( strlen(str) ) {
- /* Detect the arguments */
- if ((*str >= '0' && *str <= '7') || (*str == ',')) {
- push_str(str);
- PUSH(',');
- fword("left-parse-string");
- parstr = pop_fstr_copy();
- argstr = pop_fstr_copy();
- } else {
- argstr = str;
- }
-
- /* Convert the id to a partition number */
- if (parstr && strlen(parstr))
- parnum = atol(parstr);
- }
-
- /* Make sure argstr is not null */
- if (argstr == NULL)
- argstr = strdup("");
-
- DPRINTF("parstr: %s argstr: %s parnum: %d\n", parstr, argstr, parnum);
- free(parstr);
-
- if( parnum < 0 )
- parnum = 0;
-
- di->filesystem_ph = 0;
- di->read_xt = find_parent_method("read");
- di->seek_xt = find_parent_method("seek");
-
- SEEK( 0 );
- if( READ(buf, 512) != 512 )
- RET(0);
-
- /* Check Magic */
- if (!has_pc_part_magic(buf)) {
- DPRINTF("pc partition magic not found.\n");
- RET(0);
- }
-
- /* Actual partition data */
- partition = (struct pc_partition *) (buf + 0x1be);
-
- /* 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 */
- 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 );
- }
-
- offs = (long long)(__le32_to_cpu(p->start_sect)) * bs;
- di->offs_hi = offs >> BITS;
- di->offs_lo = offs & (ucell) -1;
-
- size = (long long)(__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;
- unsigned long ext_start, cur_table;
-
- /* Search for the extended partition
- * which contains logical partitions */
- for (i = 0; i < 4; i++) {
- if (is_pc_extended_part(p[i].type))
- break;
- }
-
- if (i >= 4) {
- DPRINTF("Extended partition not found\n");
- RET( 0 );
- }
-
- 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;
-
- while (cur_part <= parnum) {
- DPRINTF("cur_part=%d at %lx\n", cur_part, cur_table);
-
- SEEK( cur_table * bs );
- if( READ(buf, sizeof(512)) != sizeof(512) )
- RET( 0 );
-
- if (!has_pc_part_magic(buf)) {
- DPRINTF("Extended partition has no magic\n");
- break;
- }
-
- /* 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) {
- DPRINTF("Partition %d is empty\n", parnum+1);
- RET( 0 );
- }
-
- offs = (long long)(cur_table+__le32_to_cpu(p->start_sect)) * bs;
- di->offs_hi = offs >> BITS;
- di->offs_lo = offs & (ucell) -1;
-
- size = (long long)__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)) {
- DPRINTF("no link\n");
- break;
- }
-
- cur_table = ext_start + __le32_to_cpu(p[1].start_sect);
- cur_part++;
- }
-
- 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, argstr);
- di->filesystem_ph = ph;
-
- /* 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");
- }
- } 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 );
- }
-}
-
-/* ( block0 -- flag? ) */
-static void
-pcparts_probe( pcparts_info_t *dummy )
-{
- unsigned char *buf = (unsigned char *)cell2pointer(POP());
-
- 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 */
- PUSH( di->offs_lo );
- PUSH( di->offs_hi );
- PUSH( di->size_lo );
- PUSH( di->size_hi );
-}
-
-static void
-pcparts_block_size( __attribute__((unused))pcparts_info_t *di )
-{
- PUSH(512);
-}
-
-static void
-pcparts_initialize( pcparts_info_t *di )
-{
- fword("register-partition-package");
-}
-
-/* ( pos.d -- status ) */
-static void
-pcparts_seek(pcparts_info_t *di )
-{
- long long pos = DPOP();
- long long offs, size;
-
- DPRINTF("pcparts_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("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 )
-{
- /* Invoke the loader */
- load(my_self());
-}
-
-/* ( pathstr len -- ) */
-static void
-pcparts_dir( pcparts_info_t *di )
-{
- if ( di->filesystem_ph ) {
- PUSH( my_self() );
- push_str("dir");
- PUSH( di->filesystem_ph );
- fword("find-method");
- POP();
- fword("execute");
- } else {
- forth_printf("pc-parts: Unable to determine filesystem\n");
- POP();
- POP();
- }
-}
-
-NODE_METHODS( pcparts ) = {
- { "probe", pcparts_probe },
- { "open", pcparts_open },
- { "seek", pcparts_seek },
- { "read", pcparts_read },
- { "load", pcparts_load },
- { "dir", pcparts_dir },
- { "get-info", pcparts_get_info },
- { "block-size", pcparts_block_size },
- { NULL, pcparts_initialize },
-};
-
-void
-pcparts_init( void )
-{
- REGISTER_NODE( pcparts );
-}