Date:2010-05-10 01:07:17 (13 years 10 months ago)
Author:Bas Wijnen
Commit:8c7cac36e6b5650eb44fe4a39590e516608e8af9
Message:usb-booting alarm clock, with split gui

Files: Makefile (2 diffs)
boot-programs/bootinit.ccp (6 diffs)
boot-programs/udc.ccp (1 diff)
devices.hhp (4 diffs)
init.config (1 diff)
invoke.ccp (4 diffs)
iris.hhp (2 diffs)
memory.ccp (2 diffs)
mips/arch.ccp (1 diff)
mips/interrupts.ccp (2 diffs)
mips/nanonote/Makefile.arch (1 diff)
panic.ccp (2 diffs)
source/alarm.ccp (1 diff)
source/ball.ccp (1 diff)
source/bsquare.ccp (1 diff)
source/buzzer.ccp (2 diffs)
source/elfrun.ccp (5 diffs)
source/gui.ccp (1 diff)
source/init.ccp (11 diffs)
source/lcd.ccp (7 diffs)
source/metronome.ccp (1 diff)
source/nanonote-gpio.ccp (1 diff)
source/trendtac-gpio.ccp (1 diff)
ui.hhp (1 diff)

Change Details

Makefile
2323LD = $(CROSS)ld
2424OBJCOPY = $(CROSS)objcopy
2525
26headers = kernel.hh iris.hh $(arch_headers)
26headers = kernel.hh iris.hh ui.hh $(arch_headers)
2727iris_sources = panic.cc data.cc alloc.cc memory.cc invoke.cc schedule.cc $(arch_iris_sources)
2828BUILT_SOURCES = $(iris_sources) $(boot_sources)
2929
...... 
6262    cat $(SERIAL)
6363
6464.PHONY: clean
65.PRECIOUS: iris.hh kernel.hh boot-programs/crt0.o
65.PRECIOUS: iris.hh kernel.hh ui.hh boot-programs/crt0.o
boot-programs/bootinit.ccp
5858void *operator new (unsigned size):
5959    return new char[size]
6060
61static unsigned *bss_mapping
62static Iris::Page bss_page
63
6164// Get the initial block device and filesystem.
6265static Iris::Directory receive_devices ():
6366    Iris::String data
...... 
6568    bool have_data = false, have_fs = false
6669    for unsigned i = 0; i < 2; ++i:
6770        Iris::wait ()
68        if Iris::recv.data[0].l != Iris::Parent::PROVIDE_DEVICE:
71        if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY:
6972            Iris::panic (Iris::recv.data[0].l, "Invalid bootstrap request.")
7073        switch Iris::recv.data[1].l:
7174            case Iris::String::ID:
...... 
206209                Iris::Page page = mem.mapping ((void *)p)
207210                if Iris::recv.data[0].l == Iris::NO_ERROR:
208211                    // No error means there is a mapping.
212                    page.share (bss_page, 0)
209213                    Iris::free_cap (page)
210214                    for unsigned a = p; a < ((p + PAGE_SIZE) & PAGE_MASK); a += 4:
211215                        if a >= shdr->sh_addr + shdr->sh_size:
212216                            break
213217                        if a < shdr->sh_addr:
214218                            continue
215                        ((unsigned *)&mapping[p - shdr->sh_addr])[(a & ~PAGE_MASK) >> 2] = 0
219                        bss_mapping[(a & ~PAGE_MASK) >> 2] = 0
216220                else:
217221                    Iris::free_cap (page)
218222                    page = mem.create_page ()
...... 
256260    Iris::schedule ()
257261    kdebug ("Starting bootinit\n")
258262    init_alloc ()
263    bss_mapping = (unsigned *)alloc_space (1)
264    bss_page = Iris::my_memory.create_page ()
265    Iris::my_memory.map (bss_page, (unsigned)bss_mapping)
266
259267    Iris::Memory top_memory = Iris::get_top_memory ()
260268    Iris::Directory root = receive_devices ()
261269    root.lock_ro ()
...... 
263271    Iris::Cap parent_cap = Iris::my_receiver.create_capability (0)
264272    run (run_string, top_memory, parent_cap)
265273    Iris::wait ()
266    if Iris::recv.data[0].l != Iris::Parent::PROVIDE_DEVICE || Iris::recv.data[1].l != Iris::Elfrun::ID:
274    if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY || Iris::recv.data[1].l != Iris::Elfrun::ID:
267275        Iris::panic (0, "elfrun doesn't provide correct capability")
268276    Iris::Cap reply = Iris::get_reply ()
269277    Iris::Elfrun elfrun = Iris::get_arg ()
...... 
287295    while true:
288296        Iris::wait ()
289297        switch Iris::recv.data[0].l:
290            case Iris::Parent::GET_DEVICE:
298            case Iris::Parent::GET_CAPABILITY:
291299                switch Iris::recv.data[1].l:
292300                    case Iris::Directory::ID:
293301                        if have_root:
boot-programs/udc.ccp
573573    Iris::register_interrupt (IRQ_UDC)
574574    Iris::Filesystem fs = Iris::my_receiver.create_capability (FS)
575575    Iris::String data = Iris::my_receiver.create_capability (DATA)
576    Iris::my_parent.provide_device <Iris::Filesystem> (fs.copy ())
577    Iris::my_parent.provide_device <Iris::String> (data.copy ())
576    Iris::my_parent.provide_capability <Iris::Filesystem> (fs.copy ())
577    Iris::my_parent.provide_capability <Iris::String> (data.copy ())
578578    Iris::free_cap (fs)
579579    Iris::free_cap (data)
580580    unsigned state = 0
devices.hhp
126126    struct Parent : public Iris::Cap:
127127        Parent (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
128128        enum request:
129            GET_DEVICE = Elfrun::ID
130            PROVIDE_DEVICE
129            GET_CAPABILITY = Elfrun::ID
130            PROVIDE_CAPABILITY
131131            WAIT
132132            GET_MEMORY
133133            PROVIDE_MEMORY
134134            INIT_DONE
135135            EXIT
136136            ID
137        // Get a device handle.
138        template <typename _T> _T get_device (unsigned num = 0):
139            icall (Iris::Num (CAP_MASTER_DIRECT | GET_DEVICE, num), _T::ID)
137        // Get a handle.
138        template <typename _T> _T get_capability (unsigned num = 0):
139            icall (Iris::Num (CAP_MASTER_DIRECT | GET_CAPABILITY, num), _T::ID)
140140            return Iris::get_arg ()
141141        // Provide a device handle.
142        template <typename _T> void provide_device (Device dev, unsigned num = 0):
143            ocall (dev, Iris::Num (CAP_MASTER_DIRECT | PROVIDE_DEVICE, num), _T::ID)
142        template <typename _T> void provide_capability (Cap cap, unsigned num = 0):
143            ocall (cap, Iris::Num (CAP_MASTER_DIRECT | PROVIDE_CAPABILITY, num), _T::ID)
144144        // Wait until a device is used by the caller again.
145145        template <typename _T> void wait (unsigned num = 0):
146146            call (Iris::Num (CAP_MASTER_DIRECT | WAIT, num), _T::ID)
...... 
200200        enum request:
201201            SET_EOF_CB = Buzzer::ID
202202            MAP_FB
203            UNMAP_FB
203204            GET_INFO
204205            ID
205206        // Register an end-of-frame callback.
...... 
207208        void set_eof_cb (Iris::Cap cb):
208209            ocall (cb, CAP_MASTER_DIRECT | SET_EOF_CB)
209210        // Map the framebuffer into memory.
210        void map_fb (unsigned address):
211            call (CAP_MASTER_DIRECT | MAP_FB, address)
211        Iris::Caps map_fb (unsigned address, Iris::Memory mem = Iris::my_memory, bool use = true):
212            iocall (mem, Iris::Num (CAP_MASTER_DIRECT | MAP_FB, use ? 1 : 0), address)
213            return Iris::get_arg ()
214        void unmap_fb (Iris::Caps caps):
215            ocall (caps, CAP_MASTER_DIRECT | UNMAP_FB)
212216        // Get information about the display.
213217        void get_info ():
214218            // TODO: Interface is to be designed.
...... 
319323        Iris::Num write (String s, Iris::Num size):
320324            return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
321325
322
326    struct UI : public Iris::Cap:
327        UI (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
328        enum request:
329            GET_STATE = Stream::ID
330            EVENT
331            EXIT
332            ID
333        enum constant:
334            INPUT = 1 << 31
335        void get_state (Iris::Cap cap):
336            ocall (cap, CAP_MASTER_DIRECT | GET_STATE)
337        void event (unsigned code, unsigned value = 0):
338            call (Iris::Num (CAP_MASTER_DIRECT | EVENT, code), value)
339        void exit ():
340            call (CAP_MASTER_DIRECT | EXIT)
323341
324342    // Block device interface.
325343    struct Block_device : public WString:
init.config
1    # load <name> = '<filename>' load a file into memory. Don't use this after killbootthreads.
2    load driver_lcd = "lcd.elf"
3    #load driver_buzzer = "buzzer.elf"
4    #load driver_gpio = "gpio.elf"
5    load ball = "ball.elf"
6
7    # killbootthreads destroy bootinit, bootfs and bootstore.
8    killbootthreads
1    # driver <name> = '<filename>' load a file into memory to be run priviledged.
2    # program <name> = '<filename>' load a file into memory to be run normally.
3    driver driver_lcd = "lcd.elf"
4    driver driver_buzzer = "buzzer.elf"
5    driver driver_gpio = "gpio.elf"
6    program alarm = "alarm.elf"
7    program gui = "gui.elf"
98
109    # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
1110    receive driver_lcd / Display = display
1211    receive driver_lcd / Setting = display_bright
13    #receive driver_buzzer / Buzzer = buzzer
14    #receive driver_gpio / Keyboard , 0 = keyboard
15    #receive driver_gpio / Keyboard , 1 = sysreq
16
17    # driver <name> run a previously loaded program priviledged.
18    driver driver_lcd
19    #driver driver_buzzer
20    #driver driver_gpio
21
22    # wait wait until all expected capabilities are received.
23    wait
12    receive driver_buzzer / Buzzer = buzzer
13    receive driver_gpio / Keyboard , 0 = keyboard
14    receive driver_gpio / Keyboard , 1 = sysreq
15    receive alarm / UI = ui
2416
2517    # sysreq <cap> use a capability as the system request keyboard.
2618    sysreq sysreq
2719
2820    # give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
29    give ball / Display = display
21    give gui / UI = ui
22    give gui / Display = display
23    give gui / Setting = display_bright
24    give gui / Buzzer = buzzer
25    give gui / Keyboard = keyboard
3026
31    # run <name> run a previously loaded program (normally).
32    run ball
27    # include <file> include a file as another config file.
3328
34    # include <name> include a loaded file as another config file.
29    # at end of file, the initial threads are killed and the drivers and programs are run as soon as all their dependencies are provided.
invoke.ccp
390390    reply_num (0)
391391
392392static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_data, kCapability::Context *c):
393    dbg_push (__LINE__)
394393    kThread *thread = (kThread *)protected_data.l
395394    switch cmd:
396395        case Iris::Thread::GET_INFO & REQUEST_MASK:
...... 
441440                *value = (*value & ~c->data[1].h) | (c->data[1].l & c->data[1].h)
442441            break
443442        case Iris::Thread::USE_SLOT & REQUEST_MASK:
444            dbg_push (__LINE__)
445443            if c->data[1].l >= thread->slots || !c->arg.valid ():
446444                if c->data[1].l == 0xdeadbeef:
447445                    bool dummy
...... 
456454                dpanic ((unsigned)c->arg->target, "argument for USE_SLOT is not a caps")
457455                reply_num (Iris::ERR_INVALID_ARGUMENT)
458456                return
459            dbg_push (__LINE__)
460457            unsigned slot = c->data[1].l
461            dbg_push (__LINE__)
462458            kCaps *new_caps = (kCaps *)c->arg->protected_data.l
463            dbg_push (__LINE__)
464459            if slot >= thread->slots:
465460                dpanic (0, "using invalid slot")
466461                return
467            dbg_push (__LINE__)
468462            thread->unset_slot (slot)
469            dbg_push (__LINE__)
470463            thread->slot[slot].caps = new_caps
471            dbg_push (__LINE__)
472464            if new_caps:
473                dbg_push (__LINE__)
474465                thread->slot[slot].next = new_caps->first_slot
475466                thread->slot[slot].caps = new_caps
476467                new_caps->first_slot.thread = thread
477468                new_caps->first_slot.index = slot
478            dbg_push (__LINE__)
479469            break
480470        case Iris::Thread::GET_CAPS & REQUEST_MASK:
481471            unsigned slot = c->data[1].l
...... 
577567                    dpanic (0, "invalid priv thread operation")
578568                    reply_num (Iris::ERR_INVALID_OPERATION)
579569                    return
580    dbg_push (__LINE__)
581570    reply_num (0)
582    dbg_push (__LINE__)
583571    return
584572
585573static void page_check_payment (kPage *page):
iris.hhp
546546        // TODO: LIST
547547        bool map (Cap page, unsigned address):
548548            return ocall (page, CAP_MASTER_DIRECT | MAP, address).l == NO_ERROR
549        bool unmap (Cap page):
550            return map (page, ~0)
549551        Page mapping (void *address):
550552            icall (CAP_MASTER_DIRECT | MAPPING, Num ((unsigned)address))
551553            return get_arg ()
...... 
601603namespace Iris:
602604    inline void panic (unsigned code, char const *message = NULL):
603605        if message:
606            kdebug ("**********************************************************************\n")
607            kdebug_num (code)
608            kdebug_char ('\n')
604609            kdebug (message)
605610            kdebug_char ('\n')
606611        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_PANIC, code)
memory.ccp
2626    kdebug ("clearing page ")
2727    kdebug_num (page)
2828    kdebug ("+")
29    kdebug_num (num)
29    kdebug_num (num << PAGE_BITS)
3030    kdebug ('\n')
3131    #endif
3232    page = (page & ~0xc0000000) | 0xa0000000
...... 
3434        arch_uncache_page (page - 0x20000000 + (p << PAGE_BITS))
3535        for unsigned i = 0; i < (1 << (PAGE_BITS - 2)); ++i:
3636            // Clear page.
37            ((unsigned *)page)[i] = 0
38    if *((unsigned *)page) != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0:
37            ((unsigned *)page)[(p << PAGE_BITS - 2) + i] = 0
38    if *(unsigned *)page != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0:
39        kdebug_num ((num << (PAGE_BITS - 2)) - 1)
40        kdebug ("/")
41        kdebug_num (((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1])
42        kdebug (",")
43        kdebug_num (*(unsigned *)page)
44        kdebug ("\n")
3945        dpanic (0, "clear_page didn't work")
4046
4147#if 0
mips/arch.ccp
171171    return ((page->frame & ~0x80000000) >> 6) | flags
172172
173173bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address):
174    if address >= 0x80000000:
175        dpanic (address, "trying to map to kernel address")
176        return false
177174    if page->mapping != ~0:
178175        mem->unmap (page)
179176    if address == ~0:
180177        return true
178    if address >= 0x80000000:
179        dpanic (address, "trying to map to kernel address")
180        return false
181181    if address & ~PAGE_MASK:
182182        dpanic (address, "mapping not page-aligned")
183183        address &= PAGE_MASK
mips/interrupts.ccp
5858        cp0_set (CP0_STATUS, 0x1000ff13)
5959    else:
6060        cp0_set (CP0_STATUS, 0x0000ff13)
61    dbg_push ((unsigned)current)
62    dbg_push (current->pc)
6163    return current
6264
6365/// A TLB miss has occurred. This is the slow version. It is only used
...... 
163165    msg.arg = old_current->find_capability (old_current->arch.t[1], &msg.copy[1])
164166    msg.data[0] = Iris::Num (old_current->arch.a[0], old_current->arch.a[1])
165167    msg.data[1] = Iris::Num (old_current->arch.a[2], old_current->arch.a[3])
166    dbg_push (old_current->arch.v[0])
167    dbg_push (old_current->arch.t[0])
168    dbg_push (old_current->arch.t[1])
169    dbg_push (old_current->arch.a[0])
170    dbg_push (old_current->arch.a[1])
171    dbg_push (old_current->arch.a[2])
172    dbg_push (old_current->arch.a[3])
173    dbg_push (0xdeadbeef)
174168    target->invoke (&msg)
175    dbg_push (0xfacebeef)
176169    if do_schedule && !must_wait:
177170        // If the call was to schedule without wait, it isn't done yet.
178171        schedule ()
mips/nanonote/Makefile.arch
2929boot_sources = mips/init.cc mips/nanonote/board.cc
3030arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh devices.hh
3131boot_threads = bootinit udc
32programs = init gpio lcd bsquare ball buzzer metronome elfrun
32programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui
3333
3434all: test
3535
panic.ccp
105105    if old_current:
106106        kdebug ('@')
107107        kdebug_num (old_current->pc)
108        kdebug ("\nregisters: sp=")
109        kdebug_num (old_current->sp)
110        kdebug (" at=")
111        kdebug_num (old_current->arch.at)
112        kdebug ("\nv=")
113        kdebug_num (old_current->arch.v[0])
114        kdebug (" ")
115        kdebug_num (old_current->arch.v[1])
116        kdebug ("\na=")
117        for unsigned i = 0; i < 4; ++i:
118            kdebug_num (old_current->arch.a[i])
119            kdebug (" ")
120        kdebug ("\nt=")
121        for unsigned i = 0; i < 10; ++i:
122            kdebug_num (old_current->arch.t[i])
123            kdebug (" ")
124        kdebug ("\ns=")
125        for unsigned i = 0; i < 8; ++i:
126            kdebug_num (old_current->arch.s[i])
127            kdebug (" ")
128        kdebug ("\ngp=")
129        kdebug_num (old_current->arch.gp)
130        kdebug (" fp=")
131        kdebug_num (old_current->arch.fp)
132        kdebug (" ra=")
133        kdebug_num (old_current->arch.ra)
134        kdebug ("\nhi=")
135        kdebug_num (old_current->arch.hi)
136        kdebug (" lo=")
137        kdebug_num (old_current->arch.lo)
138        kdebug ("\nk=")
139        kdebug_num (old_current->arch.k[0])
140        kdebug (" ")
141        kdebug_num (old_current->arch.k[1])
142        kdebug ('\n')
108143    kdebug ("; ")
109144    kdebug (name)
110145    kdebug (':')
...... 
129164            if b == 32:
130165                b = 0
131166    kdebug ('\n')
167    if old_current:
168        kdebug ("Attempt to print *pc:\n")
169        unsigned page = old_current->pc & PAGE_MASK
170        unsigned start = old_current->pc & ~(4 * 4 - 1)
171        for int i = -4; i < 8; ++i:
172            kdebug_num (start + i * 4 * 4)
173            kdebug (" ==>")
174            for unsigned j = 0; j < 4; ++j:
175                kdebug (' ')
176                unsigned addr = start + (i * 4 + j) * 4
177                if (addr & PAGE_MASK) == page:
178                    kdebug_num (*(unsigned *)addr)
179                else:
180                    kdebug ("--------")
181            kdebug ('\n')
132182
133183void panic_impl (unsigned n, const char *line, char const *name, char const *message):
134184    // Stop all threads.
source/alarm.ccp
1#pypp 0
2#include <iris.hh>
3#include <ui.hh>
4
5enum Ins:
6    TOTAL_TIME
7    START
8    NUM_INS
9
10enum Outs:
11    CURRENT_TIME
12    ALARM
13    NUM_OUTS
14
15static UI <NUM_INS, NUM_OUTS> ui
16static UI <NUM_INS, NUM_OUTS>::in <unsigned> total_time
17static UI <NUM_INS, NUM_OUTS>::in_event do_start
18static UI <NUM_INS, NUM_OUTS>::out <unsigned> current_time
19static UI <NUM_INS, NUM_OUTS>::out_event do_alarm
20
21static bool ticking
22
23static void event (unsigned code):
24    switch code:
25        case TOTAL_TIME:
26            break
27        case START:
28            current_time = total_time
29            if !ticking:
30                if !current_time:
31                    do_alarm ()
32                else:
33                    ticking = true
34                    Iris::my_receiver.set_alarm (HZ)
35            break
36        default:
37            Iris::panic (0, "invalid event for alarm clock")
38
39Iris::Num start ():
40    ticking = false;
41    Iris::Cap ui_cap = Iris::my_receiver.create_capability (0)
42    ui.init (ui_cap.copy ());
43    Iris::free_cap (ui_cap)
44    total_time.init ()
45    do_start.init ()
46    current_time.init ()
47    do_alarm.init ()
48    ui.add_in (&total_time, TOTAL_TIME);
49    ui.add_in (&do_start, START);
50    ui.add_out (&current_time, CURRENT_TIME);
51    ui.add_out (&do_alarm, ALARM);
52    Iris::my_parent.init_done ()
53
54    while true:
55        Iris::wait ()
56        switch Iris::recv.protected_data.l:
57            case ~0:
58                // alarm.
59                current_time = current_time - 1
60                if !current_time:
61                    do_alarm ()
62                    ticking = false
63                else:
64                    // TODO: use rtc for scheduling an event.
65                    Iris::my_receiver.set_alarm (HZ)
66                continue
67            case 0:
68                // ui event.
69                if !ui.event (&event):
70                    // Exit request.
71                    return 0
source/ball.ccp
3737    Iris::my_parent.init_done ()
3838    int colour = 0x3f30ff
3939    framebuffer = (unsigned *)0x15000
40    Iris::Display display = Iris::my_parent.get_device <Iris::Display> (0x10000)
40    Iris::Display display = Iris::my_parent.get_capability <Iris::Display> ()
41    Iris::Caps fb = display.map_fb ((unsigned)framebuffer)
4142    int x = r, y = r, dx = 3, dy = 0
4243    Iris::Cap eof = Iris::my_receiver.create_capability (0)
4344    while true:
source/bsquare.ccp
3636    Iris::my_parent.init_done ()
3737    colour = 0xffff00
3838    framebuffer = (unsigned *)0x15000
39    Iris::Display display = Iris::my_parent.get_device <Iris::Display> (0x10001)
39    Iris::Display display = Iris::my_parent.get_capability <Iris::Display> (0x10001)
4040    int x = r, y = r, dx = 3, dy = 3
4141    Iris::Cap eof = Iris::my_receiver.create_capability (0)
4242    while true:
source/buzzer.ccp
5858    DevBuzzer buzzer
5959
6060    Iris::Buzzer dev = Iris::my_receiver.create_capability (BUZZER)
61    Iris::my_parent.provide_device <Iris::Buzzer> (dev.copy ())
61    Iris::my_parent.provide_capability <Iris::Buzzer> (dev.copy ())
6262    Iris::free_cap (dev)
6363    Iris::my_parent.init_done ()
6464    while true:
...... 
6666        if Iris::recv.protected_data.h == ~0:
6767            // Alarm.
6868            buzzer.stop ()
69            break
69            continue
7070        switch Iris::recv.protected_data.l:
7171            case BUZZER:
7272                // Buzzer device user request.
source/elfrun.ccp
6060static unsigned pages
6161static Iris::Caps pages_caps
6262static Iris::Memory mem
63static unsigned *bss_mapping
64static Iris::Page bss_page
6365
6466static Iris::Caps map_string (Iris::String data):
6567    // Get the size.
...... 
142144        bool readonly = !(shdr->sh_flags & SHF_WRITE)
143145        //bool executable = shdr->sh_flags & SHF_EXEC_INSTR
144146        if shdr->sh_type != SHT_NOBITS:
147            //kdebug ("loading ")
148            //kdebug_num (shdr->sh_addr)
149            //kdebug ("+")
150            //kdebug_num (shdr->sh_size)
151            //kdebug ("\n")
145152            unsigned file_offset = shdr->sh_offset >> PAGE_BITS
146153            if (file_offset + ((shdr->sh_size + PAGE_SIZE - 1) >> PAGE_BITS)) >= (PAGE_SIZE >> 2):
147154                kdebug ("thread size: ")
...... 
181188            if readonly:
182189                Iris::panic (0, "unwritable bss section")
183190                return Iris::Caps ()
191            //kdebug ("clearing ")
192            //kdebug_num (shdr->sh_addr)
193            //kdebug ("+")
194            //kdebug_num (shdr->sh_size)
195            //kdebug ("\n")
184196            for unsigned p = (shdr->sh_addr & PAGE_MASK); p < shdr->sh_addr + shdr->sh_size; p += PAGE_SIZE:
185197                Iris::Page page = mem.mapping ((void *)p)
186198                if Iris::recv.data[0].l == Iris::NO_ERROR:
187199                    // No error means there is a mapping.
200                    page.share (bss_page, 0)
188201                    Iris::free_cap (page)
189202                    for unsigned a = p; a < ((p + PAGE_SIZE) & PAGE_MASK); a += 4:
190203                        if a >= shdr->sh_addr + shdr->sh_size:
191204                            break
192205                        if a < shdr->sh_addr:
193206                            continue
194                        ((unsigned *)&mapping[p - shdr->sh_addr])[(a & ~PAGE_MASK) >> 2] = 0
207                        bss_mapping[(a & ~PAGE_MASK) >> 2] = 0
195208                else:
196209                    Iris::free_cap (page)
197210                    page = mem.create_page ()
...... 
202215                    if !mem.map (page, p):
203216                        Iris::panic (0, "unable to map bss page")
204217                    Iris::free_cap (page)
218    //kdebug ("start of program:\n")
219    //for unsigned i = 0; i < 0x40; i += 4:
220    // kdebug_num ((unsigned)mapping + 4 * i, 3)
221    // kdebug (" ==>")
222    // for unsigned j = 0; j < 4; j += 1:
223    // kdebug (" ")
224    // kdebug_num (((unsigned *)mapping)[i + j])
225    // kdebug ("\n")
205226    for unsigned p = 0; p < pages; ++p:
206227        Iris::my_memory.destroy (Iris::Page (slot, p))
207228    Iris::my_memory.destroy (pages_caps)
...... 
235256    kdebug ("elfrun started.\n")
236257    init_alloc ()
237258    Iris::Elfrun dev = Iris::my_receiver.create_capability (0)
238    Iris::my_parent.provide_device <Iris::Elfrun> (dev.copy ())
259    Iris::my_parent.provide_capability <Iris::Elfrun> (dev.copy ())
239260    Iris::free_cap (dev)
261    bss_mapping = (unsigned *)alloc_space (1)
262    bss_page = Iris::my_memory.create_page ()
263    Iris::my_memory.map (bss_page, (unsigned)bss_mapping)
240264
241265    while true:
242266        Iris::wait ()
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.
17enum outs:
18    CURRENT_TIME
19    ALARM
20
21enum ins:
22    TOTAL_TIME
23    START
24
25static Iris::Display display
26static Iris::Buzzer buzzer
27static unsigned *framebuffer
28
29enum PD:
30    UI
31    KBD
32
33static 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
133static 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
138static 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
143static 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
154static void beep ():
155    buzzer.beep (4 * 440, 1000, ~0)
156
157Iris::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
2323#define NUM_SLOTS 8
2424#define NUM_CAPS 32
2525
26#define SYSREQ 0x100
27
2628static unsigned _free
2729extern unsigned _end
2830
...... 
99101
100102struct Program
101103
102struct Device:
104struct Serverdevice:
103105    char *name
104106    unsigned name_len
105107    unsigned type, index
...... 
107109    Program *server
108110    Program *client
109111
112struct Clientdevice:
113    unsigned type, index
114    Serverdevice *dev
115
116static Iris::Memory top_memory
117static Iris::Directory root
118static Iris::Elfrun elfrun
119
110120struct Program:
111121    char *name
112122    unsigned name_len
...... 
114124    Iris::Caps pages
115125    Iris::Memory memory
116126    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 ()
119146
120static Iris::Memory top_memory
121static Iris::Directory root
122static Iris::Elfrun elfrun
123147static List <Program> programs
124static Iris::Cap sysreq
125static unsigned to_receive, progs
148static Serverdevice *sysreq
126149
127150static bool name_match (char const *name, unsigned name_len, Iris::String n):
128151    char nm[16]
...... 
255278    { "WDirectory", 10, Iris::WDirectory::ID },
256279    { "Filesystem", 10, Iris::Filesystem::ID },
257280    { "Stream", 6, Iris::Stream::ID },
281    { "UI", 2, Iris::UI::ID },
258282    { NULL, 0, 0 }
259283    }
260284
...... 
275299            return
276300    Iris::panic (0, "no valid type found")
277301
278static void do_run (char *&start, unsigned &maxlen, bool priv):
302static bool find_cap (char *&line, unsigned &len, Program *&server, Serverdevice *&dev):
279303    char *n
280304    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")
283307    List <Program>::Item *p
284308    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
306316
307317static void parse_line (char *&line, unsigned maxlen)
308static void include_caps (Iris::Caps caps, unsigned size):
318static void include (char const *name, unsigned name_len):
319    unsigned size
320    Iris::Caps caps = load (name, name_len, size)
309321    unsigned pages = (size + PAGE_SIZE - 1) >> PAGE_BITS
310322    char *config = alloc_space (pages)
311323    unsigned pages_slot = caps.use ()
...... 
321333    Iris::free_cap (caps)
322334    Iris::free_slot (pages_slot)
323335
336static 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
348static 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
324360static void parse_line (char *&line, unsigned maxlen):
325361    char *start = line
326362    while maxlen && *line != '\n':
...... 
333369    delspace (start, maxlen)
334370    if !maxlen:
335371        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)
355376    else if match (start, maxlen, "receive"):
356377        // receive <name> / <type> [, <index>] = <cap>
357378        char *n
...... 
364385                break
365386        if !p:
366387            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 ()
370389        find_type (start, maxlen, (*dev)->type, (*dev)->index)
371390        if !match (start, maxlen, "=") || !get_name (start, maxlen, (*dev)->name, (*dev)->name_len):
372391            Iris::panic (1, "syntax error in init.config (receive)")
373392        (*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 ()
419395    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")
423403    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>
428405        char *n
429406        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)")
432409        List <Program>::Item *p
433410        for p = programs.begin (); p; p = p->next:
434411            if string_match ((*p)->name, (*p)->name_len, n, l):
435412                break
436413        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)
439435    else:
440436        Iris::panic (0, "invalid line in init.config")
441437    delspace (start, maxlen)
...... 
449445Iris::Num start ():
450446    init_alloc ()
451447    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
454451    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")
460462    kdebug ("waiting for events.\n")
461463    while true:
462464        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")
468469            continue
470        Program *caller = (Program *)Iris::recv.protected_data.l
469471        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
470532            default:
471533                // TODO.
472534                kdebug ("child request: ")
...... 
475537                for unsigned i = 0; i < caller->name_len; ++i:
476538                    kdebug_char (caller->name[i])
477539                kdebug ("\n")
478
source/lcd.ccp
261261static Descriptor descriptor __attribute__ ((aligned (16)))
262262static bool is_on
263263
264static unsigned create (Iris::Memory mem, Iris::Caps caps):
264static unsigned create (Iris::Memory mem):
265265    unsigned physical = mem.alloc_range (pages)
266266    unsigned address = 0x15000
267267    if physical & ~PAGE_MASK:
...... 
275275        Iris::free_cap (p)
276276    return physical
277277
278static void destroy (unsigned physical, Iris::Caps caps):
278static void destroy (unsigned physical, Iris::Memory mem):
279279    unsigned address = 0x15000
280    Iris::Memory mem = caps.get (1)
281280    if physical == ~0:
282281        Iris::panic (0, "unable to destroy framebuffer with wrong cap0")
283282    if descriptor.frame == physical && is_on:
...... 
291290            mem.destroy (p)
292291            Iris::free_cap (p)
293292
294static void use (unsigned physical, Iris::Caps caps):
293static void use (unsigned physical):
295294    if physical == ~0:
296295        Iris::panic (0, "unable to use framebuffer with wrong cap0")
297296    bool was_unused = descriptor.frame == 0
...... 
304303        write_reg (BACKLIGHT1, 0x5f)
305304        #endif
306305
307static void unuse (unsigned physical, Iris::Caps caps):
306static void unuse (unsigned physical):
308307    if physical == ~0:
309308        Iris::panic (0, "unable to unuse framebuffer with wrong cap0")
310309    if descriptor.frame == physical:
...... 
323322    #endif
324323
325324    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
347325    unsigned physical = 0
348    #endif
349326    Iris::Page p = Iris::my_memory.mapping (&descriptor)
350327    unsigned paddr = p.physical_address ()
351328    physical_descriptor = paddr + ((unsigned)&descriptor & ~PAGE_MASK)
...... 
364341    #endif
365342
366343    // 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 ())
369346    Iris::free_cap (backlight)
370347
371348    // Register the display device.
372349    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 ())
374351    Iris::free_cap (display)
352
375353    Iris::my_parent.init_done ()
376354
377355    Iris::Cap eof_cb
...... 
441419                        reply.invoke ()
442420                        Iris::free_cap (reply)
443421                        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")
444463                    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.")
446465                    default:
447466                        Iris::panic (Iris::recv.data[0].l, "invalid operation for lcd")
448467                break
source/metronome.ccp
2121
2222Iris::Num start ():
2323    Iris::my_parent.init_done ()
24    Iris::Buzzer buzzer = Iris::my_parent.get_device <Iris::Buzzer> ()
25    Iris::Keyboard kbd = Iris::my_parent.get_device <Iris::Keyboard> ()
24    Iris::Buzzer buzzer = Iris::my_parent.get_capability <Iris::Buzzer> ()
25    Iris::Keyboard kbd = Iris::my_parent.get_capability <Iris::Keyboard> ()
2626    Iris::Cap key = Iris::my_receiver.create_capability (0)
2727    kbd.set_cb (key)
2828    // Frequency of the pulse train in millihertz.
source/nanonote-gpio.ccp
204204
205205    Iris::Device dev = Iris::my_receiver.create_capability (KBD_DEV)
206206    Iris::Keyboard pw = Iris::my_receiver.create_capability (PWR)
207    Iris::my_parent.provide_device <Iris::Keyboard> (dev.copy (), 0)
208    Iris::my_parent.provide_device <Iris::Keyboard> (pw.copy (), 1)
207    Iris::my_parent.provide_capability <Iris::Keyboard> (dev.copy (), 0)
208    Iris::my_parent.provide_capability <Iris::Keyboard> (pw.copy (), 1)
209209    Iris::free_cap (dev)
210210    Iris::free_cap (pw)
211211    Iris::my_parent.init_done ()
source/trendtac-gpio.ccp
265265    Pwm pwm
266266
267267    Iris::Cap c = Iris::my_receiver.create_capability (KEYBOARD)
268    Iris::my_parent.provide_device <Keyboard> (c.copy (), 0)
268    Iris::my_parent.provide_capability <Keyboard> (c.copy (), 0)
269269    Iris::free_cap (c)
270270    c = Iris::my_receiver.create_capability (TOUCHPAD)
271    Iris::my_parent.provide_device <Keyboard> (c.copy (), 1)
271    Iris::my_parent.provide_capability <Keyboard> (c.copy (), 1)
272272    Iris::free_cap (c)
273273    Iris::my_parent.init_done ()
274274
ui.hhp
1#pypp 0
2#include <iris.hh>
3#include <devices.hh>
4
5template <unsigned I, unsigned O> //
6class 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

Archive Download the corresponding diff file

Branches:
master



interactive