source/gui.ccp |
| 1 | #pypp 0 |
| 2 | #include <iris.hh> |
| 3 | #include <devices.hh> |
| 4 | #include <keys.hh> |
| 5 | |
| 6 | // Interface: two way, started by ui. |
| 7 | |
| 8 | // From ui to application. |
| 9 | // ~0: request reset. |
| 10 | // ~1: set reply cap; send current state. |
| 11 | // inum: event (with optional value) for input number num. |
| 12 | |
| 13 | // From application to ui. |
| 14 | // onum: event (with optional value) for output number num. |
| 15 | |
| 16 | // For now, the code is hardwired to the alarm clock interface. |
| 17 | enum outs: |
| 18 | CURRENT_TIME |
| 19 | ALARM |
| 20 | |
| 21 | enum ins: |
| 22 | TOTAL_TIME |
| 23 | START |
| 24 | |
| 25 | static Iris::Display display |
| 26 | static Iris::Buzzer buzzer |
| 27 | static unsigned *framebuffer |
| 28 | |
| 29 | enum PD: |
| 30 | UI |
| 31 | KBD |
| 32 | |
| 33 | static char const *chardef = |
| 34 | ".###.." |
| 35 | "#...#." |
| 36 | "#...#." |
| 37 | "#...#." |
| 38 | "#...#." |
| 39 | "#...#." |
| 40 | ".###.." |
| 41 | "......" |
| 42 | |
| 43 | "..#..." |
| 44 | "..#..." |
| 45 | "..#..." |
| 46 | "..#..." |
| 47 | "..#..." |
| 48 | "..#..." |
| 49 | "..#..." |
| 50 | "......" |
| 51 | |
| 52 | ".###.." |
| 53 | "#...#." |
| 54 | "....#." |
| 55 | "...#.." |
| 56 | "..#..." |
| 57 | ".#...." |
| 58 | "#####." |
| 59 | "......" |
| 60 | |
| 61 | ".###.." |
| 62 | "#...#." |
| 63 | "....#." |
| 64 | "..##.." |
| 65 | "....#." |
| 66 | "#...#." |
| 67 | ".###.." |
| 68 | "......" |
| 69 | |
| 70 | "#...#." |
| 71 | "#...#." |
| 72 | "#...#." |
| 73 | "#####." |
| 74 | "....#." |
| 75 | "....#." |
| 76 | "....#." |
| 77 | "......" |
| 78 | |
| 79 | "#####." |
| 80 | "#....." |
| 81 | "####.." |
| 82 | "....#." |
| 83 | "....#." |
| 84 | "....#." |
| 85 | "####.." |
| 86 | "......" |
| 87 | |
| 88 | "....#." |
| 89 | "...#.." |
| 90 | "..#..." |
| 91 | ".###.." |
| 92 | "#...#." |
| 93 | "#...#." |
| 94 | ".###.." |
| 95 | "......" |
| 96 | |
| 97 | "#####." |
| 98 | "....#." |
| 99 | "...#.." |
| 100 | "..#..." |
| 101 | ".#...." |
| 102 | "#....." |
| 103 | "#....." |
| 104 | "......" |
| 105 | |
| 106 | ".###.." |
| 107 | "#...#." |
| 108 | "#...#." |
| 109 | ".###.." |
| 110 | "#...#." |
| 111 | "#...#." |
| 112 | ".###.." |
| 113 | "......" |
| 114 | |
| 115 | ".###.." |
| 116 | "#...#." |
| 117 | "#...#." |
| 118 | ".###.." |
| 119 | "..#..." |
| 120 | ".#...." |
| 121 | "#....." |
| 122 | "......" |
| 123 | |
| 124 | "......" |
| 125 | "......" |
| 126 | "..#..." |
| 127 | "......" |
| 128 | "......" |
| 129 | "..#..." |
| 130 | "......" |
| 131 | "......" |
| 132 | |
| 133 | static void draw_pixel (unsigned x, unsigned y, bool set): |
| 134 | for unsigned ty = 0; ty < 8; ++ty: |
| 135 | for unsigned tx = 0; tx < 8; ++tx: |
| 136 | framebuffer[320 * (y + ty) + x + tx] = (set ? 0xffffff : 0x000000) |
| 137 | |
| 138 | static void draw_num (bool upper, unsigned x0, unsigned d): |
| 139 | for unsigned y = 0; y < 8; ++y: |
| 140 | for unsigned x = 0; x < 6; ++x: |
| 141 | draw_pixel (x * 10 + 10 + x0 * 60, y * 10 + (upper ? 30 : 50 + 80), chardef[(d * 8 + y) * 6 + x] == '#') |
| 142 | |
| 143 | static void draw_time (bool upper, unsigned time): |
| 144 | unsigned min = time / 60 |
| 145 | time %= 60 |
| 146 | if min >= 100: |
| 147 | min = 99 |
| 148 | time = 99 |
| 149 | draw_num (upper, 0, min / 10) |
| 150 | draw_num (upper, 1, min % 10) |
| 151 | draw_num (upper, 3, time / 10) |
| 152 | draw_num (upper, 4, time % 10) |
| 153 | |
| 154 | static void beep (): |
| 155 | buzzer.beep (4 * 440, 1000, ~0) |
| 156 | |
| 157 | Iris::Num start (): |
| 158 | Iris::my_parent.init_done () |
| 159 | display = Iris::my_parent.get_capability <Iris::Display> () |
| 160 | Iris::Setting bright = Iris::my_parent.get_capability <Iris::Setting> () |
| 161 | Iris::Keyboard keyboard = Iris::my_parent.get_capability <Iris::Keyboard> () |
| 162 | buzzer = Iris::my_parent.get_capability <Iris::Buzzer> () |
| 163 | Iris::UI app = Iris::my_parent.get_capability <Iris::UI> () |
| 164 | Iris::Cap cb = Iris::my_receiver.create_capability (UI) |
| 165 | framebuffer = (unsigned *)0x15000 |
| 166 | Iris::Caps fb = display.map_fb ((unsigned)framebuffer) |
| 167 | bright.set (bright.get_range ()) |
| 168 | app.get_state (cb.copy ()) |
| 169 | Iris::free_cap (cb) |
| 170 | cb = Iris::my_receiver.create_capability (KBD) |
| 171 | keyboard.set_cb (cb.copy ()) |
| 172 | Iris::free_cap (cb) |
| 173 | draw_num (false, 2, 10) |
| 174 | draw_num (true, 2, 10) |
| 175 | unsigned total_time = 0 |
| 176 | while true: |
| 177 | Iris::wait () |
| 178 | switch Iris::recv.protected_data.l: |
| 179 | case UI: |
| 180 | switch Iris::recv.data[0].l: |
| 181 | case CURRENT_TIME: |
| 182 | draw_time (false, Iris::recv.data[1].l) |
| 183 | break |
| 184 | case ALARM: |
| 185 | beep () |
| 186 | break |
| 187 | case TOTAL_TIME | Iris::UI::INPUT: |
| 188 | total_time = Iris::recv.data[1].l |
| 189 | draw_time (true, total_time) |
| 190 | break |
| 191 | case START | Iris::UI::INPUT: |
| 192 | break |
| 193 | break |
| 194 | case KBD: |
| 195 | if Iris::recv.data[0].l & Iris::Keyboard::RELEASE: |
| 196 | break |
| 197 | switch Iris::recv.data[0].l: |
| 198 | case Key::VOLUME_UP: |
| 199 | total_time += 60 |
| 200 | draw_time (true, total_time) |
| 201 | app.event (TOTAL_TIME, total_time) |
| 202 | break |
| 203 | case Key::VOLUME_DOWN: |
| 204 | if total_time < 60: |
| 205 | total_time = 0 |
| 206 | else: |
| 207 | total_time -= 60 |
| 208 | draw_time (true, total_time) |
| 209 | app.event (TOTAL_TIME, total_time) |
| 210 | break |
| 211 | case Key::UP: |
| 212 | total_time += 10 |
| 213 | draw_time (true, total_time) |
| 214 | app.event (TOTAL_TIME, total_time) |
| 215 | break |
| 216 | case Key::DOWN: |
| 217 | if total_time < 10: |
| 218 | total_time = 0 |
| 219 | else: |
| 220 | total_time -= 10 |
| 221 | draw_time (true, total_time) |
| 222 | app.event (TOTAL_TIME, total_time) |
| 223 | break |
| 224 | case Key::LEFT: |
| 225 | if total_time < 1: |
| 226 | total_time = 0 |
| 227 | else: |
| 228 | total_time -= 1 |
| 229 | draw_time (true, total_time) |
| 230 | app.event (TOTAL_TIME, total_time) |
| 231 | break |
| 232 | case Key::RIGHT: |
| 233 | total_time += 1 |
| 234 | draw_time (true, total_time) |
| 235 | app.event (TOTAL_TIME, total_time) |
| 236 | break |
| 237 | case Key::ENTER: |
| 238 | app.event (START) |
source/init.ccp |
23 | 23 | #define NUM_SLOTS 8 |
24 | 24 | #define NUM_CAPS 32 |
25 | 25 | |
| 26 | #define SYSREQ 0x100 |
| 27 | |
26 | 28 | static unsigned _free |
27 | 29 | extern unsigned _end |
28 | 30 | |
... | ... | |
99 | 101 | |
100 | 102 | struct Program |
101 | 103 | |
102 | | struct Device: |
| 104 | struct Serverdevice: |
103 | 105 | char *name |
104 | 106 | unsigned name_len |
105 | 107 | unsigned type, index |
... | ... | |
107 | 109 | Program *server |
108 | 110 | Program *client |
109 | 111 | |
| 112 | struct Clientdevice: |
| 113 | unsigned type, index |
| 114 | Serverdevice *dev |
| 115 | |
| 116 | static Iris::Memory top_memory |
| 117 | static Iris::Directory root |
| 118 | static Iris::Elfrun elfrun |
| 119 | |
110 | 120 | struct Program: |
111 | 121 | char *name |
112 | 122 | unsigned name_len |
... | ... | |
114 | 124 | Iris::Caps pages |
115 | 125 | Iris::Memory memory |
116 | 126 | Iris::Thread thread |
117 | | List <Device> devices |
118 | | Iris::Cap waiter |
| 127 | List <Serverdevice> server_devices |
| 128 | List <Clientdevice> client_devices |
| 129 | unsigned num_waiting |
| 130 | bool priv |
| 131 | void run (): |
| 132 | Iris::Cap cap = Iris::my_receiver.create_capability ((unsigned)this) |
| 133 | if priv: |
| 134 | kdebug ("priv ") |
| 135 | kdebug ("running ") |
| 136 | for unsigned i = 0; i < name_len; ++i: |
| 137 | kdebug_char (name[i]) |
| 138 | kdebug ("\n") |
| 139 | Iris::Caps caps = elfrun.run_caps (top_memory, pages, cap.copy (), (size + PAGE_SIZE - 1) >> PAGE_BITS) |
| 140 | Iris::free_cap (cap) |
| 141 | thread = caps.get (__thread_num) |
| 142 | memory = caps.get (__memory_num) |
| 143 | if priv: |
| 144 | thread.make_priv () |
| 145 | thread.run () |
119 | 146 | |
120 | | static Iris::Memory top_memory |
121 | | static Iris::Directory root |
122 | | static Iris::Elfrun elfrun |
123 | 147 | static List <Program> programs |
124 | | static Iris::Cap sysreq |
125 | | static unsigned to_receive, progs |
| 148 | static Serverdevice *sysreq |
126 | 149 | |
127 | 150 | static bool name_match (char const *name, unsigned name_len, Iris::String n): |
128 | 151 | char nm[16] |
... | ... | |
255 | 278 | { "WDirectory", 10, Iris::WDirectory::ID }, |
256 | 279 | { "Filesystem", 10, Iris::Filesystem::ID }, |
257 | 280 | { "Stream", 6, Iris::Stream::ID }, |
| 281 | { "UI", 2, Iris::UI::ID }, |
258 | 282 | { NULL, 0, 0 } |
259 | 283 | } |
260 | 284 | |
... | ... | |
275 | 299 | return |
276 | 300 | Iris::panic (0, "no valid type found") |
277 | 301 | |
278 | | static void do_run (char *&start, unsigned &maxlen, bool priv): |
| 302 | static bool find_cap (char *&line, unsigned &len, Program *&server, Serverdevice *&dev): |
279 | 303 | char *n |
280 | 304 | unsigned l |
281 | | if !get_name (start, maxlen, n, l): |
282 | | Iris::panic (0, "syntax error in init.config (driver)") |
| 305 | if !get_name (line, len, n, l): |
| 306 | Iris::panic (0, "no capability name found in init.config") |
283 | 307 | List <Program>::Item *p |
284 | 308 | for p = programs.begin (); p; p = p->next: |
285 | | if string_match ((*p)->name, (*p)->name_len, n, l): |
286 | | break |
287 | | if !p: |
288 | | Iris::panic (0, "program not found for driver") |
289 | | Iris::Cap cap = Iris::my_receiver.create_capability ((unsigned)&**p) |
290 | | if priv: |
291 | | kdebug ("priv ") |
292 | | kdebug ("running ") |
293 | | for unsigned i = 0; i < (*p)->name_len; ++i: |
294 | | kdebug_char ((*p)->name[i]) |
295 | | kdebug ("\n") |
296 | | Iris::Caps caps = elfrun.run_caps (top_memory, (*p)->pages, cap.copy (), ((*p)->size + PAGE_SIZE - 1) >> PAGE_BITS) |
297 | | Iris::free_cap (cap) |
298 | | (*p)->thread = caps.get (__thread_num) |
299 | | (*p)->memory = caps.get (__memory_num) |
300 | | if priv: |
301 | | (*p)->thread.make_priv () |
302 | | (*p)->thread.run () |
303 | | // TODO: pass arguments. |
304 | | start += maxlen |
305 | | maxlen = 0 |
| 309 | List <Serverdevice>::Item *d |
| 310 | for d = (*p)->server_devices.begin (); d; d = d->next: |
| 311 | if string_match (n, l, (*d)->name, (*d)->name_len): |
| 312 | server = &**p |
| 313 | dev = &**d |
| 314 | return true |
| 315 | return false |
306 | 316 | |
307 | 317 | static void parse_line (char *&line, unsigned maxlen) |
308 | | static void include_caps (Iris::Caps caps, unsigned size): |
| 318 | static void include (char const *name, unsigned name_len): |
| 319 | unsigned size |
| 320 | Iris::Caps caps = load (name, name_len, size) |
309 | 321 | unsigned pages = (size + PAGE_SIZE - 1) >> PAGE_BITS |
310 | 322 | char *config = alloc_space (pages) |
311 | 323 | unsigned pages_slot = caps.use () |
... | ... | |
321 | 333 | Iris::free_cap (caps) |
322 | 334 | Iris::free_slot (pages_slot) |
323 | 335 | |
| 336 | static char *get_filename (char *&line, unsigned &maxlen, unsigned &len): |
| 337 | char q = *line++ |
| 338 | --maxlen |
| 339 | len = 0 |
| 340 | while maxlen && *line != q: |
| 341 | ++line |
| 342 | --maxlen |
| 343 | ++len |
| 344 | if !maxlen: |
| 345 | Iris::panic (0, "no closing quote in init.config") |
| 346 | return line - len |
| 347 | |
| 348 | static void do_load (char *&line, unsigned &maxlen, bool priv): |
| 349 | Program *p = &**programs.insert () |
| 350 | if !get_name (line, maxlen, p->name, p->name_len) || !match (line, maxlen, "=") || !maxlen: |
| 351 | Iris::panic (0, "syntax error in init.config (load)") |
| 352 | unsigned l |
| 353 | char *n = get_filename (line, maxlen, l) |
| 354 | p->pages = load (n, l, p->size) |
| 355 | p->priv = priv |
| 356 | p->num_waiting = 0 |
| 357 | ++line |
| 358 | --maxlen |
| 359 | |
324 | 360 | static void parse_line (char *&line, unsigned maxlen): |
325 | 361 | char *start = line |
326 | 362 | while maxlen && *line != '\n': |
... | ... | |
333 | 369 | delspace (start, maxlen) |
334 | 370 | if !maxlen: |
335 | 371 | return |
336 | | if match (start, maxlen, "load"): |
337 | | Program *p = &**programs.insert () |
338 | | if !get_name (start, maxlen, p->name, p->name_len) || !match (start, maxlen, "=") || !maxlen: |
339 | | Iris::panic (0, "syntax error in init.config (load)") |
340 | | char q = *start++ |
341 | | --maxlen |
342 | | unsigned len = 0 |
343 | | while maxlen && *start != q: |
344 | | ++start |
345 | | --maxlen |
346 | | ++len |
347 | | if !maxlen: |
348 | | Iris::panic (0, "no closing quote in init.config") |
349 | | p->pages = load (start - len, len, p->size) |
350 | | p->waiter = Iris::Cap () |
351 | | ++start |
352 | | --maxlen |
353 | | else if match (start, maxlen, "killbootthreads"): |
354 | | Iris::my_parent.init_done () |
| 372 | if match (start, maxlen, "program"): |
| 373 | do_load (start, maxlen, false) |
| 374 | else if match (start, maxlen, "driver"): |
| 375 | do_load (start, maxlen, true) |
355 | 376 | else if match (start, maxlen, "receive"): |
356 | 377 | // receive <name> / <type> [, <index>] = <cap> |
357 | 378 | char *n |
... | ... | |
364 | 385 | break |
365 | 386 | if !p: |
366 | 387 | Iris::panic (0, "program not found for receive") |
367 | | if !(*p)->devices.begin (): |
368 | | ++progs |
369 | | List <Device>::Item *dev = (*p)->devices.insert () |
| 388 | List <Serverdevice>::Item *dev = (*p)->server_devices.insert () |
370 | 389 | find_type (start, maxlen, (*dev)->type, (*dev)->index) |
371 | 390 | if !match (start, maxlen, "=") || !get_name (start, maxlen, (*dev)->name, (*dev)->name_len): |
372 | 391 | Iris::panic (1, "syntax error in init.config (receive)") |
373 | 392 | (*dev)->server = &**p |
374 | | ++to_receive |
375 | | else if match (start, maxlen, "driver"): |
376 | | do_run (start, maxlen, true) |
377 | | else if match (start, maxlen, "run"): |
378 | | do_run (start, maxlen, false) |
379 | | else if match (start, maxlen, "wait"): |
380 | | kdebug ("waiting for device registration\n") |
381 | | while progs: |
382 | | Iris::wait () |
383 | | Program *caller = (Program *)Iris::recv.protected_data.l |
384 | | if !caller: |
385 | | Iris::panic (0, "bug in init: no caller") |
386 | | switch Iris::recv.data[0].l: |
387 | | case Iris::Parent::PROVIDE_DEVICE: |
388 | | if Iris::recv.data[1].h != 0: |
389 | | kdebug ("init: too high device provided\n") |
390 | | continue |
391 | | unsigned type = Iris::recv.data[1].l |
392 | | unsigned index = Iris::recv.data[0].h |
393 | | List <Device>::Item *d |
394 | | for d = caller->devices.begin (); d; d = d->next: |
395 | | if (*d)->type == type && (*d)->index == index: |
396 | | break |
397 | | if !d: |
398 | | Iris::panic (0, "unregistered device provided") |
399 | | (*d)->cap = Iris::get_arg () |
400 | | Iris::recv.reply.invoke () |
401 | | --to_receive |
402 | | break |
403 | | case Iris::Parent::INIT_DONE: |
404 | | if caller->waiter.code != Iris::Cap ().code: |
405 | | Iris::panic (0, "caller was already waiting") |
406 | | caller->waiter = Iris::get_reply () |
407 | | --progs |
408 | | break |
409 | | default: |
410 | | Iris::panic (0, "unexpected request to init") |
411 | | if to_receive: |
412 | | Iris::panic (to_receive, "not all expected devices were registered") |
413 | | for List <Program>::Item *p = programs.begin (); p; p = p->next: |
414 | | if (*p)->waiter.code != Iris::Cap ().code: |
415 | | (*p)->waiter.invoke () |
416 | | Iris::free_cap ((*p)->waiter) |
417 | | (*p)->waiter = Iris::Cap () |
418 | | kdebug ("got all devices\n") |
| 393 | (*dev)->client = NULL |
| 394 | (*dev)->cap = Iris::Cap () |
419 | 395 | else if match (start, maxlen, "sysreq"): |
420 | | // TODO |
421 | | start += maxlen |
422 | | maxlen = 0 |
| 396 | Program *server |
| 397 | if sysreq: |
| 398 | Iris::panic (0, "double registration of sysreq") |
| 399 | if !find_cap (start, maxlen, server, sysreq): |
| 400 | Iris::panic (0, "capability not found for sysreq") |
| 401 | if sysreq->type != Iris::Keyboard::ID: |
| 402 | kdebug ("capability for sysreq is not a keyboard\n") |
423 | 403 | else if match (start, maxlen, "give"): |
424 | | // TODO |
425 | | start += maxlen |
426 | | maxlen = 0 |
427 | | else if match (start, maxlen, "include"): |
| 404 | // give <name> / <type> [, <index>] = <cap> |
428 | 405 | char *n |
429 | 406 | unsigned l |
430 | | if !get_name (start, maxlen, n, l): |
431 | | Iris::panic (0, "syntax error in init.config (include)") |
| 407 | if !get_name (start, maxlen, n, l) || !match (start, maxlen, "/") || !maxlen: |
| 408 | Iris::panic (0, "syntax error in init.config (give)") |
432 | 409 | List <Program>::Item *p |
433 | 410 | for p = programs.begin (); p; p = p->next: |
434 | 411 | if string_match ((*p)->name, (*p)->name_len, n, l): |
435 | 412 | break |
436 | 413 | if !p: |
437 | | Iris::panic (0, "file not found for include") |
438 | | include_caps ((*p)->pages, (*p)->size) |
| 414 | Iris::panic (0, "program not found for give") |
| 415 | List <Clientdevice>::Item *d = (*p)->client_devices.insert () |
| 416 | find_type (start, maxlen, (*d)->type, (*d)->index) |
| 417 | if !match (start, maxlen, "="): |
| 418 | Iris::panic (1, "syntax error in init.config (give)") |
| 419 | Program *server |
| 420 | if !find_cap (start, maxlen, server, (*d)->dev): |
| 421 | Iris::panic (0, "capability not found for give") |
| 422 | if (*d)->dev->type != (*d)->type: |
| 423 | kdebug ("capability type mismatch for give\n") |
| 424 | if (*d)->dev->client: |
| 425 | Iris::panic (0, "capability given out twice") |
| 426 | (*d)->dev->client = &**p |
| 427 | ++(*p)->num_waiting |
| 428 | kdebug ("registered give device: ") |
| 429 | kdebug_num ((*d)->type) |
| 430 | kdebug ("\n") |
| 431 | else if match (start, maxlen, "include"): |
| 432 | unsigned name_len |
| 433 | char *name = get_filename (line, maxlen, name_len) |
| 434 | include (name, name_len) |
439 | 435 | else: |
440 | 436 | Iris::panic (0, "invalid line in init.config") |
441 | 437 | delspace (start, maxlen) |
... | ... | |
449 | 445 | Iris::Num start (): |
450 | 446 | init_alloc () |
451 | 447 | programs.init () |
452 | | root = Iris::my_parent.get_device <Iris::Directory> () |
453 | | elfrun = Iris::my_parent.get_device <Iris::Elfrun> () |
| 448 | root = Iris::my_parent.get_capability <Iris::Directory> () |
| 449 | elfrun = Iris::my_parent.get_capability <Iris::Elfrun> () |
| 450 | sysreq = NULL |
454 | 451 | top_memory = Iris::get_top_memory () |
455 | | to_receive = 0 |
456 | | progs = 0 |
457 | | unsigned config_size |
458 | | Iris::Caps config_pages = load ("init.config", 12, config_size) |
459 | | include_caps (config_pages, config_size) |
| 452 | include ("init.config", 12) |
| 453 | kdebug ("killing boot threads\n") |
| 454 | Iris::my_parent.init_done () |
| 455 | for List <Program>::Item *p = programs.begin (); p; p = p->next: |
| 456 | if !(*p)->num_waiting: |
| 457 | (*p)->run () |
| 458 | if !sysreq: |
| 459 | Iris::panic (0, "sysreq not registered") |
| 460 | if sysreq->client: |
| 461 | Iris::panic (0, "sysreq set to reserved capability") |
460 | 462 | kdebug ("waiting for events.\n") |
461 | 463 | while true: |
462 | 464 | Iris::wait () |
463 | | Program *caller = (Program *)Iris::recv.protected_data.l |
464 | | if !caller: |
465 | | // System request. |
466 | | // TODO. |
467 | | kdebug ("system request\n") |
| 465 | if Iris::recv.protected_data.l == SYSREQ: |
| 466 | if Iris::recv.data[0].l & Iris::Keyboard::RELEASE: |
| 467 | continue |
| 468 | kdebug ("sysreq event\n") |
468 | 469 | continue |
| 470 | Program *caller = (Program *)Iris::recv.protected_data.l |
469 | 471 | switch Iris::recv.data[0].l: |
| 472 | case Iris::Parent::GET_CAPABILITY: |
| 473 | unsigned index = Iris::recv.data[0].h |
| 474 | unsigned type = Iris::recv.data[1].l |
| 475 | if Iris::recv.data[1].h: |
| 476 | Iris::panic (Iris::recv.data[1].h, "high device requested") |
| 477 | //kdebug ("requested device ") |
| 478 | //kdebug_num (type) |
| 479 | //kdebug (":") |
| 480 | //kdebug_num (index) |
| 481 | //kdebug ("\n") |
| 482 | List <Clientdevice>::Item *d |
| 483 | for d = caller->client_devices.begin (); d; d = d->next: |
| 484 | //kdebug ("checking ") |
| 485 | //kdebug_num ((*d)->type) |
| 486 | //kdebug (":") |
| 487 | //kdebug_num ((*d)->index) |
| 488 | //kdebug ("\n") |
| 489 | if (*d)->type == type && (*d)->index == index: |
| 490 | break |
| 491 | if !d: |
| 492 | Iris::panic (type, "unregistered device requested") |
| 493 | Iris::recv.reply.invoke (0, 0, (*d)->dev->cap) |
| 494 | kdebug ("given device ") |
| 495 | kdebug_num (type) |
| 496 | kdebug (":") |
| 497 | kdebug_num (index) |
| 498 | kdebug ("\n") |
| 499 | break |
| 500 | case Iris::Parent::PROVIDE_CAPABILITY: |
| 501 | if Iris::recv.data[1].h != 0: |
| 502 | kdebug ("init: too high device provided\n") |
| 503 | continue |
| 504 | unsigned type = Iris::recv.data[1].l |
| 505 | unsigned index = Iris::recv.data[0].h |
| 506 | List <Serverdevice>::Item *d |
| 507 | for d = caller->server_devices.begin (); d; d = d->next: |
| 508 | if (*d)->type == type && (*d)->index == index: |
| 509 | break |
| 510 | if !d: |
| 511 | Iris::panic (0, "unregistered device provided") |
| 512 | (*d)->cap = Iris::get_arg () |
| 513 | Iris::recv.reply.invoke () |
| 514 | if (*d)->client: |
| 515 | if !--(*d)->client->num_waiting: |
| 516 | (*d)->client->run () |
| 517 | kdebug ("provided ") |
| 518 | kdebug_num ((*d)->type) |
| 519 | kdebug (":") |
| 520 | kdebug_num ((*d)->index) |
| 521 | kdebug ("\n") |
| 522 | break |
| 523 | case Iris::Parent::INIT_DONE: |
| 524 | kdebug ("init done\n") |
| 525 | Iris::recv.reply.invoke () |
| 526 | if caller == sysreq->server: |
| 527 | Iris::Cap cap = Iris::my_receiver.create_capability (SYSREQ) |
| 528 | Iris::Keyboard (sysreq->cap).set_cb (cap.copy ()) |
| 529 | Iris::free_cap (cap) |
| 530 | kdebug ("registered sysreq\n") |
| 531 | break |
470 | 532 | default: |
471 | 533 | // TODO. |
472 | 534 | kdebug ("child request: ") |
... | ... | |
475 | 537 | for unsigned i = 0; i < caller->name_len; ++i: |
476 | 538 | kdebug_char (caller->name[i]) |
477 | 539 | kdebug ("\n") |
478 | | |
source/lcd.ccp |
261 | 261 | static Descriptor descriptor __attribute__ ((aligned (16))) |
262 | 262 | static bool is_on |
263 | 263 | |
264 | | static unsigned create (Iris::Memory mem, Iris::Caps caps): |
| 264 | static unsigned create (Iris::Memory mem): |
265 | 265 | unsigned physical = mem.alloc_range (pages) |
266 | 266 | unsigned address = 0x15000 |
267 | 267 | if physical & ~PAGE_MASK: |
... | ... | |
275 | 275 | Iris::free_cap (p) |
276 | 276 | return physical |
277 | 277 | |
278 | | static void destroy (unsigned physical, Iris::Caps caps): |
| 278 | static void destroy (unsigned physical, Iris::Memory mem): |
279 | 279 | unsigned address = 0x15000 |
280 | | Iris::Memory mem = caps.get (1) |
281 | 280 | if physical == ~0: |
282 | 281 | Iris::panic (0, "unable to destroy framebuffer with wrong cap0") |
283 | 282 | if descriptor.frame == physical && is_on: |
... | ... | |
291 | 290 | mem.destroy (p) |
292 | 291 | Iris::free_cap (p) |
293 | 292 | |
294 | | static void use (unsigned physical, Iris::Caps caps): |
| 293 | static void use (unsigned physical): |
295 | 294 | if physical == ~0: |
296 | 295 | Iris::panic (0, "unable to use framebuffer with wrong cap0") |
297 | 296 | bool was_unused = descriptor.frame == 0 |
... | ... | |
304 | 303 | write_reg (BACKLIGHT1, 0x5f) |
305 | 304 | #endif |
306 | 305 | |
307 | | static void unuse (unsigned physical, Iris::Caps caps): |
| 306 | static void unuse (unsigned physical): |
308 | 307 | if physical == ~0: |
309 | 308 | Iris::panic (0, "unable to unuse framebuffer with wrong cap0") |
310 | 309 | if descriptor.frame == physical: |
... | ... | |
323 | 322 | #endif |
324 | 323 | |
325 | 324 | pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS |
326 | | #if 0 |
327 | | unsigned physical = Iris::my_memory.alloc_range (pages) |
328 | | assert (physical & PAGE_MASK && ~physical) |
329 | | for unsigned i = 0; i < pages; ++i: |
330 | | Iris::Page p = Iris::my_memory.create_page () |
331 | | p.alloc_physical (physical + (i << PAGE_BITS), false, true) |
332 | | Iris::my_memory.map (p, (unsigned)LCD_FRAMEBUFFER_BASE + (i << PAGE_BITS)) |
333 | | Iris::free_cap (p) |
334 | | for unsigned y = 0; y < v; ++y: |
335 | | for unsigned x = 0; x < h; ++x: |
336 | | unsigned r = spot (x, y, 100, 160) |
337 | | unsigned g = spot (x, y, 160, 60) |
338 | | unsigned b = spot (x, y, 220, 160) |
339 | | #if defined (TRENDTAC) |
340 | | LCD_FRAMEBUFFER_BASE[y * h + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3) |
341 | | #elif defined (NANONOTE) |
342 | | LCD_FRAMEBUFFER_BASE[y * h + x] = (r << 16) | (g << 8) | b |
343 | | #else |
344 | | #error "Define your framebuffer format." |
345 | | #endif |
346 | | #else |
347 | 325 | unsigned physical = 0 |
348 | | #endif |
349 | 326 | Iris::Page p = Iris::my_memory.mapping (&descriptor) |
350 | 327 | unsigned paddr = p.physical_address () |
351 | 328 | physical_descriptor = paddr + ((unsigned)&descriptor & ~PAGE_MASK) |
... | ... | |
364 | 341 | #endif |
365 | 342 | |
366 | 343 | // Register the backlight device. |
367 | | Iris::Cap backlight = Iris::my_receiver.create_capability (BACKLIGHT) |
368 | | Iris::my_parent.provide_device <Iris::Setting> (backlight.copy ()) |
| 344 | Iris::Setting backlight = Iris::my_receiver.create_capability (BACKLIGHT) |
| 345 | Iris::my_parent.provide_capability <Iris::Setting> (backlight.copy ()) |
369 | 346 | Iris::free_cap (backlight) |
370 | 347 | |
371 | 348 | // Register the display device. |
372 | 349 | Iris::Display display = Iris::my_receiver.create_capability (LCD) |
373 | | Iris::my_parent.provide_device <Iris::Display> (display.copy ()) |
| 350 | Iris::my_parent.provide_capability <Iris::Display> (display.copy ()) |
374 | 351 | Iris::free_cap (display) |
| 352 | |
375 | 353 | Iris::my_parent.init_done () |
376 | 354 | |
377 | 355 | Iris::Cap eof_cb |
... | ... | |
441 | 419 | reply.invoke () |
442 | 420 | Iris::free_cap (reply) |
443 | 421 | break |
| 422 | case Iris::Display::MAP_FB: |
| 423 | unsigned addr = Iris::recv.data[1].l |
| 424 | unsigned use = Iris::recv.data[0].h |
| 425 | Iris::Cap reply = Iris::get_reply () |
| 426 | Iris::Memory mem = Iris::get_arg () |
| 427 | unsigned physical = mem.alloc_range (pages) |
| 428 | assert (physical & PAGE_MASK && ~physical) |
| 429 | Iris::Caps ret = mem.create_caps (pages / 63 + 1) |
| 430 | unsigned slot = ret.use () |
| 431 | for unsigned c = 0; c < pages / 63 + 1; ++c: |
| 432 | Iris::Caps caps (Iris::Cap (slot, c)) |
| 433 | unsigned num = pages - 63 * c >= 63 ? 63 : pages - 63 * c |
| 434 | Iris::set_recv_arg (caps) |
| 435 | mem.create_caps (num) |
| 436 | unsigned slot2 = caps.use () |
| 437 | for unsigned i = 0; i < num; ++i: |
| 438 | Iris::Page p = Iris::Cap (slot2, i) |
| 439 | Iris::set_recv_arg (p) |
| 440 | mem.create_page () |
| 441 | p.alloc_physical (physical + ((63 * c + i) << PAGE_BITS), false, true) |
| 442 | mem.map (p, addr + ((63 * c + i) << PAGE_BITS)) |
| 443 | Iris::free_slot (slot2) |
| 444 | Iris::free_slot (slot) |
| 445 | reply.invoke (0, 0, ret.copy ()) |
| 446 | Iris::free_cap (ret) |
| 447 | Iris::free_cap (mem) |
| 448 | Iris::free_cap (reply) |
| 449 | if !use: |
| 450 | break |
| 451 | bool was_unused = descriptor.frame == 0 |
| 452 | descriptor.frame = physical |
| 453 | unsigned dptr = (unsigned)&descriptor |
| 454 | __asm__ volatile ("lw $a0, %0\ncache 0x15, 0($a0)" :: "m"(dptr) : "memory", "a0") |
| 455 | if was_unused && is_on: |
| 456 | lcd_set_ena () |
| 457 | #ifdef NANONOTE: |
| 458 | write_reg (BACKLIGHT1, 0x5f) |
| 459 | #endif |
| 460 | break |
| 461 | case Iris::Display::UNMAP_FB: |
| 462 | Iris::panic (0, "unmap_fb isn't implemented yet") |
444 | 463 | case Iris::Display::GET_INFO: |
445 | | Iris::panic (0, "get_info isn't defined yet.") |
| 464 | Iris::panic (0, "get_info isn't implemented yet.") |
446 | 465 | default: |
447 | 466 | Iris::panic (Iris::recv.data[0].l, "invalid operation for lcd") |
448 | 467 | break |
ui.hhp |
| 1 | #pypp 0 |
| 2 | #include <iris.hh> |
| 3 | #include <devices.hh> |
| 4 | |
| 5 | template <unsigned I, unsigned O> // |
| 6 | class UI: |
| 7 | struct in_base: |
| 8 | UI <I, O> *ui |
| 9 | unsigned my_index |
| 10 | void (*handle) (in_base *self, void (*cb)(unsigned)) |
| 11 | void (*send) (in_base *self, Iris::Cap c) |
| 12 | in_base () : ui (NULL), my_index (0), handle (NULL), send (NULL): |
| 13 | struct out_base: |
| 14 | UI <I, O> *ui |
| 15 | unsigned my_index |
| 16 | void (*send) (out_base *self, Iris::Cap c) |
| 17 | out_base () : ui (NULL), my_index (0), send (NULL): |
| 18 | |
| 19 | public: |
| 20 | |
| 21 | void init (Iris::Cap my_cap): |
| 22 | Iris::my_parent.provide_capability <Iris::UI> (my_cap) |
| 23 | template <typename _T> // |
| 24 | class in : public in_base: |
| 25 | friend class UI <I, O> |
| 26 | _T my_data |
| 27 | static void send_impl (in_base *self, Iris::Cap c): |
| 28 | c.invoke (self->my_index | Iris::UI::INPUT, reinterpret_cast <in <_T> *> (self)->my_data) |
| 29 | static void handle_impl (in_base *self, void (*cb)(unsigned)): |
| 30 | in *me = reinterpret_cast <in *> (self) |
| 31 | if me->my_data == Iris::recv.data[1].l: |
| 32 | return |
| 33 | me->my_data = Iris::recv.data[1].l |
| 34 | cb (me->my_index) |
| 35 | public: |
| 36 | void init (): |
| 37 | this->send = &send_impl |
| 38 | this->handle = &handle_impl |
| 39 | operator _T () const: |
| 40 | return my_data |
| 41 | class in_event : public in_base: |
| 42 | friend class UI <I, O> |
| 43 | static void send_impl (in_base *self, Iris::Cap c): |
| 44 | c.invoke (self->my_index | Iris::UI::INPUT) |
| 45 | static void handle_impl (in_base *self, void (*cb)(unsigned)): |
| 46 | cb (self->my_index) |
| 47 | public: |
| 48 | void init (): |
| 49 | this->send = &send_impl |
| 50 | this->handle = &handle_impl |
| 51 | template <typename _T> // |
| 52 | class out : public out_base: |
| 53 | friend class UI <I, O> |
| 54 | _T my_data |
| 55 | static void send_impl (out_base *self, Iris::Cap c): |
| 56 | c.invoke (self->my_index, reinterpret_cast <out <_T> *> (self)->my_data) |
| 57 | public: |
| 58 | void init (): |
| 59 | this->send = &send_impl |
| 60 | out <_T> &operator= (_T const &t): |
| 61 | if !this->ui || my_data == t: |
| 62 | return *this |
| 63 | my_data = t |
| 64 | send_impl (this, this->ui->cap) |
| 65 | return *this |
| 66 | operator _T () const: |
| 67 | return my_data |
| 68 | class out_event : public out_base: |
| 69 | friend class UI <I, O> |
| 70 | public: |
| 71 | static void send_impl (out_base *self, Iris::Cap c): |
| 72 | // Don't send an event. This is only for listing the state. |
| 73 | void operator() (): |
| 74 | if !this->ui: |
| 75 | return |
| 76 | this->ui->cap.invoke (this->my_index) |
| 77 | void init (): |
| 78 | this->send = &send_impl |
| 79 | void add_in (in_base *obj, unsigned code): |
| 80 | ins[code] = obj |
| 81 | obj->ui = this |
| 82 | obj->my_index = code |
| 83 | void add_out (out_base *obj, unsigned code): |
| 84 | outs[code] = obj |
| 85 | obj->ui = this |
| 86 | obj->my_index = code |
| 87 | bool event (void (*cb)(unsigned)): |
| 88 | switch Iris::recv.data[0].l: |
| 89 | case Iris::UI::EXIT: |
| 90 | Iris::recv.reply.invoke () |
| 91 | return false |
| 92 | case Iris::UI::GET_STATE: |
| 93 | if cap.code != CAP_NONE: |
| 94 | Iris::free_cap (cap) |
| 95 | cap = Iris::get_arg () |
| 96 | Iris::recv.reply.invoke () |
| 97 | for unsigned i = 0; i < I; ++i: |
| 98 | ins[i]->send (ins[i], cap) |
| 99 | for unsigned i = 0; i < O; ++i: |
| 100 | outs[i]->send (outs[i], cap) |
| 101 | break |
| 102 | case Iris::UI::EVENT: |
| 103 | Iris::Cap r = Iris::get_reply () |
| 104 | if Iris::recv.data[0].h >= I: |
| 105 | Iris::panic (Iris::recv.data[0].h, "invalid input requested by ui") |
| 106 | ins[Iris::recv.data[0].h]->handle (ins[Iris::recv.data[0].h], cb) |
| 107 | r.invoke () |
| 108 | Iris::free_cap (r) |
| 109 | break |
| 110 | default: |
| 111 | Iris::panic (Iris::recv.data[0].l, "invalid request for ui") |
| 112 | return true |
| 113 | private: |
| 114 | in_base *ins[I] |
| 115 | out_base *outs[O] |
| 116 | Iris::Cap cap |