summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarcus <marcus>2004-11-02 03:56:32 +0000
committermarcus <marcus>2004-11-02 03:56:32 +0000
commit84e98be73efcf23492488cc5209c5b0685f5ccbd (patch)
treeb0e54aa5dc22aa9beddc5a3e893e2605c64db16e
parentc8a3cad6258f94dd15f94a93b745696473a62c70 (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/ChangeLog8
-rw-r--r--deva/deva-class.c143
-rw-r--r--deva/deva.c22
-rw-r--r--wortel/ChangeLog6
-rw-r--r--wortel/wortel.c62
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);
}