summaryrefslogtreecommitdiff
path: root/roms/openbios/arch/ppc/mol/pseudodisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/openbios/arch/ppc/mol/pseudodisk.c')
-rw-r--r--roms/openbios/arch/ppc/mol/pseudodisk.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/roms/openbios/arch/ppc/mol/pseudodisk.c b/roms/openbios/arch/ppc/mol/pseudodisk.c
new file mode 100644
index 000000000..a98e54845
--- /dev/null
+++ b/roms/openbios/arch/ppc/mol/pseudodisk.c
@@ -0,0 +1,178 @@
+/*
+ * Creation Date: <2003/11/26 16:55:47 samuel>
+ * Time-stamp: <2004/01/07 19:41:54 samuel>
+ *
+ * <pseudodisk.c>
+ *
+ * pseudodisk (contains files exported from linux)
+ *
+ * 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 "osi_calls.h"
+#include "libc/string.h"
+#include "libopenbios/ofmem.h"
+#include "mol/prom.h"
+#include "mol/mol.h"
+#include "osi_calls.h"
+#include "pseudofs_sh.h"
+
+typedef struct {
+ int seekpos;
+ int fd;
+ char *myargs;
+ char *name;
+ int size;
+} pdisk_data_t;
+
+
+DECLARE_NODE( pdisk, INSTALL_OPEN, sizeof(pdisk_data_t), "/mol/pseudo-disk/disk" );
+
+static void
+pdisk_open( pdisk_data_t *pb )
+{
+ char *ep, *name = NULL;
+ int part;
+
+ pb->myargs = my_args_copy();
+ /* printk("pdisk-open: %s\n", pb->myargs ); */
+
+ part = strtol( pb->myargs, &ep, 10 );
+ if( *ep ) {
+ if( (name=strchr(pb->myargs, ',')) ) {
+ *name = 0;
+ name++;
+ } else {
+ name = pb->myargs;
+ }
+ }
+ if( part )
+ goto err;
+
+ if( !name || !strlen(name) )
+ pb->fd = -1;
+ else {
+ if( (pb->fd=PseudoFSOpen(name)) < 0 )
+ goto err;
+ pb->size = PseudoFSGetSize( pb->fd );
+ }
+ pb->name = name;
+ RET( -1 );
+ err:
+ free( pb->myargs );
+ RET(0);
+}
+
+/* ( addr len -- actual ) */
+static void
+pdisk_read( pdisk_data_t *pb )
+{
+ int len = POP();
+ char *dest = (char*)POP();
+ int cnt;
+
+ if( pb->fd < 0 ) {
+ memset( dest, 0, len );
+ PUSH(len);
+ return;
+ }
+ /* dest is not "mol-DMA" safe (might have a nontrivial mapping) */
+ for( cnt=0; cnt<len; ) {
+ char buf[2048];
+ int n = MIN( len-cnt, sizeof(buf) );
+
+ n = PseudoFSRead( pb->fd, pb->seekpos, buf, n );
+ if( n <= 0 )
+ break;
+
+ memcpy( dest+cnt, buf, n );
+ cnt += n;
+ pb->seekpos += n;
+ }
+ PUSH( cnt );
+}
+
+/* ( addr len -- actual ) */
+static void
+pdisk_write( pdisk_data_t *pb )
+{
+ POP(); POP(); PUSH(-1);
+ printk("pdisk write\n");
+}
+
+/* ( pos.lo pos.hi -- status ) */
+static void
+pdisk_seek( pdisk_data_t *pb )
+{
+ int pos_lo;
+ POP();
+ pos_lo = POP();
+
+ if( pb->fd >= 0 ) {
+ if( pos_lo == -1 )
+ pos_lo = pb->size;
+ }
+
+ pb->seekpos = pos_lo;
+
+ PUSH(0); /* ??? */
+}
+
+/* ( -- pos.d ) */
+static void
+pdisk_tell( pdisk_data_t *pb )
+{
+ DPUSH( pb->seekpos );
+}
+
+/* ( -- cstr ) */
+static void
+pdisk_get_path( pdisk_data_t *pb )
+{
+ PUSH( (int)pb->name );
+}
+
+/* ( -- cstr ) */
+static void
+pdisk_get_fstype( pdisk_data_t *pb )
+{
+ PUSH( (int)"PSEUDO" );
+}
+
+/* ( -- cstr ) */
+static void
+pdisk_volume_name( pdisk_data_t *pb )
+{
+ PUSH( (int)"Virtual Volume" );
+}
+
+static void
+pdisk_block_size( pdisk_data_t *pb )
+{
+ PUSH(1);
+}
+
+NODE_METHODS( pdisk ) = {
+ { "open", pdisk_open },
+ { "read", pdisk_read },
+ { "write", pdisk_write },
+ { "seek", pdisk_seek },
+ { "tell", pdisk_tell },
+ { "block-size", pdisk_block_size },
+ { "get-path", pdisk_get_path },
+ { "get-fstype", pdisk_get_fstype },
+ { "volume-name", pdisk_volume_name },
+};
+
+void
+pseudodisk_init( void )
+{
+ REGISTER_NODE( pdisk );
+}