31 |
|
|
32 |
#include "deva.h" |
#include "deva.h" |
33 |
|
|
34 |
|
/* Do not even think about improving the console! The code here is |
35 |
|
only for testing. Go do something useful. Work on the real device |
36 |
|
driver framework. */ |
37 |
|
#define SIMPLE_CONSOLE 1 |
38 |
|
|
39 |
|
#ifdef SIMPLE_CONSOLE |
40 |
|
|
41 |
|
#include <sys/io.h> |
42 |
|
|
43 |
|
pthread_mutex_t console_lock = PTHREAD_MUTEX_INITIALIZER; |
44 |
|
pthread_cond_t console_cond = PTHREAD_COND_INITIALIZER; |
45 |
|
#define CONSOLE_MAX 256 |
46 |
|
unsigned char console_input[CONSOLE_MAX]; |
47 |
|
unsigned int console_input_len; |
48 |
|
|
49 |
|
static void * |
50 |
|
console_irq_handler (void *unused) |
51 |
|
{ |
52 |
|
l4_word_t result; |
53 |
|
l4_thread_id_t irq; |
54 |
|
l4_msg_tag_t tag; |
55 |
|
|
56 |
|
#define KEYBOARD_IRQ 1 |
57 |
|
#define KEYBOARD_INPUT 0x60 |
58 |
|
|
59 |
|
irq = l4_global_id (KEYBOARD_IRQ, 1); |
60 |
|
result = wortel_thread_control (irq, irq, l4_nilthread, l4_myself (), |
61 |
|
(void *) -1); |
62 |
|
if (result) |
63 |
|
panic ("setting irq pager failed: %i", result); |
64 |
|
|
65 |
|
#define l4_reply_receive(tid) \ |
66 |
|
({ l4_thread_id_t dummy; \ |
67 |
|
l4_ipc (tid, tid, l4_timeouts (L4_ZERO_TIME, L4_NEVER), &dummy); }) |
68 |
|
|
69 |
|
tag = l4_receive (irq); |
70 |
|
|
71 |
|
while (1) |
72 |
|
{ |
73 |
|
unsigned char b; |
74 |
|
|
75 |
|
b = inb (0x60); |
76 |
|
{ |
77 |
|
/* This is a conversion table from i8042 scancode set 1 to set 2. */ |
78 |
|
static char sc_map[] = "\x00" "\x1b" "1234567890-=" "\x7f" |
79 |
|
"\x09" "qwertyuiop[]" "\x0a" |
80 |
|
"\x00" /* left ctrl */ "asdfghjkl;'`" |
81 |
|
"\x00" /* left shift */ "\\zxcvbnm,./" "\x00" /* right shift */ |
82 |
|
"*" "\x00" /* left alt */ " "; |
83 |
|
|
84 |
|
if (b < sizeof (sc_map)) |
85 |
|
b = sc_map[b]; |
86 |
|
else |
87 |
|
b = '\x00'; |
88 |
|
} |
89 |
|
|
90 |
|
pthread_mutex_lock (&console_lock); |
91 |
|
if (b == '\x1b') |
92 |
|
asm volatile ("int $3"); |
93 |
|
else if (b != '\x00') |
94 |
|
{ |
95 |
|
if (console_input_len == CONSOLE_MAX) |
96 |
|
{ |
97 |
|
putchar ('^'); |
98 |
|
putchar ('G'); |
99 |
|
} |
100 |
|
else |
101 |
|
{ |
102 |
|
putchar (b); |
103 |
|
if (!console_input_len) |
104 |
|
pthread_cond_broadcast (&console_cond); |
105 |
|
console_input[console_input_len++] = b; |
106 |
|
} |
107 |
|
} |
108 |
|
pthread_mutex_unlock (&console_lock); |
109 |
|
|
110 |
|
l4_load_mr (0, 0); |
111 |
|
l4_reply_receive (irq); |
112 |
|
} |
113 |
|
} |
114 |
|
|
115 |
|
|
116 |
|
static void |
117 |
|
console_init (void) |
118 |
|
{ |
119 |
|
error_t err; |
120 |
|
l4_thread_id_t irq_handler_tid; |
121 |
|
pthread_t irq_handler; |
122 |
|
|
123 |
|
irq_handler_tid = pthread_pool_get_np (); |
124 |
|
if (irq_handler_tid == l4_nilthread) |
125 |
|
panic ("Can not create the irq handler thread"); |
126 |
|
|
127 |
|
err = pthread_create_from_l4_tid_np (&irq_handler, NULL, |
128 |
|
irq_handler_tid, console_irq_handler, |
129 |
|
NULL); |
130 |
|
if (err) |
131 |
|
panic ("Can not create the irq handler thread: %i", err); |
132 |
|
|
133 |
|
pthread_detach (irq_handler); |
134 |
|
} |
135 |
|
|
136 |
|
#endif /* SIMPLE_CONSOLE */ |
137 |
|
|
138 |
|
|
139 |
struct deva |
struct deva |
140 |
{ |
{ |
154 |
|
|
155 |
|
|
156 |
error_t |
error_t |
157 |
|
deva_io_read (hurd_cap_rpc_context_t ctx) |
158 |
|
{ |
159 |
|
#ifdef SIMPLE_CONSOLE |
160 |
|
unsigned char b = '\x00'; |
161 |
|
|
162 |
|
pthread_mutex_lock (&console_lock); |
163 |
|
while (!console_input_len) |
164 |
|
pthread_cond_wait (&console_cond, &console_lock); |
165 |
|
b = console_input[--console_input_len]; |
166 |
|
pthread_mutex_unlock (&console_lock); |
167 |
|
|
168 |
|
/* Prepare reply message. */ |
169 |
|
l4_msg_clear (ctx->msg); |
170 |
|
l4_msg_append_word (ctx->msg, (l4_word_t) b); |
171 |
|
|
172 |
|
#endif |
173 |
|
return 0; |
174 |
|
} |
175 |
|
|
176 |
|
|
177 |
|
error_t |
178 |
deva_io_write (hurd_cap_rpc_context_t ctx) |
deva_io_write (hurd_cap_rpc_context_t ctx) |
179 |
{ |
{ |
180 |
|
#ifdef SIMPLE_CONSOLE |
181 |
|
l4_word_t chr; |
182 |
|
|
183 |
|
chr = l4_msg_word (ctx->msg, 1); |
184 |
|
putchar ((unsigned char) chr); |
185 |
|
#endif |
186 |
|
|
187 |
return 0; |
return 0; |
188 |
} |
} |
189 |
|
|
195 |
|
|
196 |
switch (l4_msg_label (ctx->msg)) |
switch (l4_msg_label (ctx->msg)) |
197 |
{ |
{ |
198 |
|
/* DEVA_IO_READ */ |
199 |
|
case 768: |
200 |
|
err = deva_io_read (ctx); |
201 |
|
break; |
202 |
|
|
203 |
/* DEVA_IO_WRITE */ |
/* DEVA_IO_WRITE */ |
204 |
case 256: |
case 769: |
205 |
err = deva_io_write (ctx); |
err = deva_io_write (ctx); |
206 |
break; |
break; |
207 |
|
|
220 |
error_t |
error_t |
221 |
deva_class_init () |
deva_class_init () |
222 |
{ |
{ |
223 |
|
#ifdef SIMPLE_CONSOLE |
224 |
|
console_init (); |
225 |
|
#endif |
226 |
|
|
227 |
return hurd_cap_class_init (&deva_class, deva_t, |
return hurd_cap_class_init (&deva_class, deva_t, |
228 |
NULL, NULL, deva_reinit, NULL, |
NULL, NULL, deva_reinit, NULL, |
229 |
deva_demuxer); |
deva_demuxer); |