[Prev][Next][Index][Thread]

random pool bottom example




Hi,

Included below is diffs against St Patrick's and some new files that
demonstrate the bottom interface to the random pool.  The code is a
real mess, I've cut every corner I could and I've left in lots of
debugging prinf's, but I hope it serves to get some discussion going
about how this should be hooked in to OSKit.  For instance, I'm
hanging 'rpchannel' references from the blkdevs data structure, but
don't know if that's the best place for them.  Also, I still don't
fully understand the OSKit naming conventions.  Is it good to have the
random directory I've created or should I put that stuff in an
existing direcory?  I haven't tried to hook up anything but the block
device yet.  The network, keyboard, mouse, etc will come later.  You
can try this by booting rndtest from examples/x86 .

Derek


% diff -ru orig-oskit-20020317/ oskit-20020317/
--- orig-oskit-20020317/examples/x86/GNUmakerules	Tue Feb 27 17:35:35 2001
+++ oskit-20020317/examples/x86/GNUmakerules	Sat Apr 20 17:26:15 2002
@@ -30,7 +30,7 @@
 TARGETS = hello multiboot timer timer_com timer_com2 stream_netio \
 	spf uspf pingreply diskpart diskpart2 blkio tty netbsd_fs_com \
 	netbsd_fs_posix fsread socket_com socket_com2 mouse memtest \
-        memfs_com memfstest1 perfmon anno_test
+        memfs_com memfstest1 perfmon anno_test rndtest
 
 all: $(TARGETS)
 
@@ -433,6 +433,14 @@
 	$(LD) -Ttext 100000 $(LDFLAGS) $(OSKIT_LDFLAGS) \
 		-o $@ $(filter-out %.a,$^)		\
 		-loskit_clientos -loskit_kern -loskit_lmm \
+		$(CLIB) $(OBJDIR)/lib/crtn.o
+
+rndtest: $(OBJDIR)/lib/multiboot.o rndtest.o $(DEPENDLIBS)
+	$(OSKIT_QUIET_MAKE_INFORM) "Linking example $@"
+	$(LD) -Ttext 100000 $(LDFLAGS) $(OSKIT_LDFLAGS) \
+		-o $@ $(filter-out %.a,$^)		\
+		-loskit_startup -loskit_clientos -loskit_linux_dev \
+		-loskit_dev -loskit_kern -loskit_lmm -loskit_random \
 		$(CLIB) $(OBJDIR)/lib/crtn.o
 
 endif
Only in oskit-20020317/examples/x86: rndtest.c
diff -ru orig-oskit-20020317/linux/dev/block.h oskit-20020317/linux/dev/block.h
--- orig-oskit-20020317/linux/dev/block.h	Mon Dec  7 06:14:41 1998
+++ oskit-20020317/linux/dev/block.h	Wed May  1 00:22:33 2002
@@ -20,6 +20,7 @@
 
 #include <oskit/io/blkio.h>
 #include <oskit/dev/blk.h>
+#include <oskit/dev/rpchannel.h>
 
 /*
  * One of these structures exists for each
@@ -62,6 +63,9 @@
 	/* The following members are set by blkdev_register() */
 	struct file_operations *fops;	/* Linux file operations vector */
 	const char *name;		/* Device name */
+
+        /* This gets set by probe_raw in linux/dev/ide.c */
+	oskit_osenv_rpchannel_t *rpchannel_ref;
 };
 
 extern struct device_struct blkdevs[];
diff -ru orig-oskit-20020317/linux/dev/ide.c oskit-20020317/linux/dev/ide.c
--- orig-oskit-20020317/linux/dev/ide.c	Fri Oct 13 17:56:07 2000
+++ oskit-20020317/linux/dev/ide.c	Sun May  5 11:54:52 2002
@@ -27,11 +27,17 @@
 #include <oskit/dev/isa.h>
 #include <oskit/dev/ide.h>
 #include <oskit/dev/native.h>
+#include <oskit/dev/randompool.h>
+#include <oskit/dev/rpchannel.h>
 
 #include "glue.h"
 #include "block.h"
 #include "osenv.h"
 
+/* +++ DLD DEBUG FIXME */
+#include <oskit/c/stdio.h>
+/* --- DLD */
+
 static oskit_error_t probe(struct driver_struct *ds);
 
 /* Device driver structure representing the Linux IDE device driver */
@@ -273,8 +279,10 @@
 static oskit_error_t probe_raw(struct driver_struct *ds)
 {
 	static int initialized = 0;
+	oskit_osenv_randompool_t **randompool_aref;
+	oskit_osenv_rpchannel_t *rpchannel_ref = NULL;
 	oskit_error_t rc;
-	int i, j, found;
+	int i, j, found, n_rp_dev;
 
 	if (initialized)
 		return 0;
@@ -283,6 +291,18 @@
 	/* Call the Linux IDE probe code */
 	ide_init();
 
+#if 1
+	/* See if the random pool has been registered */
+	n_rp_dev = osenv_device_lookup(&oskit_osenv_randompool_iid,
+				       (void ***)&randompool_aref);
+	if (n_rp_dev > 1)
+	    panic("Too many random pool devices found!");
+
+	else if (n_rp_dev == 1)
+	    printf("DLD: probe_raw() Got the random pool device!\n");
+	else
+	    printf("DLD: No random pool found.\n");
+#endif
 	/*
 	 * Register each IDE device found in the hardware tree.
 	 * Each hardware interface becomes an IDE bus,
@@ -331,8 +351,37 @@
 		rc = osenv_isabus_addchild(
 			ide_hwifs[i].io_ports[IDE_DATA_OFFSET],
 			(oskit_device_t*)&busi[i]);
+
+#if 1
+		/* Attach to the random pool, if it's been registered, and
+		   store it's emissary for later use (see add_blkdev_randomness()) */
+		printf("Attaching random pool to IDE bus # %d\n", i);
+		oskit_osenv_randompool_attach_source(randompool_aref[0],
+						     NULL, /* char *name */
+						     0,    /* oskit_u32_t type */
+						     0,    /* oskit_u32_t flags */
+						     &rpchannel_ref);
+		printf("storing rp channel %x for major %d\n",
+		       rpchannel_ref,
+		       ide_hwif_to_major[i]);
+		blkdevs[ide_hwif_to_major[i]].rpchannel_ref = rpchannel_ref;
+#endif
 	}
 
+#if 1
+	/* Done with the randompool itself.  All further communication
+	   is via the rpchannel object stored in blkdevs .
+	*/
+	printf("blkdevs is %x\n", blkdevs);
+	if (n_rp_dev == 1)
+	{
+#if 0
+	    oskit_osenv_randompool_release(randompool_aref[0]);
+	    /*free(randompool_aref);*/
+#endif
+	}
+#endif
+	
 	return found;
 }
 
diff -ru orig-oskit-20020317/linux/dev/misc.c oskit-20020317/linux/dev/misc.c
--- orig-oskit-20020317/linux/dev/misc.c	Wed Nov 10 19:53:10 1999
+++ oskit-20020317/linux/dev/misc.c	Sun May  5 11:55:48 2002
@@ -27,6 +27,8 @@
 #include <linux/kernel_stat.h>
 #include <linux/time.h>
 #include <linux/module.h>
+#include <oskit/dev/randompool.h>
+#include <linux/dev/block.h>
 
 #include "linux_emul.h"
 #include "osenv.h"
@@ -107,6 +109,52 @@
 void
 add_blkdev_randomness (int major)
 {
+#if 1
+    printf("blkdevs is %x  ", blkdevs);
+    if (blkdevs[major].rpchannel_ref)
+	printf("add_blkdev_randomness: major %d has rp channel %x!\n",
+	       major,
+	       blkdevs[major].rpchannel_ref);
+#if 1
+    else
+	printf("add_blkdev_randomness: major %d has no rp channel!\n", major);
+#endif
+#else
+    int ndev;
+    oskit_osenv_randompool_t **randompool_ref = NULL;
+
+    if (major >= MAX_BLKDEV)
+    {
+	panic(
+	    "Someone called add_blkdev_randomness with major %d > MAX_BLKDEV",
+	    major);
+    }
+    /*
+    printf("Someone called add_blkdev_randomness, major is %d\n", major);
+    printf("# of randompool services registered in device_registry is %d\n",
+	   oskit_services_lookup(device_registry,
+				 &oskit_osenv_randompool_iid,
+				 (void***)&randompool_ref));
+    */
+    ndev = osenv_device_lookup(&oskit_osenv_randompool_iid,
+			       (void***)&randompool_ref);
+
+    if (ndev > 0)
+    {
+	printf("dev major #%d found randompool\n", major);
+	oskit_osenv_randompool_release(randompool_ref[0]);
+#if 0
+	printf("add_blkdev_randomness, doing add_data call\n");
+	oskit_osenv_randompool_add_data(randompool_ref[0], NULL, 0, 0);
+#endif
+    }
+    else
+    {
+#if 0
+	printf("dev major #%d didn't find randompool\n", major);
+#endif
+    }
+#endif
 }
 
 int
diff -ru orig-oskit-20020317/modules.x86.pc oskit-20020317/modules.x86.pc
--- orig-oskit-20020317/modules.x86.pc	Tue Mar 12 12:38:48 2002
+++ oskit-20020317/modules.x86.pc	Sat Apr 20 11:34:35 2002
@@ -202,6 +202,9 @@
 ## Requires the udp library.
 #netdisk
 
+### The random number stuff.
+random
+
 ### --- Scripts and build/debug utilities
 
 ### Includes the CPU-oskit-gcc wrapper.
Only in oskit-20020317/oskit/dev: randompool.h
Only in oskit-20020317/oskit/dev: rpchannel.h
Only in oskit-20020317/: random
diff -ru orig-oskit-20020317/startup/start_devices.c oskit-20020317/startup/start_devices.c
--- orig-oskit-20020317/startup/start_devices.c	Thu Nov  2 17:21:16 2000
+++ oskit-20020317/startup/start_devices.c	Mon Apr 22 21:39:18 2002
@@ -30,7 +30,7 @@
 #include <oskit/dev/osenv_sleep.h>
 
 #ifdef DEBUG
-static int verbose = 1;
+static int verbose = 0; /* DLD 1;*/
 #else
 static int verbose = 0;
 #endif




rndtest.c:


/*
 * Random testbed.
 */

/* FIXME: separate these wrt INCL_x */
#include <malloc.h> /* smemalign */
#include <oskit/types.h>
#include <oskit/clientos.h>
#include <oskit/dev/osenv.h>
#include <oskit/dev/randompool.h>
#include <oskit/dev/ethernet.h>
#include <oskit/dev/linux.h>
#include <oskit/net/ether.h>
#include <oskit/c/string.h>
#include <oskit/startup.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
#include <assert.h>
#include "bootp.h"
#include "netinet.h"

extern oskit_services_t *global_registry;
extern oskit_services_t *device_registry;
extern oskit_services_t *driver_registry;

#define MAX_RANDOMPOOL_DEVICES 1	/* max number of randompool devices */

/* static oskit_osenv_randompool_stats_t randompool_stats; */

extern void (*_init_devices_blk)(void);

int test_block(int, int);
int read_test(int, int, char *);

oskit_blkio_t *io;

/* These are in terms of SECTORS. */
int test_offset[] = { 0, 1, 3,  7, 8, 63, 64, 127, 128, 1024, 1025 };
int test_size[]   = { 1, 2, 5, 11, 8, 63, 64, 128, 129, 333, 1024, 1025 };

#define n_offsets (sizeof(test_offset) / sizeof(test_offset[0]))
#define n_sizes (sizeof(test_size) / sizeof(test_size[0]))

static int ndev;

int
main(int argc, char **argv)
{
	oskit_error_t err;
	oskit_osenv_randompool_t *randompool;
	oskit_osenv_randompool_t **randompool_ref;
	oskit_osenv_t *osenv;
	int i;
	int verbose = 1;
	char name[10];
	oskit_size_t sec_size;
	oskit_off_t disk_size;
	int rc;
	int n_tests, j;

	/* Must be on little endian machine. */
	i = 1;
	assert(*(char *)&i == 1);
	
	oskit_clientos_init();
	osenv = start_osenv();

#if 1 // HERE DLD
	/* ===================================================== */
	/*
	 * Initialize the random pool device.
	 */
	/*printf("DLD: Calling oskit_osenv_randompool_init\n");*/
	randompool = oskit_osenv_randompool_init();

	/*
	 * Make it possible to query the device registry.
	 */
	/*printf("DLD: Calling osenv_device_registration_init\n");*/
	osenv_device_registration_init();

#if 1
	oskit_dev_init(osenv);
	oskit_linux_init_osenv(osenv);
#endif
	
	/*printf("DLD: Registering random pool device\n");*/
	(void)osenv_device_register((oskit_device_t *)randompool,
				    &oskit_osenv_randompool_iid, 1);
	/*
	 * Find the random pool device node.
	 */
	/*printf("Calling osenv_device_lookup\n");*/
	ndev = osenv_device_lookup(&oskit_osenv_randompool_iid,
				   (void***)&randompool_ref);
	if (ndev <= 0)
		panic("No random pool device found!");
	if (ndev > MAX_RANDOMPOOL_DEVICES)
		panic("Too many random pool devices found!");

	printf("DLD: main() -- init'd random pool device!\n");
#endif
	
#if 1
	/*
	 * Start the block devices
	 */
	printf("DLD: Starting blk devices\n");
	/* start_blk_devices(); */
#if 0
	oskit_dev_init(osenv);
	oskit_linux_init_osenv(osenv);
#endif
	_init_devices_blk = oskit_linux_init_blk;
	(*_init_devices_blk)();
#if 0
	if (verbose)
		oskit_dump_drivers();
#endif
	if (verbose)
		printf("Probing devices...\n");
	oskit_dev_probe();
#if 0
	if (verbose)
		oskit_dump_devices();
#endif
#endif

	do {
		printf("\nEnter drive name (eg hda1) to test, `quit' to exit: ");
		gets(name);

		if (!strcmp(name, "quit"))
			return 1;

		if (!strcmp(name, ""))
			continue;

		printf("Opening disk %s...\n", name);
		err = oskit_linux_block_open(name, OSKIT_DEV_OPEN_READ, &io);

		if (err) {
			if (err == OSKIT_E_DEV_NOSUCH_DEV)
				printf("disk %s does not exist!\n", name);
			else	
				printf("error %x opening disk %s\n", 
				       err, name);
		}
		
	} while (err);

	sec_size = oskit_blkio_getblocksize(io);
	printf("disk native sectors are %d bytes\n", sec_size);

	if (oskit_blkio_getsize(io, &disk_size)) {
		printf("Can't determine disk size...assuming the disk is big enough!\n");
		disk_size = (test_offset[n_offsets - 1] + 
			    test_size[n_sizes - 1]) * sec_size;
	} else
		printf("size of disk is %d kbytes\n", 
		       (unsigned int)(disk_size >> 10));

	n_tests = n_offsets;
	printf("\nRunning %d tests\n\n", n_tests);
	for (i = 0; i < n_tests; i++) {
		for (j = 0; j < n_sizes; j++) {
			if (((test_offset[i] + test_size[j]) * sec_size) <=
			    disk_size) {
				rc = test_block(test_offset[i] * sec_size, 
						test_size[j] * sec_size);

				if (rc) {
					printf("\nEXITING: errors in the disk tests.\n");
				
					oskit_blkio_release(io);
					return rc;
				}
			}
		}
	}
	oskit_blkio_release(io);

	printf("\nTests completed with no errors.\n");
	
	oskit_osenv_randompool_release(randompool_ref[0]);
	
	return 0;
}

int
read_test(int offset, int size, char *buf)
{
	int err, amt;

#ifdef DEBUG_TEST
	printf("Reading %d bytes at offset %d\n", size,
		offset);
#endif

	err = oskit_blkio_read(io, buf, offset, size, &amt);
	if (err) {
		printf("  Read ERROR %08x\n", err);
		return(1);
	}

#ifdef DEBUG_TEST
	printf("Read done, amt = %d of %d\n", amt, size);
#endif

	return 0;
}

/*
 * This runs tests on a bunch of disk blocks.
 * Generally, these should be an integral multiple of sectors aligned
 * on a sector boundary.
 */
int
test_block(int offset, int size)
{
	char *wbuf;

	/* Allocate memory for the data */
	wbuf = smemalign(512, size);
	if (!wbuf) {
		printf("  can't allocate buf!\n");
		_exit(1);
	}
	memset(wbuf, 0xA5, size);

#if 0
	printf("Doing read test of %d bytes at offset %d\n", size, offset);
#endif

	/* Read in blocks from the disk. */
	if (read_test(offset, size, wbuf))
		return -1;

#ifdef DEBUG_TEST
	printf("read %x\n", wbuf[0] & 0xff);
#endif
	
	/* release the memory */
	sfree(wbuf, size);
	
	return 0;
}

/* End of rndtest.c */



randompool.h:

/*
 * Copyright (c) 1997-1999 University of Utah and the Flux Group.
 * All rights reserved.
 * 
 * This file is part of the Flux OSKit.  The OSKit is free software, also known
 * as "open source;" you can redistribute it and/or modify it under the terms
 * of the GNU General Public License (GPL), version 2, as published by the Free
 * Software Foundation (FSF).  To explore alternate licensing terms, contact
 * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
 * 
 * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have
 * received a copy of the GPL along with the OSKit; see the file COPYING.  If
 * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
 */
/*
 * COMification of the osenv random pool interface. 
 */
#ifndef _OSKIT_DEV_OSENV_RANDOMPOOL_H_
#define _OSKIT_DEV_OSENV_RANDOMPOOL_H_

#include <oskit/com.h>
#include <oskit/dev/driver.h>
#include <oskit/error.h>
#include <oskit/dev/rpchannel.h>

/*
 * osenv random pool interface.
 *
 * IID FIXME: 4aa7dfee-7c74-11cf-5bee80ee9035da2c
 */
struct oskit_osenv_randompool {
	struct oskit_osenv_randompool_ops *ops;
};
typedef struct oskit_osenv_randompool oskit_osenv_randompool_t;

oskit_osenv_randompool_t *oskit_osenv_randompool_init(void);

struct oskit_osenv_randompool_ops {

	/*** COM-specified IUnknown interface operations ***/
	OSKIT_COMDECL_IUNKNOWN(oskit_osenv_randompool_t)

	/*** Simultaneously extend oskit_device_t and oskit_driver_t ***/
	OSKIT_COMDECL	(*getinfo)(oskit_osenv_randompool_t *r, oskit_devinfo_t *out_info);
	OSKIT_COMDECL	(*getdriver)(oskit_osenv_randompool_t *r,
				     oskit_driver_t **out_driver);

#if 0
	/*** randompool stuff ***/
	OSKIT_COMDECL_V (*add_data)(oskit_osenv_randompool_t *r, void *data,
				    oskit_u32_t len, oskit_u32_t entropy);

	OSKIT_COMDECL_V (*get_stats)(oskit_osenv_randompool_t *r,
				     oskit_osenv_randompool_stats_t *stats);
#endif
	/*** This is how device drivers attach to the random pool.
	     They then talk to the randompool through the channel. ***/
	OSKIT_COMDECL (*attach_source)(oskit_osenv_randompool_t *r,
				       char *name,
				       oskit_u32_t type,
				       oskit_u32_t flags,
				       oskit_osenv_rpchannel_t **out_chan);
};

/* GUID for oskit_osenv_randompool interface */
/* DLD FIXME: I made this up!! */
extern const struct oskit_guid oskit_osenv_randompool_iid;
#define OSKIT_OSENV_RANDOMPOOL_IID OSKIT_GUID(0x4aa7dfee, 0x7c74, 0x11cf, \
				0x5b, 0xee, 0x80, 0xee, 0x90, 0x35, 0xda, 0x2c)

#define oskit_osenv_randompool_query(r, iid, out_ihandle) \
	((r)->ops->query((oskit_osenv_randompool_t *)(r), (iid), (out_ihandle)))
#define oskit_osenv_randompool_addref(r) \
	((r)->ops->addref((oskit_osenv_randompool_t *)(r)))
#define oskit_osenv_randompool_release(r) \
	((r)->ops->release((oskit_osenv_randompool_t *)(r)))

#define oskit_osenv_getinfo(r, dev, inf) \
	((r)->ops->getinfo((oskit_osenv_randompool_t *)(r), (dev), (inf)))
#define oskit_osenv_getdriver(r, dev, drv) \
	((r)->ops->getdriver((oskit_osenv_randompool_t *)(r), (dev), (drv)))

#if 0
#define oskit_osenv_randompool_add_data(r, data, len, entropy) \
	((r)->ops->add_data((oskit_osenv_randompool_t *)(r), (data), (len), (entropy)))

#define oskit_osenv_randompool_get_stats(r, stats) \
	((r)->ops->get_stats((oskit_osenv_randompool_t *)(r), (stats)))
#endif

#define oskit_osenv_randompool_attach_source(r, name, type, flags, chan) \
	((r)->ops->attach_source((oskit_osenv_randompool_t *)(r), \
				 (name), (type), (flags), (chan)))

/*
 * Return a reference to an osenv randompool interface object.
 */
#if 0
oskit_osenv_randompool_t	*oskit_create_osenv_randompool(void);
#endif

#endif /* _OSKIT_DEV_OSENV_RANDOMPOOL_H_ */


rpchannel.h:


#ifndef _OSKIT_DEV_OSENV_RPCHANNEL_H_
#define _OSKIT_DEV_OSENV_RPCHANNEL_H_

#include <oskit/com.h>
#include <oskit/error.h>
#include <oskit/dev/osenv_mem.h>

typedef struct stats
{
    unsigned add_data_count;
}
oskit_osenv_randompool_stats_t;

/*
 * osenv random pool channel interface.  This is how drivers
 * communicate with the random pool.
 *
 * IID FIXME: 4fa7d9ee-7324-44cf-5bcb80ae5032d329
 *
 */
struct oskit_osenv_rpchannel {
	struct oskit_osenv_rpchannel_ops *ops;
};
typedef struct oskit_osenv_rpchannel oskit_osenv_rpchannel_t;

struct oskit_osenv_rpchannel_ops {

	/*** COM-specified IUnknown interface operations ***/
	OSKIT_COMDECL_IUNKNOWN(oskit_osenv_rpchannel_t)

	/*** random pool channel stuff ***/
	OSKIT_COMDECL_V (*add_data)(oskit_osenv_rpchannel_t *c, void *data,
				    oskit_u32_t len, oskit_u32_t entropy);

	OSKIT_COMDECL_V (*get_stats)(oskit_osenv_rpchannel_t *c,
				     oskit_osenv_randompool_stats_t *stats);
};

/* GUID for oskit_osenv_rpchannel interface */
/* DLD FIXME: I made this up!! */
extern const struct oskit_guid oskit_osenv_rpchannel_iid;
#define OSKIT_OSENV_RPCHANNEL_IID OSKIT_GUID(0x4fa7d9ee, 0x7324, 0x44cf, \
				             0x5b, 0xcb, 0x80, 0xae, 0x50, 0x32, 0xd3, 0x29)

#define oskit_osenv_rpchannel_query(c, iid, out_ihandle) \
	((c)->ops->query((oskit_osenv_rpchannel_t *)(c), (iid), (out_ihandle)))
#define oskit_osenv_rpchannel_addref(c) \
	((c)->ops->addref((oskit_osenv_rpchannel_t *)(c)))
#define oskit_osenv_rpchannel_release(c) \
	((c)->ops->release((oskit_osenv_rpchannel_t *)(c)))

#define oskit_osenv_rpchannel_add_data(c, data, len, entropy) \
	((c)->ops->add_data((oskit_osenv_rpchannel_t *)(c), (data), (len), (entropy)))

#define oskit_osenv_rpchannel_get_stats(c, stats) \
	((c)->ops->get_stats((oskit_osenv_rpchannel_t *)(c), (stats)))

oskit_error_t create_rpchannel(oskit_osenv_mem_t *, oskit_osenv_rpchannel_t **);
    
#endif

<oskit-src-root>/random/randompool.c:

/*
 * Copyright (c) 1996, 1998, 1999 University of Utah and the Flux Group.
 * All rights reserved.
 * 
 * This file is part of the Flux OSKit.  The OSKit is free software, also known
 * as "open source;" you can redistribute it and/or modify it under the terms
 * of the GNU General Public License (GPL), version 2, as published by the Free
 * Software Foundation (FSF).  To explore alternate licensing terms, contact
 * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
 * 
 * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have
 * received a copy of the GPL along with the OSKit; see the file COPYING.  If
 * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
 */

/*
 * Default randompool control object.
 */
#include <oskit/dev/osenv.h>
#include <oskit/dev/osenv_mem.h>
#include <oskit/com.h>
#include <oskit/dev/driver.h>
#include <oskit/dev/randompool.h>
#include <oskit/dev/rpchannel.h>
/*#include <stdlib.h>*/
/*#include <string.h>*/

/* +++ Debug only... */
#include <stdio.h>
#include <oskit/debug.h>
/* --- */

static oskit_osenv_randompool_stats_t randompool_internal;

static struct oskit_osenv_randompool_ops	osenv_randompool_ops;
#if 0
static struct oskit_osenv_randompool		osenv_randompool_object={&osenv_randompool_ops};
#endif

typedef struct osenv_randompool_impl {
	oskit_osenv_randompool_t	irp;    /* COM random pool interface */
	unsigned			count;  /* Ref count */

	unsigned			add_data_count; /* Number of calls to add_data */

#ifndef KNIT
	oskit_osenv_mem_t		*mem;
#endif
} osenv_randompool_impl_t;

/*
 * Currently, we only support one instance
 * Note the COM code is written for dynamic allocation/deallocation,
 * which is why we keep a pointer here
 */
osenv_randompool_impl_t	*oskit_osenv_randompool;

static OSKIT_COMDECL
randompool_query(oskit_osenv_randompool_t *r, const oskit_iid_t *iid, void **out_ihandle)
{
    printf ("randompool_query\n");
        if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
            memcmp(iid, &oskit_osenv_randompool_iid, sizeof(*iid)) == 0) {
                *out_ihandle = r;
                return 0;
        }

        *out_ihandle = 0;
        return OSKIT_E_NOINTERFACE;
};

static OSKIT_COMDECL_U
randompool_addref(oskit_osenv_randompool_t *r)
{
	printf ("randompool_addref\n");

	/* Only one object */
	return 1;
}

static OSKIT_COMDECL_U
randompool_release(oskit_osenv_randompool_t *r)
{
	printf ("randompool_release\n");
	
	/* Only one object */
	return 1;
}

static OSKIT_COMDECL
randompool_getinfo(oskit_osenv_randompool_t *r, oskit_devinfo_t *out_info)
{
	printf ("randompool_getinfo\n");

	return 0;
}

static OSKIT_COMDECL
randompool_getdriver(oskit_osenv_randompool_t *r, oskit_driver_t **out_driver)
{
	printf ("randompool_getdriver\n");

	return 0;
}

#if 0
static OSKIT_COMDECL_V
randompool_add_data(oskit_osenv_randompool_t *r, void* data, oskit_u32_t len, oskit_u32_t entropy)
{
	printf("randompool_add_data\n");

	randompool_internal.add_data_count++;

	return;
}

static OSKIT_COMDECL_V
randompool_get_stats(oskit_osenv_randompool_t *r, oskit_osenv_randompool_stats_t *stats)
{
	if (stats != NULL)
	{
	    stats->add_data_count == randompool_internal.add_data_count;
	}
	
	return;
}
#endif

static OSKIT_COMDECL
randompool_attach_source(oskit_osenv_randompool_t *r,
			 char *name,
			 oskit_u32_t type,
			 oskit_u32_t flags,
			 oskit_osenv_rpchannel_t **out_chan)
{
	oskit_osenv_rpchannel_t *c;
	oskit_error_t e;

	printf ("randompool_attach_source\n");

	e = create_rpchannel(oskit_osenv_randompool->mem, &c);
	if (e) return e;

	*out_chan = c;
	
	return 0;
}

static struct oskit_osenv_randompool_ops osenv_randompool_ops = {
	randompool_query,
	randompool_addref,
	randompool_release,
	randompool_getinfo,
	randompool_getdriver,
#if 0
	randompool_add_data,
	randompool_get_stats,
#endif
	randompool_attach_source
};

#if 0
oskit_osenv_randompool_t *
oskit_create_osenv_randompool(void)
{
    printf ("oskit_create_osenv_randompool\n");
	return &osenv_randompool_object;
}
#else
/* Not sure how I got the idea for the above.  This is
   cribbed from dev/clock.c//oskit_clock_init() which is used
   early on in numerous example kernels to access the clock device.
*/

/*
 * Return a reference to the random pool; creating the object if necessary
 */
oskit_osenv_randompool_t *
oskit_osenv_randompool_init()
{
    osenv_randompool_impl_t    *rp;
#ifndef KNIT
    oskit_osenv_t *osenv;
    oskit_osenv_mem_t *mem;
#endif /* KNIT */

    if (oskit_osenv_randompool) {
	++oskit_osenv_randompool->count;
	return &oskit_osenv_randompool->irp;
    }

    randompool_internal.add_data_count = 0;
    
#ifndef KNIT
    oskit_lookup_first(&oskit_osenv_iid, (void *) &osenv);

    if (!osenv)
	panic("oskit_osenv_randompool_init(): osenv not yet registered.");

    oskit_osenv_lookup(osenv,
		       &oskit_osenv_mem_iid, (void *) &mem);

    oskit_osenv_release(osenv);
#endif /* KNIT */

    /*
     * Instantiate the COM object
     */
    rp = (osenv_randompool_impl_t *)oskit_osenv_mem_alloc(mem, sizeof(*rp), 0, 0);

    if (rp == NULL)
	return NULL;

    memset(rp, 0, sizeof(*rp));
    rp->irp.ops = &osenv_randompool_ops;
    rp->count = 1;

#ifndef KNIT
    rp->mem = mem;
#endif /* KNIT */
    
    oskit_osenv_randompool->mem = mem;
    
    return &rp->irp;
}
#endif

/* End of osenv_randompool.c */


<oskit-src-root>/random/rpchannel.c:


#include <oskit/dev/rpchannel.h>

/* +++ Debug Only */
#include <stdio.h>
/* --- */

#if 0
static oskit_osenv_rpchannel_stats_t rpchannel_internal;
#endif

static struct oskit_osenv_rpchannel_ops		osenv_rpchannel_ops;
static struct oskit_osenv_rpchannel		osenv_rpchannel_object={&osenv_rpchannel_ops};

typedef struct osenv_rpchannel_impl {
	oskit_osenv_rpchannel_t		irc;
	unsigned			count;
} osdenv_rpchannel_impl_t;

static OSKIT_COMDECL
rpchannel_query(oskit_osenv_rpchannel_t *r,
		const oskit_iid_t *iid,
		void **out_ihandle)
{
	printf ("rpchannel_query\n");
        if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
            memcmp(iid, &oskit_osenv_rpchannel_iid, sizeof(*iid)) == 0) {
                *out_ihandle = r;
                return 0;
        }

        *out_ihandle = 0;
        return OSKIT_E_NOINTERFACE;
};

static OSKIT_COMDECL_U
rpchannel_addref(oskit_osenv_rpchannel_t *r)
{
    printf ("rpchannel_addref\n");
	/* Only one object */
	return 1;
}

static OSKIT_COMDECL_U
rpchannel_release(oskit_osenv_rpchannel_t *r)
{
	printf ("rpchannel_release\n");
	
	/* Only one object */
	return 1;
}

static OSKIT_COMDECL_V
rpchannel_add_data(oskit_osenv_rpchannel_t *c, void *data,
		   oskit_u32_t len, oskit_u32_t entropy)
{
	return;
}

static OSKIT_COMDECL_V
rpchannel_get_stats(oskit_osenv_rpchannel_t *c,
		    oskit_osenv_randompool_stats_t *stats)
{
	return;
}

static struct oskit_osenv_rpchannel_ops osenv_rpchannel_ops = {
	rpchannel_query,
	rpchannel_addref,
	rpchannel_release,
	rpchannel_add_data,
	rpchannel_get_stats
};

oskit_error_t create_rpchannel(oskit_osenv_mem_t *mem, oskit_osenv_rpchannel_t **out_chan)
{
	oskit_osenv_rpchannel_t *c;

	c = (oskit_osenv_rpchannel_t *)oskit_osenv_mem_alloc(mem, sizeof(*c), 0, 0);

	if (c == NULL)
	    return OSKIT_E_OUTOFMEMORY;

	memset(c, 0, sizeof(*c));
	c->ops = &osenv_rpchannel_ops;
	/*c->count = 1;*/

	*out_chan = &c;
	
	return 0;
}

/* End of rpchannel.c */


<oskit-src-root>/random/GNUmakefile.in

#
# Copyright (c) 1996, 1998 University of Utah and the Flux Group.
# All rights reserved.
# 
# This file is part of the Flux OSKit.  The OSKit is free software, also known
# as "open source;" you can redistribute it and/or modify it under the terms
# of the GNU General Public License (GPL), version 2, as published by the Free
# Software Foundation (FSF).  To explore alternate licensing terms, contact
# the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
# 
# The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have
# received a copy of the GPL along with the OSKit; see the file COPYING.  If
# not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
#

#### Start of configuration section ####

OSKIT_SRCDIR	= @top_srcdir@
OBJDIR		= ..

prefix		= @prefix@
exec_prefix	= @exec_prefix@

include $(OBJDIR)/Makeconf

##### End of configuration section #####

TARGET	= liboskit_random.a

SRCDIRS += $(OSKIT_SRCDIR)/random

INCDIRS += $(OSKIT_SRCDIR)/oskit/c

include $(OSKIT_SRCDIR)/GNUmakerules-lib