Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / arch / ppc / mol / osi-blk.c
diff --git a/qemu/roms/openbios/arch/ppc/mol/osi-blk.c b/qemu/roms/openbios/arch/ppc/mol/osi-blk.c
new file mode 100644 (file)
index 0000000..4ed1b5a
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *   Creation Date: <2003/12/07 19:08:33 samuel>
+ *   Time-stamp: <2004/01/07 19:38:36 samuel>
+ *
+ *     <osi-blk.c>
+ *
+ *     OSI-block interface
+ *
+ *   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 "mol/mol.h"
+#include "osi_calls.h"
+
+typedef struct {
+       int     unit;
+       int     channel;
+} osiblk_data_t;
+
+
+DECLARE_NODE( osiblk, INSTALL_OPEN, sizeof(osiblk_data_t),
+             "/pci/pci-bridge/mol-blk/disk", "/mol/mol-blk" );
+
+
+static void
+osiblk_open( osiblk_data_t *pb )
+{
+       phandle_t ph;
+
+       fword("my-unit");
+       pb->unit = POP();
+       pb->channel = 0;        /* FIXME */
+
+       selfword("open-deblocker");
+
+       /* interpose disk-label */
+       ph = find_dev("/packages/disk-label");
+       fword("my-args");
+       PUSH_ph( ph );
+       fword("interpose");
+
+       /* printk("osi-blk: open %d\n", pb->unit ); */
+       PUSH( -1 );
+}
+
+static void
+osiblk_close( osiblk_data_t *pb )
+{
+       selfword("close-deblocker");
+}
+
+
+/* ( buf blk nblks -- actual ) */
+static void
+osiblk_read_blocks( osiblk_data_t *pb )
+{
+       int i, n = POP();
+       int blk = POP();
+       char *dest = (char*)POP();
+
+       /* printk("osiblk_read_blocks %x block=%d n=%d\n", (int)dest, blk, n ); */
+
+       for( i=0; i<n; ) {
+               char buf[4096];
+               int m = MIN( n-i, sizeof(buf)/512 );
+
+               if( OSI_ABlkSyncRead(pb->channel, pb->unit, blk+i, (int)buf, m*512) < 0 ) {
+                       printk("SyncRead: error\n");
+                       RET(0);
+               }
+               memcpy( dest, buf, m * 512 );
+               i += m;
+               dest += m * 512;
+       }
+       PUSH( n );
+}
+
+/* ( -- bs ) */
+static void
+osiblk_block_size( osiblk_data_t *pb )
+{
+       PUSH( 512 );
+}
+
+/* ( -- maxbytes ) */
+static void
+osiblk_max_transfer( osiblk_data_t *pb )
+{
+       PUSH( 1024*1024 );
+}
+
+static void
+osiblk_initialize( osiblk_data_t *pb )
+{
+       fword("is-deblocker");
+}
+
+
+NODE_METHODS( osiblk ) = {
+       { NULL,                 osiblk_initialize       },
+       { "open",               osiblk_open             },
+       { "close",              osiblk_close            },
+       { "read-blocks",        osiblk_read_blocks      },
+       { "block-size",         osiblk_block_size       },
+       { "max-transfer",       osiblk_max_transfer     },
+};
+
+void
+osiblk_init( void )
+{
+       REGISTER_NODE( osiblk );
+}