Date:2010-08-23 23:55:51 (13 years 7 months ago)
Author:Bas Wijnen
Commit:aef83317c942027994cccc463a300f8eb1f8970f
Message:working boot loader

Files: devices.hhp (1 diff)
init.config (2 diffs)
invoke.ccp (2 diffs)
iris.hhp (1 diff)
kernel.hhp (1 diff)
mips/interrupts.ccp (1 diff)
mips/nanonote/Makefile.arch (1 diff)
mips/nanonote/board.ccp (1 diff)
source/boot.ccp (1 diff)
source/booter.ccp (1 diff)
source/init.ccp (12 diffs)

Change Details

devices.hhp
8585        void set_block (Num idx, Page page, unsigned size = PAGE_SIZE, unsigned offset = 0):
8686            ocall (page, Iris::Num (CAP_MASTER_DIRECT | SET_BLOCK, size << 16 | offset), idx)
8787
88    // This interface allows another kernel to be booted by Iris.
89    struct Boot : public Cap:
90        Boot (Cap c = Cap ()) : Cap (c):
91        enum request:
92            BOOT = WString::ID
93            ID
94        // Boot a new kernel.
95        void boot (String code, unsigned load, unsigned entry):
96            ocall (code, CAP_MASTER_DIRECT | BOOT, Iris::Num (load, entry))
97
8898    // Every process which wants to be switchable through a terminal must implement this interface.
8999    struct Device : public Cap:
90100        Device (Cap c = Cap ()) : Cap (c):
91101        enum request:
92            RESET = WString::ID
102            RESET = Boot::ID
93103            ID
94104        // Reset the device. This is called by the terminal while switching owners.
95105        void reset ():
init.config
11    # driver <name> = '<filename>' load a file into memory to be run priviledged.
22    # program <name> = '<filename>' load a file into memory to be run normally.
3    # file <name> = '<filename>' load a file into memory as a String.
34    # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
45    # sysreq <cap> use a capability as the system request keyboard.
56    # give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
...... 
1213    receive driver_gpio / Event = sdmmc_gpio
1314    sysreq sysreq
1415
15    driver nand = "nand.elf"
16    #driver nand = "nand.elf"
1617
17    #driver driver_lcd = "lcd.elf"
18    #receive driver_lcd / Display = display
19    #receive driver_lcd / Setting = display_bright
18    #driver driver_boot = "boot.elf"
19    #receive driver_boot / Boot = boot
2020
21    #driver driver_buzzer = "buzzer.elf"
22    #receive driver_buzzer / Buzzer = buzzer
21    #file kernel = "kernel.raw"
22    #program booter = "booter.elf"
23    #give booter / String = kernel
24    #give booter / Boot = boot
2325
24    #program alarm = "alarm.elf"
25    #receive alarm / UI = ui
26    driver driver_lcd = "lcd.elf"
27    receive driver_lcd / Display = display
28    receive driver_lcd / Setting = display_bright
2629
27    #program gui = "gui.elf"
28    #give gui / UI = ui
29    #give gui / Display = display
30    #give gui / Setting = display_bright
31    #give gui / Buzzer = buzzer
32    #give gui / Keyboard = keyboard
30    driver driver_buzzer = "buzzer.elf"
31    receive driver_buzzer / Buzzer = buzzer
32
33    program alarm = "alarm.elf"
34    receive alarm / UI = ui
35
36    program gui = "gui.elf"
37    give gui / UI = ui
38    give gui / Display = display
39    give gui / Setting = display_bright
40    give gui / Buzzer = buzzer
41    give gui / Keyboard = keyboard
3342
3443    #driver sdmmc = "sd+mmc.elf"
3544    #receive sdmmc / WString = sdmmc
invoke.ccp
501501                    break
502502                case Iris::Thread::PRIV_ALLOC_RANGE & REQUEST_MASK:
503503                    if !c->arg.valid () || ((unsigned)c->arg->target) & ~REQUEST_MASK != CAPTYPE_MEMORY:
504                        panic (0x54365435, "non-memory argument to alloc_range")
504                        dpanic (0x54365435, "non-memory argument to alloc_range")
505505                        reply_num (Iris::ERR_INVALID_ARGUMENT)
506506                        return
507507                    kMemory *mem = (kMemory *)c->arg->protected_data.l
...... 
559559                case Iris::Thread::PRIV_POWEROFF & REQUEST_MASK:
560560                    arch_poweroff ()
561561                case Iris::Thread::PRIV_BOOT & REQUEST_MASK:
562                    arch_boot (c->data[1].l)
562                    arch_boot (c->data[1].l, c->data[1].h)
563563                case Iris::Thread::PRIV_PANIC & REQUEST_MASK:
564564                    if c->data[1].l == 0xdeaddead:
565565                        dbg_code.l = 1
iris.hhp
582582        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT)
583583    inline void poweroff ():
584584        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_POWEROFF)
585    inline void boot (unsigned address):
586        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_BOOT, address)
585    inline void boot (unsigned address, unsigned arg):
586        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_BOOT, Iris::Num (address, arg))
587587
588588    void Receiver::sleep (unsigned value):
589589        set_alarm (value)
kernel.hhp
323323void arch_register_interrupt (unsigned num, kReceiverP r)
324324void arch_reboot ()
325325void arch_poweroff ()
326void arch_boot (unsigned address)
326void arch_boot (unsigned address, unsigned arg)
327327void arch_uncache_page (unsigned page)
328328
329329#define assert(x) do { if (!(x)) panic (__LINE__, "assertion failed"); } while (0)
mips/interrupts.ccp
1919#define ARCH
2020#include "../kernel.hh"
2121
22typedef unsigned cacheline[8]
2322void arch_flush_cache ():
24    for cacheline *line = (cacheline *)0x80000000; line < (cacheline *)0x80008000; ++line:
25        __asm__ volatile ("lw $k0, %0; cache 0, 0($k0); cache 1, 0($k0)" :: "m"(line))
23    __asm__ volatile ("\t.set noreorder\n"
24        "\tlui $k0, 0x8000\n"
25        "\tori $k1, $k0, 0x4000 - 0x20\n"
26        "1:\tcache 0, 0($k0)\n"
27        "\tcache 1, 0($k0)\n"
28        "\tbne $k0, $k1, 1b\n"
29        "\taddiu $k0, $k0, 0x20\n"
30        "\t.set reorder\n")
2631
2732static kThread *handle_exit ():
2833    dbg_check ()
mips/nanonote/Makefile.arch
2626sd_boot_programs = sd+mmc partition fat
2727standard_boot_programs = bootinit
2828
29programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs)
29programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test boot booter $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs)
3030
3131ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
3232CROSS = mipsel-linux-gnu-
mips/nanonote/board.ccp
118118    kdebug ("Power down failed! Rebooting instead.\n")
119119    arch_reboot ()
120120
121void arch_boot (unsigned address):
121// Boot into another kernel.
122void arch_boot (unsigned address, unsigned arg):
122123    sync_serial ()
123    // Boot into another kernel.
124124    arch_flush_cache ()
125    return ((void (*)())address) ()
125    ((void (*)(unsigned))address) (arg)
source/boot.ccp
1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// source/boot.ccp: Boot into another kernel.
4// Copyright 2010 Bas Wijnen <wijnen@debian.org>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#include <iris.hh>
20#include <devices.hh>
21
22extern "C":
23    extern unsigned pre_code, pre_end, post_code, post_end
24
25struct args_t:
26    unsigned load
27    unsigned size
28    unsigned entry
29    unsigned source
30
31Iris::Num start ():
32    unsigned *loader_addr = (unsigned *)0x15000
33    unsigned *page_addr = (unsigned *)0x16000
34    unsigned *tmp_addr = (unsigned *)0x17000
35    Iris::Boot cap = Iris::my_receiver.create_capability (0)
36    Iris::my_parent.provide_capability <Iris::Boot> (cap.copy ())
37    Iris::free_cap (cap)
38    Iris::my_parent.init_done ()
39
40    while true:
41        Iris::wait ()
42        switch Iris::recv.data[0].l:
43            case Iris::Boot::BOOT:
44                Iris::String code = Iris::get_arg ()
45                unsigned load = Iris::recv.data[1].l
46                unsigned entry = Iris::recv.data[1].h
47                Iris::Num lsize = code.get_size ()
48                if lsize.h != 0:
49                    Iris::panic (lsize.h, "string to boot is too large to be loaded")
50                unsigned size = lsize.l
51                unsigned pages = ((size + ~PAGE_MASK) >> PAGE_BITS) + 1
52                unsigned phys = Iris::my_memory.alloc_range (pages)
53                if phys & ~PAGE_MASK:
54                    Iris::panic (size, "unable to allocate space for string to load")
55                unsigned target, offset
56                if phys < (load & ~0xa0000000):
57                    Iris::debug ("pre-loading\n")
58                    Iris::Page pre = Iris::my_memory.create_page ()
59                    pre.alloc_physical (phys, true, true)
60                    Iris::my_memory.map (pre, (unsigned)loader_addr)
61                    for unsigned i = 0; i < &pre_end - &pre_code; ++i:
62                        loader_addr[i] = (&pre_code)[i]
63                    target = phys
64                    offset = 1
65                else:
66                    Iris::debug ("post-loading\n")
67                    Iris::Page post = Iris::my_memory.create_page ()
68                    post.alloc_physical (phys + ((pages - 1) << PAGE_BITS), true, true)
69                    Iris::my_memory.map (post, (unsigned)loader_addr)
70                    for unsigned i = 0; i < &post_end - &post_code; ++i:
71                        loader_addr[i] = (&post_code)[i]
72                    target = phys + ((pages - 1) << PAGE_BITS)
73                    offset = 0
74                Iris::Page tmp = Iris::my_memory.create_page ()
75                tmp.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
76                Iris::my_memory.map (tmp, (unsigned)tmp_addr)
77                for unsigned i = 0; i < pages - 1; ++i:
78                    Iris::Page page = Iris::my_memory.create_page ()
79                    page.alloc_physical (phys + ((i + offset) << PAGE_BITS), true, true)
80                    Iris::my_memory.map (page, (unsigned)page_addr)
81                    code.get_block (i << PAGE_BITS, PAGE_SIZE, 0, tmp)
82                    for unsigned t = 0; t < PAGE_SIZE / 4; ++t:
83                        page_addr[t] = tmp_addr[t]
84                args_t *args = (args_t *)((unsigned)loader_addr + PAGE_SIZE - sizeof (args_t))
85                unsigned phys_args = target + PAGE_SIZE - sizeof (args_t)
86                args->load = load
87                args->entry = entry
88                args->size = size
89                args->source = phys + (offset << PAGE_BITS) | 0x80000000
90                Iris::debug ("booting into: %x+%x->%x@%x (%x, %x)\n", args->source, args->size, args->load, args->entry, args, phys_args)
91                // Everything is set up; jump to the loader.
92                Iris::boot (target | 0x80000000, phys_args | 0x80000000)
93                Iris::panic (0, "Iris::boot should not return, but it does")
94            default:
95                Iris::panic (Iris::recv.data[0].l, "invalid commend received on boot capability")
96
97asm volatile ("\t.set noreorder\n"
98    "\t.globl pre_code, pre_end, post_code, post_end\n"
99    "\t.text\n"
100    "pre_code:\n"
101    "\tlw $t0, 0($a0)\n" // t0 is the load address
102    "\tlw $t1, 4($a0)\n" // t1 is the size
103    "\tlw $t9, 8($a0)\n" // t9 is the entry point
104    "\tlw $t2, 12($a0)\n" // t2 is the source of the loaded image
105    "\tadd $t0, $t0, $t1\n" // t0 is the end of the load region
106    "\tadd $t2, $t2, $t1\n" // t2 is the end of the source
107    "1:\n"
108    "\tlw $t3, -4($t2)\n"
109    "\tsw $t3, -4($t0)\n"
110    "\taddiu $t2, $t2, -4\n"
111    "\taddiu $t1, $t1, -4\n"
112    "\tbnez $t1, 1b\n"
113    "\taddiu $t0, $t0, -4\n"
114                // Done copying
115    "\tjr $t9\n"
116    "\tnop\n"
117    "pre_end:\n"
118    "\n"
119    "post_code:\n"
120    "\tlw $t0, 0($a0)\n" // t0 is the load address
121    "\tlw $t1, 4($a0)\n" // t1 is the size
122    "\tlw $t9, 8($a0)\n" // t9 is the entry point
123    "\tlw $t2, 12($a0)\n" // t2 is the source of the loaded image
124    "1:\n"
125    "\tlw $t3, 0($t2)\n"
126    "\tsw $t3, 0($t0)\n"
127    "\taddiu $t2, $t2, 4\n"
128    "\taddiu $t1, $t1, -4\n"
129    "\tbnez $t1, 1b\n"
130    "\taddiu $t0, $t0, 4\n"
131                // Done copying
132    "\tjr $t9\n"
133    "\tnop\n"
134    "post_end:\n"
135    "\n"
136    "\t.set reorder\n")
source/booter.ccp
1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// source/booter.ccp: Boot into another kernel.
4// Copyright 2010 Bas Wijnen <wijnen@debian.org>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#include <iris.hh>
20#include <devices.hh>
21
22Iris::Num start ():
23    Iris::String data = Iris::my_parent.get_capability <Iris::String> ()
24    Iris::Boot boot = Iris::my_parent.get_capability <Iris::Boot> ()
25    //boot.boot (data, 0x81fff000, 0x81fff000)
26    boot.boot (data, 0xa1fff000, 0xa1fff000)
27    Iris::panic (0, "boot returns")
28    return 0
source/init.ccp
2626#define NUM_SLOTS 8
2727#define NUM_CAPS 32
2828
29#define SYSREQ 0x100
29enum Captype:
30    SYSREQ
31    PROGRAM
32    FILE
3033
3134static unsigned _free
3235extern unsigned _end
...... 
104107
105108struct Program
106109
107struct Serverdevice:
110struct Devbase:
108111    char *name
109112    unsigned name_len
110    unsigned type, index
113    unsigned type
114    Program *client
111115    Iris::Cap cap
116
117struct Serverdevice : public Devbase:
118    unsigned index
112119    Program *server
113    Program *client
114120
115121struct Clientdevice:
116122    unsigned type, index
117    Serverdevice *dev
123    Devbase *dev
118124
119125static Iris::Memory top_memory
120126static Iris::Directory root
...... 
132138    unsigned num_waiting
133139    bool priv
134140    void run ():
135        Iris::Cap cap = Iris::my_receiver.create_capability ((unsigned)this)
141        Iris::Cap cap = Iris::my_receiver.create_capability (Iris::Num (PROGRAM, (unsigned)this))
136142        if priv:
137143            kdebug ("priv ")
138144        kdebug ("running ")
...... 
148154            thread.make_priv ()
149155        thread.run ()
150156
157struct File : public Devbase:
158    unsigned size
159    Iris::Caps pages
160
151161static List <Program> programs
162static List <File> files
152163static Serverdevice *sysreq
153164
154165static bool name_match (char const *name, unsigned name_len, Iris::String n):
...... 
238249    while name_len < len && isnamechar (line[name_len]):
239250        ++name_len
240251    name = new char[name_len]
252    kdebug ("name: ")
241253    for unsigned i = 0; i < name_len; ++i:
242254        name[i] = line[i]
255        kdebug_char (name[i])
256    kdebug_char ('\n')
243257    line += name_len
244258    len -= name_len
245259    delspace (line, len)
...... 
272286static Type types[] = {
273287    { "String", 6, Iris::String::ID },
274288    { "WString", 7, Iris::WString::ID },
289    { "Boot", 4, Iris::Boot::ID },
275290    { "Device", 6, Iris::Device::ID },
276291    { "Event", 5, Iris::Event::ID },
277292    { "Parent", 6, Iris::Parent::ID },
...... 
303318            return
304319    Iris::panic (0, "no valid type found")
305320
306static bool find_cap (char *&line, unsigned &len, Program *&server, Serverdevice *&dev):
321static bool find_cap (char *&line, unsigned &len, Program **server, Devbase *&dev, bool &present):
307322    char *n
308323    unsigned l
309324    if !get_name (line, len, n, l):
310325        Iris::panic (0, "no capability name found in init.config")
311    List <Program>::Item *p
312    for p = programs.begin (); p; p = p->next:
326    for List <Program>::Item *p = programs.begin (); p; p = p->next:
313327        List <Serverdevice>::Item *d
314328        for d = (*p)->server_devices.begin (); d; d = d->next:
315329            if string_match (n, l, (*d)->name, (*d)->name_len):
316                server = &**p
330                if server:
331                    *server = &**p
317332                dev = &**d
333                present = false
318334                return true
335    if server:
336        return false
337    for List <File>::Item *f = files.begin (); f; f = f->next:
338        if string_match (n, l, (*f)->name, (*f)->name_len):
339            dev = &**f
340            present = true
341            return true
319342    return false
320343
321344static void parse_line (char *&line, unsigned maxlen)
...... 
374397    if !maxlen:
375398        return
376399    if match (start, maxlen, "program"):
400        // program <name> = "<filename>"
377401        do_load (start, maxlen, false)
378402    else if match (start, maxlen, "driver"):
403        // driver <name> = "<filename>"
379404        do_load (start, maxlen, true)
405    else if match (start, maxlen, "file"):
406        // file <name> = "<filename>"
407        File *f = &**files.insert ()
408        f->type = Iris::String::ID
409        if !get_name (start, maxlen, f->name, f->name_len) || !match (start, maxlen, "=") || !maxlen:
410            Iris::panic (0, "syntax error in init.config (file name)")
411        unsigned l
412        char *n = get_filename (start, maxlen, l)
413        f->pages = load (n, l, f->size)
414        f->cap = Iris::my_receiver.create_capability (Iris::Num (FILE, (unsigned)f))
415        ++line
416        --maxlen
380417    else if match (start, maxlen, "receive"):
381418        // receive <name> / <type> [, <index>] = <cap>
382419        char *n
...... 
400437        Program *server
401438        if sysreq:
402439            Iris::panic (0, "double registration of sysreq")
403        if !find_cap (start, maxlen, server, sysreq):
440        bool dummy
441        if !find_cap (start, maxlen, &server, *(Devbase **)&sysreq, dummy):
404442            Iris::panic (0, "capability not found for sysreq")
405443        if sysreq->type != Iris::Keyboard::ID:
406444            kdebug ("capability for sysreq is not a keyboard\n")
...... 
420458        find_type (start, maxlen, (*d)->type, (*d)->index)
421459        if !match (start, maxlen, "="):
422460            Iris::panic (1, "syntax error in init.config (give)")
423        Program *server
424        if !find_cap (start, maxlen, server, (*d)->dev):
461        bool present
462        if !find_cap (start, maxlen, NULL, (*d)->dev, present):
425463            Iris::panic (0, "capability not found for give")
426464        if (*d)->dev->type != (*d)->type:
427465            kdebug ("capability type mismatch for give\n")
428466        if (*d)->dev->client:
429467            Iris::panic (0, "capability given out twice")
430468        (*d)->dev->client = &**p
431        ++(*p)->num_waiting
469        if !present:
470            ++(*p)->num_waiting
432471        //kdebug ("registered give device: ")
433472        //kdebug_num ((*d)->type)
434473        //kdebug ("\n")
...... 
452491Iris::Num start ():
453492    init_alloc ()
454493    programs.init ()
494    files.init ()
455495    root = Iris::my_parent.get_capability <Iris::Directory> ()
456496    elfrun = Iris::my_parent.get_capability <Iris::Elfrun> ()
457497    sysreq = NULL
...... 
469509    kdebug ("waiting for events.\n")
470510    while true:
471511        Iris::wait ()
472        if Iris::recv.protected_data.l == SYSREQ:
473            if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
512        switch Iris::recv.protected_data.l:
513            case SYSREQ:
514                if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
515                    Iris::poweroff ()
516                    continue
517                kdebug ("sysreq event: powering device off at release\n")
474518                continue
475            kdebug ("sysreq event: powering device off\n")
476            Iris::poweroff ()
477            continue
478        Program *caller = (Program *)Iris::recv.protected_data.l
479        switch Iris::recv.data[0].l:
480            case Iris::Parent::GET_CAPABILITY:
481                unsigned index = Iris::recv.data[0].h
482                unsigned type = Iris::recv.data[1].l
483                if Iris::recv.data[1].h:
484                    Iris::panic (Iris::recv.data[1].h, "high device requested")
485                //kdebug ("requested device ")
486                //kdebug_num (type)
487                //kdebug (":")
488                //kdebug_num (index)
489                //kdebug ("\n")
490                List <Clientdevice>::Item *d
491                for d = caller->client_devices.begin (); d; d = d->next:
492                    //kdebug ("checking ")
493                    //kdebug_num ((*d)->type)
494                    //kdebug (":")
495                    //kdebug_num ((*d)->index)
496                    //kdebug ("\n")
497                    if (*d)->type == type && (*d)->index == index:
519            case FILE:
520                File *file = (File *)Iris::recv.protected_data.h
521                switch Iris::recv.data[0].l:
522                    case Iris::String::GET_SIZE:
523                        Iris::recv.reply.invoke (file->size)
498524                        break
499                if !d:
500                    Iris::panic (type, "unregistered device requested")
501                Iris::recv.reply.invoke (0, 0, (*d)->dev->cap)
502                //kdebug ("given device ")
503                //kdebug_num (type)
504                //kdebug (":")
505                //kdebug_num (index)
506                //kdebug ("\n")
507                break
508            case Iris::Parent::PROVIDE_CAPABILITY:
509                if Iris::recv.data[1].h != 0:
510                    kdebug ("init: too high device provided\n")
511                    continue
512                unsigned type = Iris::recv.data[1].l
513                unsigned index = Iris::recv.data[0].h
514                List <Serverdevice>::Item *d
515                for d = caller->server_devices.begin (); d; d = d->next:
516                    if (*d)->type == type && (*d)->index == index:
525                    case Iris::String::GET_CHARS:
526                        Iris::panic (0, "get_chars is not defined for init strings")
527                    case Iris::String::GET_ALIGN_BITS:
528                        Iris::recv.reply.invoke (PAGE_BITS)
517529                        break
518                if !d:
519                    Iris::panic (0, "unregistered device provided")
520                (*d)->cap = Iris::get_arg ()
521                Iris::recv.reply.invoke ()
522                if (*d)->client:
523                    if !--(*d)->client->num_waiting:
524                        (*d)->client->run ()
525                //kdebug ("provided ")
526                //kdebug_num ((*d)->type)
527                //kdebug (":")
528                //kdebug_num ((*d)->index)
529                //kdebug ("\n")
530                break
531            case Iris::Parent::INIT_DONE:
532                //kdebug ("init done\n")
533                Iris::recv.reply.invoke ()
534                if caller == sysreq->server:
535                    Iris::Cap cap = Iris::my_receiver.create_capability (SYSREQ)
536                    Iris::Keyboard (sysreq->cap).set_cb (cap.copy ())
537                    Iris::free_cap (cap)
538                    kdebug ("registered sysreq\n")
539                break
540            case Iris::Parent::EXIT:
541                kdebug ("child exits with code ")
542                // TODO: print name.
543                kdebug_num (Iris::recv.data[1].h)
544                kdebug (":")
545                kdebug_num (Iris::recv.data[1].l)
546                kdebug ("\n")
547                // TODO: destroy memory.
530                    case Iris::String::GET_BLOCK:
531                        Iris::Cap reply = Iris::get_reply ()
532                        Iris::Page target = Iris::get_arg ()
533                        Iris::Page source = file->pages.get (Iris::recv.data[1].l >> PAGE_BITS)
534                        source.share (target, Iris::Page::READONLY)
535                        reply.invoke ()
536                        Iris::free_cap (reply)
537                        Iris::free_cap (source)
538                        Iris::free_cap (target)
539                        break
540                    default:
541                        Iris::panic (Iris::recv.data[0].l, "unknown request for init string")
548542                break
549            default:
550                // TODO.
551                kdebug ("child request: ")
552                kdebug_num (Iris::recv.data[0].l)
553                kdebug (" from ")
554                for unsigned i = 0; i < caller->name_len; ++i:
555                    kdebug_char (caller->name[i])
556                kdebug ("\n")
543            case PROGRAM:
544                Program *caller = (Program *)Iris::recv.protected_data.h
545                switch Iris::recv.data[0].l:
546                    case Iris::Parent::GET_CAPABILITY:
547                        unsigned index = Iris::recv.data[0].h
548                        unsigned type = Iris::recv.data[1].l
549                        if Iris::recv.data[1].h:
550                            Iris::panic (Iris::recv.data[1].h, "high device requested")
551                        //kdebug ("requested device ")
552                        //kdebug_num (type)
553                        //kdebug (":")
554                        //kdebug_num (index)
555                        //kdebug ("\n")
556                        List <Clientdevice>::Item *d
557                        for d = caller->client_devices.begin (); d; d = d->next:
558                            //kdebug ("checking ")
559                            //kdebug_num ((*d)->type)
560                            //kdebug (":")
561                            //kdebug_num ((*d)->index)
562                            //kdebug ("\n")
563                            if (*d)->type == type && (*d)->index == index:
564                                break
565                        if !d:
566                            Iris::panic (type, "unregistered device requested")
567                        Iris::recv.reply.invoke (0, 0, (*d)->dev->cap)
568                        //kdebug ("given device ")
569                        //kdebug_num (type)
570                        //kdebug (":")
571                        //kdebug_num (index)
572                        //kdebug ("\n")
573                        break
574                    case Iris::Parent::PROVIDE_CAPABILITY:
575                        if Iris::recv.data[1].h != 0:
576                            kdebug ("init: too high device provided\n")
577                            continue
578                        unsigned type = Iris::recv.data[1].l
579                        unsigned index = Iris::recv.data[0].h
580                        List <Serverdevice>::Item *d
581                        for d = caller->server_devices.begin (); d; d = d->next:
582                            if (*d)->type == type && (*d)->index == index:
583                                break
584                        if !d:
585                            Iris::panic (0, "unregistered device provided")
586                        (*d)->cap = Iris::get_arg ()
587                        Iris::recv.reply.invoke ()
588                        if (*d)->client:
589                            if !--(*d)->client->num_waiting:
590                                (*d)->client->run ()
591                        //kdebug ("provided ")
592                        //kdebug_num ((*d)->type)
593                        //kdebug (":")
594                        //kdebug_num ((*d)->index)
595                        //kdebug ("\n")
596                        break
597                    case Iris::Parent::INIT_DONE:
598                        //kdebug ("init done\n")
599                        Iris::recv.reply.invoke ()
600                        if caller == sysreq->server:
601                            Iris::Cap cap = Iris::my_receiver.create_capability (SYSREQ)
602                            Iris::Keyboard (sysreq->cap).set_cb (cap.copy ())
603                            Iris::free_cap (cap)
604                            kdebug ("registered sysreq\n")
605                        break
606                    case Iris::Parent::EXIT:
607                        kdebug ("child ")
608                        for unsigned i = 0; i < caller->name_len; ++i:
609                            kdebug_char (caller->name[i])
610                        kdebug (" exits with code ")
611                        kdebug_num (Iris::recv.data[1].h)
612                        kdebug (":")
613                        kdebug_num (Iris::recv.data[1].l)
614                        kdebug ("\n")
615                        top_memory.destroy (caller->memory)
616                        break
617                    default:
618                        // TODO.
619                        kdebug ("child request: ")
620                        kdebug_num (Iris::recv.data[0].l)
621                        kdebug (" from ")
622                        for unsigned i = 0; i < caller->name_len; ++i:
623                            kdebug_char (caller->name[i])
624                        kdebug ("\n")

Archive Download the corresponding diff file

Branches:
master



interactive