diff options
author | marcus <marcus> | 2004-11-02 03:56:32 +0000 |
---|---|---|
committer | marcus <marcus> | 2004-11-02 03:56:32 +0000 |
commit | 84e98be73efcf23492488cc5209c5b0685f5ccbd (patch) | |
tree | b0e54aa5dc22aa9beddc5a3e893e2605c64db16e | |
parent | c8a3cad6258f94dd15f94a93b745696473a62c70 (diff) |
deva/
2004-11-02 Marcus Brinkmann <marcus@gnu.org>
* deva-class.c (SIMPLE_CONSOLE): Define.
[SIMPLE_CONSOLE]: A lot of new code that is only used for testing.
(deva_io_read): New function.
(deva_demuxer): Add handling for deva_io_read.
* deva.c (create_bootstrap_caps): Allocate only one object, and
copy it out several times. Call wortel_get_deva_cap_reply, not
wortel_get_task_cap_reply.
wortel/
2004-11-02 Marcus Brinkmann <marcus@gnu.org>
* wortel.c (deva_master): New global variable.
(serve_bootstrap_requests): New variable CUR_DEVA. Handle
WORTEL_MSG_GET_DEVA_CAP_REQUEST and WORTEL_MSG_GET_DEVA_CAP_REPLY.
When replying to deva's bootstrap request, give it all the info we
have.
-rw-r--r-- | deva/ChangeLog | 8 | ||||
-rw-r--r-- | deva/deva-class.c | 143 | ||||
-rw-r--r-- | deva/deva.c | 22 | ||||
-rw-r--r-- | wortel/ChangeLog | 6 | ||||
-rw-r--r-- | wortel/wortel.c | 62 |
5 files changed, 227 insertions, 14 deletions
diff --git a/deva/ChangeLog b/deva/ChangeLog index 05e8918..4e5250a 100644 --- a/deva/ChangeLog +++ b/deva/ChangeLog @@ -1,5 +1,13 @@ 2004-11-02 Marcus Brinkmann <marcus@gnu.org> + * deva-class.c (SIMPLE_CONSOLE): Define. + [SIMPLE_CONSOLE]: A lot of new code that is only used for testing. + (deva_io_read): New function. + (deva_demuxer): Add handling for deva_io_read. + * deva.c (create_bootstrap_caps): Allocate only one object, and + copy it out several times. Call wortel_get_deva_cap_reply, not + wortel_get_task_cap_reply. + * Makefile.am (deva_SOURCES): Add task-user.h and task-user.c. * task-user.h, task-user.c: New files. * deva.c: Include "task-user.h". diff --git a/deva/deva-class.c b/deva/deva-class.c index 44fde26..dd7acb3 100644 --- a/deva/deva-class.c +++ b/deva/deva-class.c @@ -31,6 +31,110 @@ #include "deva.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) +{ + l4_word_t result; + l4_thread_id_t irq; + l4_msg_tag_t tag; + +#define KEYBOARD_IRQ 1 +#define KEYBOARD_INPUT 0x60 + + irq = l4_global_id (KEYBOARD_IRQ, 1); + result = wortel_thread_control (irq, irq, l4_nilthread, l4_myself (), + (void *) -1); + if (result) + panic ("setting irq pager failed: %i", result); + +#define l4_reply_receive(tid) \ + ({ l4_thread_id_t dummy; \ + l4_ipc (tid, tid, l4_timeouts (L4_ZERO_TIME, L4_NEVER), &dummy); }) + + tag = l4_receive (irq); + + while (1) + { + unsigned char b; + + b = inb (0x60); + { + /* This is a conversion table from i8042 scancode set 1 to set 2. */ + static char sc_map[] = "\x00" "\x1b" "1234567890-=" "\x7f" + "\x09" "qwertyuiop[]" "\x0a" + "\x00" /* left ctrl */ "asdfghjkl;'`" + "\x00" /* left shift */ "\\zxcvbnm,./" "\x00" /* right shift */ + "*" "\x00" /* left alt */ " "; + + if (b < sizeof (sc_map)) + b = sc_map[b]; + else + b = '\x00'; + } + + pthread_mutex_lock (&console_lock); + if (b == '\x1b') + asm volatile ("int $3"); + else if (b != '\x00') + { + if (console_input_len == CONSOLE_MAX) + { + putchar ('^'); + putchar ('G'); + } + else + { + putchar (b); + if (!console_input_len) + pthread_cond_broadcast (&console_cond); + console_input[console_input_len++] = b; + } + } + pthread_mutex_unlock (&console_lock); + + l4_load_mr (0, 0); + l4_reply_receive (irq); + } +} + + +static void +console_init (void) +{ + error_t err; + l4_thread_id_t irq_handler_tid; + pthread_t irq_handler; + + irq_handler_tid = pthread_pool_get_np (); + if (irq_handler_tid == l4_nilthread) + panic ("Can not create the irq handler thread"); + + err = pthread_create_from_l4_tid_np (&irq_handler, NULL, + irq_handler_tid, console_irq_handler, + NULL); + if (err) + panic ("Can not create the irq handler thread: %i", err); + + pthread_detach (irq_handler); +} + +#endif /* SIMPLE_CONSOLE */ + struct deva { @@ -50,8 +154,36 @@ deva_reinit (hurd_cap_class_t cap_class, hurd_cap_obj_t obj) error_t +deva_io_read (hurd_cap_rpc_context_t ctx) +{ +#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); + +#endif + return 0; +} + + +error_t deva_io_write (hurd_cap_rpc_context_t ctx) { +#ifdef SIMPLE_CONSOLE + l4_word_t chr; + + chr = l4_msg_word (ctx->msg, 1); + putchar ((unsigned char) chr); +#endif + return 0; } @@ -63,8 +195,13 @@ deva_demuxer (hurd_cap_rpc_context_t ctx) switch (l4_msg_label (ctx->msg)) { + /* DEVA_IO_READ */ + case 768: + err = deva_io_read (ctx); + break; + /* DEVA_IO_WRITE */ - case 256: + case 769: err = deva_io_write (ctx); break; @@ -83,6 +220,10 @@ static struct hurd_cap_class deva_class; error_t deva_class_init () { +#ifdef SIMPLE_CONSOLE + console_init (); +#endif + return hurd_cap_class_init (&deva_class, deva_t, NULL, NULL, deva_reinit, NULL, deva_demuxer); diff --git a/deva/deva.c b/deva/deva.c index 0d5465e..5089d70 100644 --- a/deva/deva.c +++ b/deva/deva.c @@ -76,6 +76,12 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket) l4_accept (L4_UNTYPED_WORDS_ACCEPTOR); + /* FIXME: Allocate a system console driver. */ + err = deva_alloc (&obj); + if (err) + panic ("deva_alloc: %i\n", err); + hurd_cap_obj_unlock (obj); + while (1) { hurd_task_id_t task_id; @@ -88,7 +94,7 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket) /* FIXME: Create capability. */ /* FIXME: Use our control cap for this task here. */ - wortel_get_task_cap_reply (0xf00); + wortel_get_deva_cap_reply (0xf00); /* This is the last request made. */ return; @@ -97,26 +103,20 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket) { debug ("Creating deva cap for 0x%x:", task_id); - /* FIXME: Allocate a system console driver. */ - err = deva_alloc (&obj); - - if (err) - panic ("deva_alloc: %i\n", err); - hurd_cap_obj_unlock (obj); - err = hurd_cap_bucket_inject (bucket, obj, task_id, &cap); if (err) panic ("hurd_cap_bucket_inject: %i\n", err); - hurd_cap_obj_lock (obj); - hurd_cap_obj_drop (obj); - debug (" 0x%x\n", cap); /* Return CAP. */ wortel_get_deva_cap_reply (cap); } } + + hurd_cap_obj_lock (obj); + hurd_cap_obj_drop (obj); + } diff --git a/wortel/ChangeLog b/wortel/ChangeLog index 70a91ac..0cdb691 100644 --- a/wortel/ChangeLog +++ b/wortel/ChangeLog @@ -1,5 +1,11 @@ 2004-11-02 Marcus Brinkmann <marcus@gnu.org> + * wortel.c (deva_master): New global variable. + (serve_bootstrap_requests): New variable CUR_DEVA. Handle + WORTEL_MSG_GET_DEVA_CAP_REQUEST and WORTEL_MSG_GET_DEVA_CAP_REPLY. + When replying to deva's bootstrap request, give it all the info we + have. + * wortel.c (start_elf): Initialize PHYS_STARTUP->task. 2004-11-01 Marcus Brinkmann <marcus@gnu.org> diff --git a/wortel/wortel.c b/wortel/wortel.c index eba3756..da3f374 100644 --- a/wortel/wortel.c +++ b/wortel/wortel.c @@ -70,10 +70,11 @@ struct wortel_module mods[MOD_NUMBER]; MOD_NUMBER. */ unsigned int mods_count; -/* The physical memory and task server master control capabilities for - the root filesystem. */ +/* The physical memory, task and deva server master control + capabilities for the root filesystem. */ hurd_cap_handle_t physmem_master; hurd_cap_handle_t task_master; +hurd_cap_handle_t deva_master; /* The wortel task capability object handle. */ hurd_cap_handle_t task_wortel; @@ -881,6 +882,9 @@ serve_bootstrap_requests (void) /* This is to keep information about created task caps. */ unsigned int cur_task = (unsigned int) -1; + /* This is to keep information about created deva caps. */ + unsigned int cur_deva = 0; + /* Make a list of all the containers we want. */ for (i = 0; i < mods_count; i++) { @@ -1138,6 +1142,10 @@ serve_bootstrap_requests (void) l4_reply (bootstrap_final_task); /* Send the reply to deva's bootstrap final RPC. */ + l4_msg_append_word (msg, l4_nilthread); + l4_msg_append_word (msg, 0); + l4_msg_append_word (msg, mods[MOD_DEVA].server_thread); + l4_msg_append_word (msg, mods[MOD_DEVA].deva); l4_msg_clear (msg); /* It already has its caps. */ l4_msg_load (msg); @@ -1250,6 +1258,56 @@ serve_bootstrap_requests (void) l4_msg_load (msg); l4_reply (from); } + else if (label == WORTEL_MSG_GET_DEVA_CAP_REQUEST) + { + if (cur_deva > mods_count) + panic ("deva does not stop requesting capability requests"); + else if (cur_deva == mods_count) + { + /* Request the global control capability now. */ + l4_msg_clear (msg); + l4_msg_append_word + (msg, l4_version (mods[MOD_ROOT_FS].server_thread)); + /* Is master? */ + l4_msg_append_word (msg, 1); + l4_msg_load (msg); + l4_reply (from); + } + else + { + /* We are allowed to make a capability request now. */ + + /* We know that cur_deva == 0 is one of the good + cases. */ + l4_msg_clear (msg); + l4_set_msg_label (msg, 0); + l4_msg_append_word (msg, mods[cur_deva].task_id); + /* Is master? */ + l4_msg_append_word (msg, 0); + l4_msg_load (msg); + l4_reply (from); + } + } + else if (label == WORTEL_MSG_GET_DEVA_CAP_REPLY) + { + if (l4_untyped_words (tag) != 1 || l4_typed_words (tag) != 0) + panic ("Invalid format of get deva cap reply msg"); + + if (cur_deva > mods_count) + panic ("Invalid get deva cap reply message"); + else if (cur_deva == mods_count) + deva_master = l4_msg_word (msg, 0); + else + mods[cur_deva].deva = l4_msg_word (msg, 0); + + do + cur_deva++; + while (cur_deva < mods_count && !MOD_IS_TASK (cur_deva)); + + l4_msg_clear (msg); + l4_msg_load (msg); + l4_reply (from); + } else panic ("Invalid message with tag 0x%x", tag); } |