diff options
-rw-r--r-- | deva/ChangeLog | 14 | ||||
-rw-r--r-- | deva/Makefile.am | 3 | ||||
-rw-r--r-- | deva/deva.c | 10 | ||||
-rw-r--r-- | deva/deva.h | 18 | ||||
-rw-r--r-- | deva/device-console.c (renamed from deva/deva-class.c) | 163 | ||||
-rw-r--r-- | deva/device.c | 146 | ||||
-rw-r--r-- | deva/device.h | 73 |
7 files changed, 295 insertions, 132 deletions
diff --git a/deva/ChangeLog b/deva/ChangeLog index 2018351..a5ea0cd 100644 --- a/deva/ChangeLog +++ b/deva/ChangeLog @@ -1,3 +1,17 @@ +2005-02-01 Marcus Brinkmann <marcus@gnu.org> + + * deva.h (deva_alloc): Renamed to device_alloc. + (deva_class_init): Renamed to device_class_init and add new device + type argument. + (enum device_type): New enum. + * deva.c (create_bootstrap_caps): Call device_alloc, not + deva_alloc, and pass device type argument. + (main): Call device_class_init, not deva_class_init. + * deva-class.c: Removed file. + * device.h, device.c, device-console.c: New files. + * Makefile.am (deva_SOURCES): Remove deva-class.c and add + device.h, device.c, device-console.c. + 2005-01-11 Neal H. Walfield <neal@gnu.org> * Makefile.am (deva_SOURCES): Remove physmem-user.h and diff --git a/deva/Makefile.am b/deva/Makefile.am index bffa984..9ab43c1 100644 --- a/deva/Makefile.am +++ b/deva/Makefile.am @@ -32,7 +32,8 @@ deva_SOURCES = $(ARCH_SOURCES) \ output.h output.c \ mmap.c malloc-wrap.c \ task-user.h task-user.c \ - deva.h deva.c deva-class.c + deva.h deva.c \ + device.h device.c device-console.c device-serial.c # Doug Lea's malloc is included by malloc-wrap.c. EXTRA_deva_SOURCES = malloc.c diff --git a/deva/deva.c b/deva/deva.c index 7597d59..47c44d2 100644 --- a/deva/deva.c +++ b/deva/deva.c @@ -77,9 +77,9 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket) l4_accept (L4_UNTYPED_WORDS_ACCEPTOR); /* FIXME: Allocate a system console driver. */ - err = deva_alloc (&obj); + err = device_alloc (&obj, DEVICE_CONSOLE); if (err) - panic ("deva_alloc: %i\n", err); + panic ("device_alloc: %i\n", err); hurd_cap_obj_unlock (obj); while (1) @@ -101,7 +101,7 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket) } else { - debug ("Creating deva cap for 0x%x:", task_id); + debug ("Creating console device cap for 0x%x:", task_id); err = hurd_cap_bucket_inject (bucket, obj, task_id, &cap); if (err) @@ -232,9 +232,9 @@ main (int argc, char *argv[]) server_thread = setup_threads (); - err = deva_class_init (); + err = device_class_init (); if (err) - panic ("deva_class_init: %i\n", err); + panic ("device_class_init: %i\n", err); err = hurd_cap_bucket_create (&bucket); if (err) diff --git a/deva/deva.h b/deva/deva.h index 6b52fb5..f2a47a5 100644 --- a/deva/deva.h +++ b/deva/deva.h @@ -42,11 +42,17 @@ int main (int argc, char *argv[]); void switch_thread (l4_thread_id_t from, l4_thread_id_t to); -/* Deva objects. */ +/* Device objects. */ -/* Initialize the task class subsystem. */ -error_t deva_class_init (); +/* Initialize the device class subsystem. */ +error_t device_class_init (); -/* Allocate a new deva object. The object returned is locked and has - one reference. */ -error_t deva_alloc (hurd_cap_obj_t *r_obj); +enum device_type + { + DEVICE_CONSOLE = 0, + DEVICE_SERIAL = 1 + }; + +/* Allocate a new device object. The object returned is locked and + has one reference. */ +error_t device_alloc (hurd_cap_obj_t *r_obj, enum device_type type); diff --git a/deva/deva-class.c b/deva/device-console.c index dd7acb3..6185b85 100644 --- a/deva/deva-class.c +++ b/deva/device-console.c @@ -1,5 +1,5 @@ -/* deva-class.c - Deva class for the deva server. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* device-console.c - A small console device, until we have the real thing. + Copyright (C) 2005 Free Software Foundation, Inc. Written by Marcus Brinkmann. This file is part of the GNU Hurd. @@ -23,32 +23,27 @@ #include <config.h> #endif -#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include <sys/io.h> #include <l4.h> -#include <hurd/cap-server.h> + #include <hurd/wortel.h> -#include "deva.h" +#include "output.h" + +#include "device.h" + /* Do not even think about improving the console! The code here is only for testing. Go do something useful. Work on the real device driver framework. */ -#define SIMPLE_CONSOLE 1 - -#ifdef SIMPLE_CONSOLE - -#include <sys/io.h> - -pthread_mutex_t console_lock = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t console_cond = PTHREAD_COND_INITIALIZER; -#define CONSOLE_MAX 256 -unsigned char console_input[CONSOLE_MAX]; -unsigned int console_input_len; static void * -console_irq_handler (void *unused) +console_irq_handler (void *_console) { + device_t *dev = (device_t *) _console; l4_word_t result; l4_thread_id_t irq; l4_msg_tag_t tag; @@ -87,12 +82,12 @@ console_irq_handler (void *unused) b = '\x00'; } - pthread_mutex_lock (&console_lock); + pthread_mutex_lock (&dev->console.lock); if (b == '\x1b') asm volatile ("int $3"); else if (b != '\x00') { - if (console_input_len == CONSOLE_MAX) + if (dev->console.input_len == CONSOLE_MAX) { putchar ('^'); putchar ('G'); @@ -100,12 +95,12 @@ console_irq_handler (void *unused) else { putchar (b); - if (!console_input_len) - pthread_cond_broadcast (&console_cond); - console_input[console_input_len++] = b; + if (!dev->console.input_len) + pthread_cond_broadcast (&dev->console.cond); + dev->console.input[dev->console.input_len++] = b; } } - pthread_mutex_unlock (&console_lock); + pthread_mutex_unlock (&dev->console.lock); l4_load_mr (0, 0); l4_reply_receive (irq); @@ -114,7 +109,7 @@ console_irq_handler (void *unused) static void -console_init (void) +console_init (device_t *dev) { error_t err; l4_thread_id_t irq_handler_tid; @@ -126,127 +121,55 @@ console_init (void) err = pthread_create_from_l4_tid_np (&irq_handler, NULL, irq_handler_tid, console_irq_handler, - NULL); + dev); if (err) panic ("Can not create the irq handler thread: %i", err); pthread_detach (irq_handler); } -#endif /* SIMPLE_CONSOLE */ - - -struct deva -{ - /* FIXME: More stuff. */ - int foo; -}; -typedef struct deva *deva_t; - - -static void -deva_reinit (hurd_cap_class_t cap_class, hurd_cap_obj_t obj) -{ - deva_t deva = hurd_cap_obj_to_user (deva_t, obj); - - /* FIXME: Release resources. */ -} - -error_t -deva_io_read (hurd_cap_rpc_context_t ctx) +static error_t +console_io_read (device_t *dev, int *chr) { -#ifdef SIMPLE_CONSOLE unsigned char b = '\x00'; - - pthread_mutex_lock (&console_lock); - while (!console_input_len) - pthread_cond_wait (&console_cond, &console_lock); - b = console_input[--console_input_len]; - pthread_mutex_unlock (&console_lock); - /* Prepare reply message. */ - l4_msg_clear (ctx->msg); - l4_msg_append_word (ctx->msg, (l4_word_t) b); + pthread_mutex_lock (&dev->console.lock); + while (!dev->console.input_len) + pthread_cond_wait (&dev->console.cond, &dev->console.lock); + b = dev->console.input[0]; + dev->console.input_len--; + memmove (&dev->console.input[0], &dev->console.input[1], + dev->console.input_len); + pthread_mutex_unlock (&dev->console.lock); + + *chr = b; -#endif return 0; } -error_t -deva_io_write (hurd_cap_rpc_context_t ctx) +static error_t +console_io_write (device_t *dev, int chr) { -#ifdef SIMPLE_CONSOLE - l4_word_t chr; - - chr = l4_msg_word (ctx->msg, 1); putchar ((unsigned char) chr); -#endif return 0; } - -error_t -deva_demuxer (hurd_cap_rpc_context_t ctx) -{ - error_t err = 0; - - switch (l4_msg_label (ctx->msg)) - { - /* DEVA_IO_READ */ - case 768: - err = deva_io_read (ctx); - break; - - /* DEVA_IO_WRITE */ - case 769: - err = deva_io_write (ctx); - break; - - default: - err = EOPNOTSUPP; - } - - return err; -} - - -static struct hurd_cap_class deva_class; - -/* Initialize the deva class subsystem. */ +/* Create a new console device in DEV. */ error_t -deva_class_init () +device_console_init (device_t *dev) { -#ifdef SIMPLE_CONSOLE - console_init (); -#endif - - return hurd_cap_class_init (&deva_class, deva_t, - NULL, NULL, deva_reinit, NULL, - deva_demuxer); -} - - -/* Allocate a new deva object. The object returned is locked and has - one reference. */ -error_t -deva_alloc (hurd_cap_obj_t *r_obj) -{ - error_t err; - hurd_cap_obj_t obj; - deva_t deva; - - err = hurd_cap_class_alloc (&deva_class, &obj); - if (err) - return err; - - deva = hurd_cap_obj_to_user (deva_t, obj); + dev->io_read = console_io_read; + dev->io_write = console_io_write; + dev->console.lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; + dev->console.cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER; + dev->console.input_len = 0; - /* FIXME: Add some stuff. */ + /* We know this is only called once, so what the hell. */ + console_init (dev); - *r_obj = obj; return 0; } diff --git a/deva/device.c b/deva/device.c new file mode 100644 index 0000000..5494c5c --- /dev/null +++ b/deva/device.c @@ -0,0 +1,146 @@ +/* deva-class.c - Deva class for the deva server. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Written by Marcus Brinkmann. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU Hurd 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 GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> + +#include <l4.h> +#include <hurd/cap-server.h> + +#include "deva.h" +#include "device.h" + + +static void +device_reinit (hurd_cap_class_t cap_class, hurd_cap_obj_t obj) +{ + device_t *dev = hurd_cap_obj_to_user (device_t *, obj); + + /* FIXME: Release resources. */ +} + + +static error_t +device_io_read (hurd_cap_rpc_context_t ctx) +{ + error_t err; + device_t *dev = hurd_cap_obj_to_user (device_t *, ctx->obj); + int chr; + + err = (*dev->io_read) (dev, &chr); + if (err) + return err; + + /* Prepare reply message. */ + l4_msg_clear (ctx->msg); + l4_msg_append_word (ctx->msg, (l4_word_t) chr); + + return 0; +} + + +static error_t +device_io_write (hurd_cap_rpc_context_t ctx) +{ + device_t *dev = hurd_cap_obj_to_user (device_t *, ctx->obj); + int chr; + + chr = (int) l4_msg_word (ctx->msg, 1); + + return (*dev->io_write) (dev, chr); +} + + +static error_t +device_demuxer (hurd_cap_rpc_context_t ctx) +{ + error_t err = 0; + + switch (l4_msg_label (ctx->msg)) + { + /* DEVICE_IO_READ */ + case 768: + err = device_io_read (ctx); + break; + + /* DEVICE_IO_WRITE */ + case 769: + err = device_io_write (ctx); + break; + + default: + err = EOPNOTSUPP; + } + + return err; +} + + + +static struct hurd_cap_class device_class; + +/* Initialize the device class subsystem. */ +error_t +device_class_init () +{ + return hurd_cap_class_init (&device_class, device_t *, + NULL, NULL, device_reinit, NULL, + device_demuxer); +} + + +/* Allocate a new device object. The object returned is locked and + has one reference. */ +error_t +device_alloc (hurd_cap_obj_t *r_obj, enum device_type type) +{ + error_t err; + hurd_cap_obj_t obj; + device_t *dev; + + err = hurd_cap_class_alloc (&device_class, &obj); + if (err) + return err; + + dev = hurd_cap_obj_to_user (device_t *, obj); + + switch (type) + { + case DEVICE_CONSOLE: + device_console_init (dev); + break; + + case DEVICE_SERIAL: +#if 0 + device_serial_init (dev); +#endif + break; + + default: + break; + } + + *r_obj = obj; + return 0; +} diff --git a/deva/device.h b/deva/device.h new file mode 100644 index 0000000..03491d8 --- /dev/null +++ b/deva/device.h @@ -0,0 +1,73 @@ +/* device.h - A small device interface, until we have the real thing. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Marcus Brinkmann. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU Hurd 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 GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef DEVICE_H +#define DEVICE_H 1 + +#include <errno.h> + + +typedef struct device device_t; + +struct device +{ + /* Read a single character from DEV and return it in CHR. */ + error_t (*io_read) (device_t *dev, int *chr); + + /* Write the single character CHR to DEV. */ + error_t (*io_write) (device_t *dev, int chr); + + /* Private data area. */ + union + { + /* The data used by the console driver. */ + struct console_data + { + pthread_mutex_t lock; + pthread_cond_t cond; +#define CONSOLE_MAX 256 + unsigned char input[CONSOLE_MAX]; + unsigned int input_len; + } console; + + /* The data used by the serial driver. */ + struct serial_data + { + pthread_mutex_t lock; + pthread_cond_t cond; +#define SERIAL_MAX 128 + unsigned char input[SERIAL_MAX]; + unsigned int input_len; + unsigned char output[SERIAL_MAX]; + unsigned int output_len; + } serial; + }; +}; +; + + +/* Create a new console device in DEV. */ +error_t device_console_init (device_t *dev); + +/* Create a new serial device in DEV. */ +error_t device_serial_init (device_t *dev); + +#endif /* DEVICE_H */ |