mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-12-28 12:20:49 +02:00
usb-booting alarm clock, with split gui
This commit is contained in:
parent
a4b5d94200
commit
8c7cac36e6
4
Makefile
4
Makefile
@ -23,7 +23,7 @@ CC = $(CROSS)gcc
|
||||
LD = $(CROSS)ld
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
headers = kernel.hh iris.hh $(arch_headers)
|
||||
headers = kernel.hh iris.hh ui.hh $(arch_headers)
|
||||
iris_sources = panic.cc data.cc alloc.cc memory.cc invoke.cc schedule.cc $(arch_iris_sources)
|
||||
BUILT_SOURCES = $(iris_sources) $(boot_sources)
|
||||
|
||||
@ -62,4 +62,4 @@ debug:
|
||||
cat $(SERIAL)
|
||||
|
||||
.PHONY: clean
|
||||
.PRECIOUS: iris.hh kernel.hh boot-programs/crt0.o
|
||||
.PRECIOUS: iris.hh kernel.hh ui.hh boot-programs/crt0.o
|
||||
|
@ -58,6 +58,9 @@ void *operator new[] (unsigned size):
|
||||
void *operator new (unsigned size):
|
||||
return new char[size]
|
||||
|
||||
static unsigned *bss_mapping
|
||||
static Iris::Page bss_page
|
||||
|
||||
// Get the initial block device and filesystem.
|
||||
static Iris::Directory receive_devices ():
|
||||
Iris::String data
|
||||
@ -65,7 +68,7 @@ static Iris::Directory receive_devices ():
|
||||
bool have_data = false, have_fs = false
|
||||
for unsigned i = 0; i < 2; ++i:
|
||||
Iris::wait ()
|
||||
if Iris::recv.data[0].l != Iris::Parent::PROVIDE_DEVICE:
|
||||
if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY:
|
||||
Iris::panic (Iris::recv.data[0].l, "Invalid bootstrap request.")
|
||||
switch Iris::recv.data[1].l:
|
||||
case Iris::String::ID:
|
||||
@ -206,13 +209,14 @@ static void run (Iris::String data, Iris::Memory parent_memory, Iris::Cap parent
|
||||
Iris::Page page = mem.mapping ((void *)p)
|
||||
if Iris::recv.data[0].l == Iris::NO_ERROR:
|
||||
// No error means there is a mapping.
|
||||
page.share (bss_page, 0)
|
||||
Iris::free_cap (page)
|
||||
for unsigned a = p; a < ((p + PAGE_SIZE) & PAGE_MASK); a += 4:
|
||||
if a >= shdr->sh_addr + shdr->sh_size:
|
||||
break
|
||||
if a < shdr->sh_addr:
|
||||
continue
|
||||
((unsigned *)&mapping[p - shdr->sh_addr])[(a & ~PAGE_MASK) >> 2] = 0
|
||||
bss_mapping[(a & ~PAGE_MASK) >> 2] = 0
|
||||
else:
|
||||
Iris::free_cap (page)
|
||||
page = mem.create_page ()
|
||||
@ -256,6 +260,10 @@ Iris::Num start ():
|
||||
Iris::schedule ()
|
||||
kdebug ("Starting bootinit\n")
|
||||
init_alloc ()
|
||||
bss_mapping = (unsigned *)alloc_space (1)
|
||||
bss_page = Iris::my_memory.create_page ()
|
||||
Iris::my_memory.map (bss_page, (unsigned)bss_mapping)
|
||||
|
||||
Iris::Memory top_memory = Iris::get_top_memory ()
|
||||
Iris::Directory root = receive_devices ()
|
||||
root.lock_ro ()
|
||||
@ -263,7 +271,7 @@ Iris::Num start ():
|
||||
Iris::Cap parent_cap = Iris::my_receiver.create_capability (0)
|
||||
run (run_string, top_memory, parent_cap)
|
||||
Iris::wait ()
|
||||
if Iris::recv.data[0].l != Iris::Parent::PROVIDE_DEVICE || Iris::recv.data[1].l != Iris::Elfrun::ID:
|
||||
if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY || Iris::recv.data[1].l != Iris::Elfrun::ID:
|
||||
Iris::panic (0, "elfrun doesn't provide correct capability")
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
Iris::Elfrun elfrun = Iris::get_arg ()
|
||||
@ -287,7 +295,7 @@ Iris::Num start ():
|
||||
while true:
|
||||
Iris::wait ()
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::Parent::GET_DEVICE:
|
||||
case Iris::Parent::GET_CAPABILITY:
|
||||
switch Iris::recv.data[1].l:
|
||||
case Iris::Directory::ID:
|
||||
if have_root:
|
||||
|
@ -573,8 +573,8 @@ Iris::Num start ():
|
||||
Iris::register_interrupt (IRQ_UDC)
|
||||
Iris::Filesystem fs = Iris::my_receiver.create_capability (FS)
|
||||
Iris::String data = Iris::my_receiver.create_capability (DATA)
|
||||
Iris::my_parent.provide_device <Iris::Filesystem> (fs.copy ())
|
||||
Iris::my_parent.provide_device <Iris::String> (data.copy ())
|
||||
Iris::my_parent.provide_capability <Iris::Filesystem> (fs.copy ())
|
||||
Iris::my_parent.provide_capability <Iris::String> (data.copy ())
|
||||
Iris::free_cap (fs)
|
||||
Iris::free_cap (data)
|
||||
unsigned state = 0
|
||||
|
38
devices.hhp
38
devices.hhp
@ -126,21 +126,21 @@ namespace Iris:
|
||||
struct Parent : public Iris::Cap:
|
||||
Parent (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
|
||||
enum request:
|
||||
GET_DEVICE = Elfrun::ID
|
||||
PROVIDE_DEVICE
|
||||
GET_CAPABILITY = Elfrun::ID
|
||||
PROVIDE_CAPABILITY
|
||||
WAIT
|
||||
GET_MEMORY
|
||||
PROVIDE_MEMORY
|
||||
INIT_DONE
|
||||
EXIT
|
||||
ID
|
||||
// Get a device handle.
|
||||
template <typename _T> _T get_device (unsigned num = 0):
|
||||
icall (Iris::Num (CAP_MASTER_DIRECT | GET_DEVICE, num), _T::ID)
|
||||
// Get a handle.
|
||||
template <typename _T> _T get_capability (unsigned num = 0):
|
||||
icall (Iris::Num (CAP_MASTER_DIRECT | GET_CAPABILITY, num), _T::ID)
|
||||
return Iris::get_arg ()
|
||||
// Provide a device handle.
|
||||
template <typename _T> void provide_device (Device dev, unsigned num = 0):
|
||||
ocall (dev, Iris::Num (CAP_MASTER_DIRECT | PROVIDE_DEVICE, num), _T::ID)
|
||||
template <typename _T> void provide_capability (Cap cap, unsigned num = 0):
|
||||
ocall (cap, Iris::Num (CAP_MASTER_DIRECT | PROVIDE_CAPABILITY, num), _T::ID)
|
||||
// Wait until a device is used by the caller again.
|
||||
template <typename _T> void wait (unsigned num = 0):
|
||||
call (Iris::Num (CAP_MASTER_DIRECT | WAIT, num), _T::ID)
|
||||
@ -200,6 +200,7 @@ namespace Iris:
|
||||
enum request:
|
||||
SET_EOF_CB = Buzzer::ID
|
||||
MAP_FB
|
||||
UNMAP_FB
|
||||
GET_INFO
|
||||
ID
|
||||
// Register an end-of-frame callback.
|
||||
@ -207,8 +208,11 @@ namespace Iris:
|
||||
void set_eof_cb (Iris::Cap cb):
|
||||
ocall (cb, CAP_MASTER_DIRECT | SET_EOF_CB)
|
||||
// Map the framebuffer into memory.
|
||||
void map_fb (unsigned address):
|
||||
call (CAP_MASTER_DIRECT | MAP_FB, address)
|
||||
Iris::Caps map_fb (unsigned address, Iris::Memory mem = Iris::my_memory, bool use = true):
|
||||
iocall (mem, Iris::Num (CAP_MASTER_DIRECT | MAP_FB, use ? 1 : 0), address)
|
||||
return Iris::get_arg ()
|
||||
void unmap_fb (Iris::Caps caps):
|
||||
ocall (caps, CAP_MASTER_DIRECT | UNMAP_FB)
|
||||
// Get information about the display.
|
||||
void get_info ():
|
||||
// TODO: Interface is to be designed.
|
||||
@ -319,7 +323,21 @@ namespace Iris:
|
||||
Iris::Num write (String s, Iris::Num size):
|
||||
return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
|
||||
|
||||
|
||||
struct UI : public Iris::Cap:
|
||||
UI (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
|
||||
enum request:
|
||||
GET_STATE = Stream::ID
|
||||
EVENT
|
||||
EXIT
|
||||
ID
|
||||
enum constant:
|
||||
INPUT = 1 << 31
|
||||
void get_state (Iris::Cap cap):
|
||||
ocall (cap, CAP_MASTER_DIRECT | GET_STATE)
|
||||
void event (unsigned code, unsigned value = 0):
|
||||
call (Iris::Num (CAP_MASTER_DIRECT | EVENT, code), value)
|
||||
void exit ():
|
||||
call (CAP_MASTER_DIRECT | EXIT)
|
||||
|
||||
// Block device interface.
|
||||
struct Block_device : public WString:
|
||||
|
41
init.config
41
init.config
@ -1,34 +1,29 @@
|
||||
# load <name> = '<filename>' load a file into memory. Don't use this after killbootthreads.
|
||||
load driver_lcd = "lcd.elf"
|
||||
#load driver_buzzer = "buzzer.elf"
|
||||
#load driver_gpio = "gpio.elf"
|
||||
load ball = "ball.elf"
|
||||
|
||||
# killbootthreads destroy bootinit, bootfs and bootstore.
|
||||
killbootthreads
|
||||
# driver <name> = '<filename>' load a file into memory to be run priviledged.
|
||||
# program <name> = '<filename>' load a file into memory to be run normally.
|
||||
driver driver_lcd = "lcd.elf"
|
||||
driver driver_buzzer = "buzzer.elf"
|
||||
driver driver_gpio = "gpio.elf"
|
||||
program alarm = "alarm.elf"
|
||||
program gui = "gui.elf"
|
||||
|
||||
# receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
|
||||
receive driver_lcd / Display = display
|
||||
receive driver_lcd / Setting = display_bright
|
||||
#receive driver_buzzer / Buzzer = buzzer
|
||||
#receive driver_gpio / Keyboard , 0 = keyboard
|
||||
#receive driver_gpio / Keyboard , 1 = sysreq
|
||||
|
||||
# driver <name> run a previously loaded program priviledged.
|
||||
driver driver_lcd
|
||||
#driver driver_buzzer
|
||||
#driver driver_gpio
|
||||
|
||||
# wait wait until all expected capabilities are received.
|
||||
wait
|
||||
receive driver_buzzer / Buzzer = buzzer
|
||||
receive driver_gpio / Keyboard , 0 = keyboard
|
||||
receive driver_gpio / Keyboard , 1 = sysreq
|
||||
receive alarm / UI = ui
|
||||
|
||||
# sysreq <cap> use a capability as the system request keyboard.
|
||||
sysreq sysreq
|
||||
|
||||
# give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
|
||||
give ball / Display = display
|
||||
give gui / UI = ui
|
||||
give gui / Display = display
|
||||
give gui / Setting = display_bright
|
||||
give gui / Buzzer = buzzer
|
||||
give gui / Keyboard = keyboard
|
||||
|
||||
# run <name> run a previously loaded program (normally).
|
||||
run ball
|
||||
# include <file> include a file as another config file.
|
||||
|
||||
# include <name> include a loaded file as another config file.
|
||||
# at end of file, the initial threads are killed and the drivers and programs are run as soon as all their dependencies are provided.
|
||||
|
12
invoke.ccp
12
invoke.ccp
@ -390,7 +390,6 @@ static void memory_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
|
||||
reply_num (0)
|
||||
|
||||
static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_data, kCapability::Context *c):
|
||||
dbg_push (__LINE__)
|
||||
kThread *thread = (kThread *)protected_data.l
|
||||
switch cmd:
|
||||
case Iris::Thread::GET_INFO & REQUEST_MASK:
|
||||
@ -441,7 +440,6 @@ static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
|
||||
*value = (*value & ~c->data[1].h) | (c->data[1].l & c->data[1].h)
|
||||
break
|
||||
case Iris::Thread::USE_SLOT & REQUEST_MASK:
|
||||
dbg_push (__LINE__)
|
||||
if c->data[1].l >= thread->slots || !c->arg.valid ():
|
||||
if c->data[1].l == 0xdeadbeef:
|
||||
bool dummy
|
||||
@ -456,26 +454,18 @@ static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
|
||||
dpanic ((unsigned)c->arg->target, "argument for USE_SLOT is not a caps")
|
||||
reply_num (Iris::ERR_INVALID_ARGUMENT)
|
||||
return
|
||||
dbg_push (__LINE__)
|
||||
unsigned slot = c->data[1].l
|
||||
dbg_push (__LINE__)
|
||||
kCaps *new_caps = (kCaps *)c->arg->protected_data.l
|
||||
dbg_push (__LINE__)
|
||||
if slot >= thread->slots:
|
||||
dpanic (0, "using invalid slot")
|
||||
return
|
||||
dbg_push (__LINE__)
|
||||
thread->unset_slot (slot)
|
||||
dbg_push (__LINE__)
|
||||
thread->slot[slot].caps = new_caps
|
||||
dbg_push (__LINE__)
|
||||
if new_caps:
|
||||
dbg_push (__LINE__)
|
||||
thread->slot[slot].next = new_caps->first_slot
|
||||
thread->slot[slot].caps = new_caps
|
||||
new_caps->first_slot.thread = thread
|
||||
new_caps->first_slot.index = slot
|
||||
dbg_push (__LINE__)
|
||||
break
|
||||
case Iris::Thread::GET_CAPS & REQUEST_MASK:
|
||||
unsigned slot = c->data[1].l
|
||||
@ -577,9 +567,7 @@ static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
|
||||
dpanic (0, "invalid priv thread operation")
|
||||
reply_num (Iris::ERR_INVALID_OPERATION)
|
||||
return
|
||||
dbg_push (__LINE__)
|
||||
reply_num (0)
|
||||
dbg_push (__LINE__)
|
||||
return
|
||||
|
||||
static void page_check_payment (kPage *page):
|
||||
|
5
iris.hhp
5
iris.hhp
@ -546,6 +546,8 @@ namespace Iris:
|
||||
// TODO: LIST
|
||||
bool map (Cap page, unsigned address):
|
||||
return ocall (page, CAP_MASTER_DIRECT | MAP, address).l == NO_ERROR
|
||||
bool unmap (Cap page):
|
||||
return map (page, ~0)
|
||||
Page mapping (void *address):
|
||||
icall (CAP_MASTER_DIRECT | MAPPING, Num ((unsigned)address))
|
||||
return get_arg ()
|
||||
@ -601,6 +603,9 @@ static void kdebug_num (unsigned n, unsigned digits = 8):
|
||||
namespace Iris:
|
||||
inline void panic (unsigned code, char const *message = NULL):
|
||||
if message:
|
||||
kdebug ("**********************************************************************\n")
|
||||
kdebug_num (code)
|
||||
kdebug_char ('\n')
|
||||
kdebug (message)
|
||||
kdebug_char ('\n')
|
||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_PANIC, code)
|
||||
|
12
memory.ccp
12
memory.ccp
@ -26,7 +26,7 @@ static void clear_page (unsigned page, unsigned num = 1):
|
||||
kdebug ("clearing page ")
|
||||
kdebug_num (page)
|
||||
kdebug ("+")
|
||||
kdebug_num (num)
|
||||
kdebug_num (num << PAGE_BITS)
|
||||
kdebug ('\n')
|
||||
#endif
|
||||
page = (page & ~0xc0000000) | 0xa0000000
|
||||
@ -34,8 +34,14 @@ static void clear_page (unsigned page, unsigned num = 1):
|
||||
arch_uncache_page (page - 0x20000000 + (p << PAGE_BITS))
|
||||
for unsigned i = 0; i < (1 << (PAGE_BITS - 2)); ++i:
|
||||
// Clear page.
|
||||
((unsigned *)page)[i] = 0
|
||||
if *((unsigned *)page) != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0:
|
||||
((unsigned *)page)[(p << PAGE_BITS - 2) + i] = 0
|
||||
if *(unsigned *)page != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0:
|
||||
kdebug_num ((num << (PAGE_BITS - 2)) - 1)
|
||||
kdebug ("/")
|
||||
kdebug_num (((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1])
|
||||
kdebug (",")
|
||||
kdebug_num (*(unsigned *)page)
|
||||
kdebug ("\n")
|
||||
dpanic (0, "clear_page didn't work")
|
||||
|
||||
#if 0
|
||||
|
@ -171,13 +171,13 @@ static unsigned make_entry_lo (kPage *page):
|
||||
return ((page->frame & ~0x80000000) >> 6) | flags
|
||||
|
||||
bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address):
|
||||
if address >= 0x80000000:
|
||||
dpanic (address, "trying to map to kernel address")
|
||||
return false
|
||||
if page->mapping != ~0:
|
||||
mem->unmap (page)
|
||||
if address == ~0:
|
||||
return true
|
||||
if address >= 0x80000000:
|
||||
dpanic (address, "trying to map to kernel address")
|
||||
return false
|
||||
if address & ~PAGE_MASK:
|
||||
dpanic (address, "mapping not page-aligned")
|
||||
address &= PAGE_MASK
|
||||
|
@ -58,6 +58,8 @@ static kThread *handle_exit ():
|
||||
cp0_set (CP0_STATUS, 0x1000ff13)
|
||||
else:
|
||||
cp0_set (CP0_STATUS, 0x0000ff13)
|
||||
dbg_push ((unsigned)current)
|
||||
dbg_push (current->pc)
|
||||
return current
|
||||
|
||||
/// A TLB miss has occurred. This is the slow version. It is only used
|
||||
@ -163,16 +165,7 @@ static void arch_invoke ():
|
||||
msg.arg = old_current->find_capability (old_current->arch.t[1], &msg.copy[1])
|
||||
msg.data[0] = Iris::Num (old_current->arch.a[0], old_current->arch.a[1])
|
||||
msg.data[1] = Iris::Num (old_current->arch.a[2], old_current->arch.a[3])
|
||||
dbg_push (old_current->arch.v[0])
|
||||
dbg_push (old_current->arch.t[0])
|
||||
dbg_push (old_current->arch.t[1])
|
||||
dbg_push (old_current->arch.a[0])
|
||||
dbg_push (old_current->arch.a[1])
|
||||
dbg_push (old_current->arch.a[2])
|
||||
dbg_push (old_current->arch.a[3])
|
||||
dbg_push (0xdeadbeef)
|
||||
target->invoke (&msg)
|
||||
dbg_push (0xfacebeef)
|
||||
if do_schedule && !must_wait:
|
||||
// If the call was to schedule without wait, it isn't done yet.
|
||||
schedule ()
|
||||
|
@ -29,7 +29,7 @@ arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||
boot_sources = mips/init.cc mips/nanonote/board.cc
|
||||
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh devices.hh
|
||||
boot_threads = bootinit udc
|
||||
programs = init gpio lcd bsquare ball buzzer metronome elfrun
|
||||
programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui
|
||||
|
||||
all: test
|
||||
|
||||
|
50
panic.ccp
50
panic.ccp
@ -105,6 +105,41 @@ static void panic_message (unsigned n, const char *line, char const *name, char
|
||||
if old_current:
|
||||
kdebug ('@')
|
||||
kdebug_num (old_current->pc)
|
||||
kdebug ("\nregisters: sp=")
|
||||
kdebug_num (old_current->sp)
|
||||
kdebug (" at=")
|
||||
kdebug_num (old_current->arch.at)
|
||||
kdebug ("\nv=")
|
||||
kdebug_num (old_current->arch.v[0])
|
||||
kdebug (" ")
|
||||
kdebug_num (old_current->arch.v[1])
|
||||
kdebug ("\na=")
|
||||
for unsigned i = 0; i < 4; ++i:
|
||||
kdebug_num (old_current->arch.a[i])
|
||||
kdebug (" ")
|
||||
kdebug ("\nt=")
|
||||
for unsigned i = 0; i < 10; ++i:
|
||||
kdebug_num (old_current->arch.t[i])
|
||||
kdebug (" ")
|
||||
kdebug ("\ns=")
|
||||
for unsigned i = 0; i < 8; ++i:
|
||||
kdebug_num (old_current->arch.s[i])
|
||||
kdebug (" ")
|
||||
kdebug ("\ngp=")
|
||||
kdebug_num (old_current->arch.gp)
|
||||
kdebug (" fp=")
|
||||
kdebug_num (old_current->arch.fp)
|
||||
kdebug (" ra=")
|
||||
kdebug_num (old_current->arch.ra)
|
||||
kdebug ("\nhi=")
|
||||
kdebug_num (old_current->arch.hi)
|
||||
kdebug (" lo=")
|
||||
kdebug_num (old_current->arch.lo)
|
||||
kdebug ("\nk=")
|
||||
kdebug_num (old_current->arch.k[0])
|
||||
kdebug (" ")
|
||||
kdebug_num (old_current->arch.k[1])
|
||||
kdebug ('\n')
|
||||
kdebug ("; ")
|
||||
kdebug (name)
|
||||
kdebug (':')
|
||||
@ -129,6 +164,21 @@ static void panic_message (unsigned n, const char *line, char const *name, char
|
||||
if b == 32:
|
||||
b = 0
|
||||
kdebug ('\n')
|
||||
if old_current:
|
||||
kdebug ("Attempt to print *pc:\n")
|
||||
unsigned page = old_current->pc & PAGE_MASK
|
||||
unsigned start = old_current->pc & ~(4 * 4 - 1)
|
||||
for int i = -4; i < 8; ++i:
|
||||
kdebug_num (start + i * 4 * 4)
|
||||
kdebug (" ==>")
|
||||
for unsigned j = 0; j < 4; ++j:
|
||||
kdebug (' ')
|
||||
unsigned addr = start + (i * 4 + j) * 4
|
||||
if (addr & PAGE_MASK) == page:
|
||||
kdebug_num (*(unsigned *)addr)
|
||||
else:
|
||||
kdebug ("--------")
|
||||
kdebug ('\n')
|
||||
|
||||
void panic_impl (unsigned n, const char *line, char const *name, char const *message):
|
||||
// Stop all threads.
|
||||
|
71
source/alarm.ccp
Normal file
71
source/alarm.ccp
Normal file
@ -0,0 +1,71 @@
|
||||
#pypp 0
|
||||
#include <iris.hh>
|
||||
#include <ui.hh>
|
||||
|
||||
enum Ins:
|
||||
TOTAL_TIME
|
||||
START
|
||||
NUM_INS
|
||||
|
||||
enum Outs:
|
||||
CURRENT_TIME
|
||||
ALARM
|
||||
NUM_OUTS
|
||||
|
||||
static UI <NUM_INS, NUM_OUTS> ui
|
||||
static UI <NUM_INS, NUM_OUTS>::in <unsigned> total_time
|
||||
static UI <NUM_INS, NUM_OUTS>::in_event do_start
|
||||
static UI <NUM_INS, NUM_OUTS>::out <unsigned> current_time
|
||||
static UI <NUM_INS, NUM_OUTS>::out_event do_alarm
|
||||
|
||||
static bool ticking
|
||||
|
||||
static void event (unsigned code):
|
||||
switch code:
|
||||
case TOTAL_TIME:
|
||||
break
|
||||
case START:
|
||||
current_time = total_time
|
||||
if !ticking:
|
||||
if !current_time:
|
||||
do_alarm ()
|
||||
else:
|
||||
ticking = true
|
||||
Iris::my_receiver.set_alarm (HZ)
|
||||
break
|
||||
default:
|
||||
Iris::panic (0, "invalid event for alarm clock")
|
||||
|
||||
Iris::Num start ():
|
||||
ticking = false;
|
||||
Iris::Cap ui_cap = Iris::my_receiver.create_capability (0)
|
||||
ui.init (ui_cap.copy ());
|
||||
Iris::free_cap (ui_cap)
|
||||
total_time.init ()
|
||||
do_start.init ()
|
||||
current_time.init ()
|
||||
do_alarm.init ()
|
||||
ui.add_in (&total_time, TOTAL_TIME);
|
||||
ui.add_in (&do_start, START);
|
||||
ui.add_out (¤t_time, CURRENT_TIME);
|
||||
ui.add_out (&do_alarm, ALARM);
|
||||
Iris::my_parent.init_done ()
|
||||
|
||||
while true:
|
||||
Iris::wait ()
|
||||
switch Iris::recv.protected_data.l:
|
||||
case ~0:
|
||||
// alarm.
|
||||
current_time = current_time - 1
|
||||
if !current_time:
|
||||
do_alarm ()
|
||||
ticking = false
|
||||
else:
|
||||
// TODO: use rtc for scheduling an event.
|
||||
Iris::my_receiver.set_alarm (HZ)
|
||||
continue
|
||||
case 0:
|
||||
// ui event.
|
||||
if !ui.event (&event):
|
||||
// Exit request.
|
||||
return 0
|
@ -37,7 +37,8 @@ Iris::Num start ():
|
||||
Iris::my_parent.init_done ()
|
||||
int colour = 0x3f30ff
|
||||
framebuffer = (unsigned *)0x15000
|
||||
Iris::Display display = Iris::my_parent.get_device <Iris::Display> (0x10000)
|
||||
Iris::Display display = Iris::my_parent.get_capability <Iris::Display> ()
|
||||
Iris::Caps fb = display.map_fb ((unsigned)framebuffer)
|
||||
int x = r, y = r, dx = 3, dy = 0
|
||||
Iris::Cap eof = Iris::my_receiver.create_capability (0)
|
||||
while true:
|
||||
|
@ -36,7 +36,7 @@ Iris::Num start ():
|
||||
Iris::my_parent.init_done ()
|
||||
colour = 0xffff00
|
||||
framebuffer = (unsigned *)0x15000
|
||||
Iris::Display display = Iris::my_parent.get_device <Iris::Display> (0x10001)
|
||||
Iris::Display display = Iris::my_parent.get_capability <Iris::Display> (0x10001)
|
||||
int x = r, y = r, dx = 3, dy = 3
|
||||
Iris::Cap eof = Iris::my_receiver.create_capability (0)
|
||||
while true:
|
||||
|
@ -58,7 +58,7 @@ Iris::Num start ():
|
||||
DevBuzzer buzzer
|
||||
|
||||
Iris::Buzzer dev = Iris::my_receiver.create_capability (BUZZER)
|
||||
Iris::my_parent.provide_device <Iris::Buzzer> (dev.copy ())
|
||||
Iris::my_parent.provide_capability <Iris::Buzzer> (dev.copy ())
|
||||
Iris::free_cap (dev)
|
||||
Iris::my_parent.init_done ()
|
||||
while true:
|
||||
@ -66,7 +66,7 @@ Iris::Num start ():
|
||||
if Iris::recv.protected_data.h == ~0:
|
||||
// Alarm.
|
||||
buzzer.stop ()
|
||||
break
|
||||
continue
|
||||
switch Iris::recv.protected_data.l:
|
||||
case BUZZER:
|
||||
// Buzzer device user request.
|
||||
|
@ -60,6 +60,8 @@ static char *mapping
|
||||
static unsigned pages
|
||||
static Iris::Caps pages_caps
|
||||
static Iris::Memory mem
|
||||
static unsigned *bss_mapping
|
||||
static Iris::Page bss_page
|
||||
|
||||
static Iris::Caps map_string (Iris::String data):
|
||||
// Get the size.
|
||||
@ -142,6 +144,11 @@ static Iris::Caps run (Iris::Caps data, Iris::Memory parent_memory, Iris::Cap pa
|
||||
bool readonly = !(shdr->sh_flags & SHF_WRITE)
|
||||
//bool executable = shdr->sh_flags & SHF_EXEC_INSTR
|
||||
if shdr->sh_type != SHT_NOBITS:
|
||||
//kdebug ("loading ")
|
||||
//kdebug_num (shdr->sh_addr)
|
||||
//kdebug ("+")
|
||||
//kdebug_num (shdr->sh_size)
|
||||
//kdebug ("\n")
|
||||
unsigned file_offset = shdr->sh_offset >> PAGE_BITS
|
||||
if (file_offset + ((shdr->sh_size + PAGE_SIZE - 1) >> PAGE_BITS)) >= (PAGE_SIZE >> 2):
|
||||
kdebug ("thread size: ")
|
||||
@ -181,17 +188,23 @@ static Iris::Caps run (Iris::Caps data, Iris::Memory parent_memory, Iris::Cap pa
|
||||
if readonly:
|
||||
Iris::panic (0, "unwritable bss section")
|
||||
return Iris::Caps ()
|
||||
//kdebug ("clearing ")
|
||||
//kdebug_num (shdr->sh_addr)
|
||||
//kdebug ("+")
|
||||
//kdebug_num (shdr->sh_size)
|
||||
//kdebug ("\n")
|
||||
for unsigned p = (shdr->sh_addr & PAGE_MASK); p < shdr->sh_addr + shdr->sh_size; p += PAGE_SIZE:
|
||||
Iris::Page page = mem.mapping ((void *)p)
|
||||
if Iris::recv.data[0].l == Iris::NO_ERROR:
|
||||
// No error means there is a mapping.
|
||||
page.share (bss_page, 0)
|
||||
Iris::free_cap (page)
|
||||
for unsigned a = p; a < ((p + PAGE_SIZE) & PAGE_MASK); a += 4:
|
||||
if a >= shdr->sh_addr + shdr->sh_size:
|
||||
break
|
||||
if a < shdr->sh_addr:
|
||||
continue
|
||||
((unsigned *)&mapping[p - shdr->sh_addr])[(a & ~PAGE_MASK) >> 2] = 0
|
||||
bss_mapping[(a & ~PAGE_MASK) >> 2] = 0
|
||||
else:
|
||||
Iris::free_cap (page)
|
||||
page = mem.create_page ()
|
||||
@ -202,6 +215,14 @@ static Iris::Caps run (Iris::Caps data, Iris::Memory parent_memory, Iris::Cap pa
|
||||
if !mem.map (page, p):
|
||||
Iris::panic (0, "unable to map bss page")
|
||||
Iris::free_cap (page)
|
||||
//kdebug ("start of program:\n")
|
||||
//for unsigned i = 0; i < 0x40; i += 4:
|
||||
// kdebug_num ((unsigned)mapping + 4 * i, 3)
|
||||
// kdebug (" ==>")
|
||||
// for unsigned j = 0; j < 4; j += 1:
|
||||
// kdebug (" ")
|
||||
// kdebug_num (((unsigned *)mapping)[i + j])
|
||||
// kdebug ("\n")
|
||||
for unsigned p = 0; p < pages; ++p:
|
||||
Iris::my_memory.destroy (Iris::Page (slot, p))
|
||||
Iris::my_memory.destroy (pages_caps)
|
||||
@ -235,8 +256,11 @@ Iris::Num start ():
|
||||
kdebug ("elfrun started.\n")
|
||||
init_alloc ()
|
||||
Iris::Elfrun dev = Iris::my_receiver.create_capability (0)
|
||||
Iris::my_parent.provide_device <Iris::Elfrun> (dev.copy ())
|
||||
Iris::my_parent.provide_capability <Iris::Elfrun> (dev.copy ())
|
||||
Iris::free_cap (dev)
|
||||
bss_mapping = (unsigned *)alloc_space (1)
|
||||
bss_page = Iris::my_memory.create_page ()
|
||||
Iris::my_memory.map (bss_page, (unsigned)bss_mapping)
|
||||
|
||||
while true:
|
||||
Iris::wait ()
|
||||
|
238
source/gui.ccp
Normal file
238
source/gui.ccp
Normal file
@ -0,0 +1,238 @@
|
||||
#pypp 0
|
||||
#include <iris.hh>
|
||||
#include <devices.hh>
|
||||
#include <keys.hh>
|
||||
|
||||
// Interface: two way, started by ui.
|
||||
|
||||
// From ui to application.
|
||||
// ~0: request reset.
|
||||
// ~1: set reply cap; send current state.
|
||||
// inum: event (with optional value) for input number num.
|
||||
|
||||
// From application to ui.
|
||||
// onum: event (with optional value) for output number num.
|
||||
|
||||
// For now, the code is hardwired to the alarm clock interface.
|
||||
enum outs:
|
||||
CURRENT_TIME
|
||||
ALARM
|
||||
|
||||
enum ins:
|
||||
TOTAL_TIME
|
||||
START
|
||||
|
||||
static Iris::Display display
|
||||
static Iris::Buzzer buzzer
|
||||
static unsigned *framebuffer
|
||||
|
||||
enum PD:
|
||||
UI
|
||||
KBD
|
||||
|
||||
static char const *chardef =
|
||||
".###.."
|
||||
"#...#."
|
||||
"#...#."
|
||||
"#...#."
|
||||
"#...#."
|
||||
"#...#."
|
||||
".###.."
|
||||
"......"
|
||||
|
||||
"..#..."
|
||||
"..#..."
|
||||
"..#..."
|
||||
"..#..."
|
||||
"..#..."
|
||||
"..#..."
|
||||
"..#..."
|
||||
"......"
|
||||
|
||||
".###.."
|
||||
"#...#."
|
||||
"....#."
|
||||
"...#.."
|
||||
"..#..."
|
||||
".#...."
|
||||
"#####."
|
||||
"......"
|
||||
|
||||
".###.."
|
||||
"#...#."
|
||||
"....#."
|
||||
"..##.."
|
||||
"....#."
|
||||
"#...#."
|
||||
".###.."
|
||||
"......"
|
||||
|
||||
"#...#."
|
||||
"#...#."
|
||||
"#...#."
|
||||
"#####."
|
||||
"....#."
|
||||
"....#."
|
||||
"....#."
|
||||
"......"
|
||||
|
||||
"#####."
|
||||
"#....."
|
||||
"####.."
|
||||
"....#."
|
||||
"....#."
|
||||
"....#."
|
||||
"####.."
|
||||
"......"
|
||||
|
||||
"....#."
|
||||
"...#.."
|
||||
"..#..."
|
||||
".###.."
|
||||
"#...#."
|
||||
"#...#."
|
||||
".###.."
|
||||
"......"
|
||||
|
||||
"#####."
|
||||
"....#."
|
||||
"...#.."
|
||||
"..#..."
|
||||
".#...."
|
||||
"#....."
|
||||
"#....."
|
||||
"......"
|
||||
|
||||
".###.."
|
||||
"#...#."
|
||||
"#...#."
|
||||
".###.."
|
||||
"#...#."
|
||||
"#...#."
|
||||
".###.."
|
||||
"......"
|
||||
|
||||
".###.."
|
||||
"#...#."
|
||||
"#...#."
|
||||
".###.."
|
||||
"..#..."
|
||||
".#...."
|
||||
"#....."
|
||||
"......"
|
||||
|
||||
"......"
|
||||
"......"
|
||||
"..#..."
|
||||
"......"
|
||||
"......"
|
||||
"..#..."
|
||||
"......"
|
||||
"......"
|
||||
|
||||
static void draw_pixel (unsigned x, unsigned y, bool set):
|
||||
for unsigned ty = 0; ty < 8; ++ty:
|
||||
for unsigned tx = 0; tx < 8; ++tx:
|
||||
framebuffer[320 * (y + ty) + x + tx] = (set ? 0xffffff : 0x000000)
|
||||
|
||||
static void draw_num (bool upper, unsigned x0, unsigned d):
|
||||
for unsigned y = 0; y < 8; ++y:
|
||||
for unsigned x = 0; x < 6; ++x:
|
||||
draw_pixel (x * 10 + 10 + x0 * 60, y * 10 + (upper ? 30 : 50 + 80), chardef[(d * 8 + y) * 6 + x] == '#')
|
||||
|
||||
static void draw_time (bool upper, unsigned time):
|
||||
unsigned min = time / 60
|
||||
time %= 60
|
||||
if min >= 100:
|
||||
min = 99
|
||||
time = 99
|
||||
draw_num (upper, 0, min / 10)
|
||||
draw_num (upper, 1, min % 10)
|
||||
draw_num (upper, 3, time / 10)
|
||||
draw_num (upper, 4, time % 10)
|
||||
|
||||
static void beep ():
|
||||
buzzer.beep (4 * 440, 1000, ~0)
|
||||
|
||||
Iris::Num start ():
|
||||
Iris::my_parent.init_done ()
|
||||
display = Iris::my_parent.get_capability <Iris::Display> ()
|
||||
Iris::Setting bright = Iris::my_parent.get_capability <Iris::Setting> ()
|
||||
Iris::Keyboard keyboard = Iris::my_parent.get_capability <Iris::Keyboard> ()
|
||||
buzzer = Iris::my_parent.get_capability <Iris::Buzzer> ()
|
||||
Iris::UI app = Iris::my_parent.get_capability <Iris::UI> ()
|
||||
Iris::Cap cb = Iris::my_receiver.create_capability (UI)
|
||||
framebuffer = (unsigned *)0x15000
|
||||
Iris::Caps fb = display.map_fb ((unsigned)framebuffer)
|
||||
bright.set (bright.get_range ())
|
||||
app.get_state (cb.copy ())
|
||||
Iris::free_cap (cb)
|
||||
cb = Iris::my_receiver.create_capability (KBD)
|
||||
keyboard.set_cb (cb.copy ())
|
||||
Iris::free_cap (cb)
|
||||
draw_num (false, 2, 10)
|
||||
draw_num (true, 2, 10)
|
||||
unsigned total_time = 0
|
||||
while true:
|
||||
Iris::wait ()
|
||||
switch Iris::recv.protected_data.l:
|
||||
case UI:
|
||||
switch Iris::recv.data[0].l:
|
||||
case CURRENT_TIME:
|
||||
draw_time (false, Iris::recv.data[1].l)
|
||||
break
|
||||
case ALARM:
|
||||
beep ()
|
||||
break
|
||||
case TOTAL_TIME | Iris::UI::INPUT:
|
||||
total_time = Iris::recv.data[1].l
|
||||
draw_time (true, total_time)
|
||||
break
|
||||
case START | Iris::UI::INPUT:
|
||||
break
|
||||
break
|
||||
case KBD:
|
||||
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
||||
break
|
||||
switch Iris::recv.data[0].l:
|
||||
case Key::VOLUME_UP:
|
||||
total_time += 60
|
||||
draw_time (true, total_time)
|
||||
app.event (TOTAL_TIME, total_time)
|
||||
break
|
||||
case Key::VOLUME_DOWN:
|
||||
if total_time < 60:
|
||||
total_time = 0
|
||||
else:
|
||||
total_time -= 60
|
||||
draw_time (true, total_time)
|
||||
app.event (TOTAL_TIME, total_time)
|
||||
break
|
||||
case Key::UP:
|
||||
total_time += 10
|
||||
draw_time (true, total_time)
|
||||
app.event (TOTAL_TIME, total_time)
|
||||
break
|
||||
case Key::DOWN:
|
||||
if total_time < 10:
|
||||
total_time = 0
|
||||
else:
|
||||
total_time -= 10
|
||||
draw_time (true, total_time)
|
||||
app.event (TOTAL_TIME, total_time)
|
||||
break
|
||||
case Key::LEFT:
|
||||
if total_time < 1:
|
||||
total_time = 0
|
||||
else:
|
||||
total_time -= 1
|
||||
draw_time (true, total_time)
|
||||
app.event (TOTAL_TIME, total_time)
|
||||
break
|
||||
case Key::RIGHT:
|
||||
total_time += 1
|
||||
draw_time (true, total_time)
|
||||
app.event (TOTAL_TIME, total_time)
|
||||
break
|
||||
case Key::ENTER:
|
||||
app.event (START)
|
309
source/init.ccp
309
source/init.ccp
@ -23,6 +23,8 @@
|
||||
#define NUM_SLOTS 8
|
||||
#define NUM_CAPS 32
|
||||
|
||||
#define SYSREQ 0x100
|
||||
|
||||
static unsigned _free
|
||||
extern unsigned _end
|
||||
|
||||
@ -99,7 +101,7 @@ struct List:
|
||||
|
||||
struct Program
|
||||
|
||||
struct Device:
|
||||
struct Serverdevice:
|
||||
char *name
|
||||
unsigned name_len
|
||||
unsigned type, index
|
||||
@ -107,6 +109,14 @@ struct Device:
|
||||
Program *server
|
||||
Program *client
|
||||
|
||||
struct Clientdevice:
|
||||
unsigned type, index
|
||||
Serverdevice *dev
|
||||
|
||||
static Iris::Memory top_memory
|
||||
static Iris::Directory root
|
||||
static Iris::Elfrun elfrun
|
||||
|
||||
struct Program:
|
||||
char *name
|
||||
unsigned name_len
|
||||
@ -114,15 +124,28 @@ struct Program:
|
||||
Iris::Caps pages
|
||||
Iris::Memory memory
|
||||
Iris::Thread thread
|
||||
List <Device> devices
|
||||
Iris::Cap waiter
|
||||
List <Serverdevice> server_devices
|
||||
List <Clientdevice> client_devices
|
||||
unsigned num_waiting
|
||||
bool priv
|
||||
void run ():
|
||||
Iris::Cap cap = Iris::my_receiver.create_capability ((unsigned)this)
|
||||
if priv:
|
||||
kdebug ("priv ")
|
||||
kdebug ("running ")
|
||||
for unsigned i = 0; i < name_len; ++i:
|
||||
kdebug_char (name[i])
|
||||
kdebug ("\n")
|
||||
Iris::Caps caps = elfrun.run_caps (top_memory, pages, cap.copy (), (size + PAGE_SIZE - 1) >> PAGE_BITS)
|
||||
Iris::free_cap (cap)
|
||||
thread = caps.get (__thread_num)
|
||||
memory = caps.get (__memory_num)
|
||||
if priv:
|
||||
thread.make_priv ()
|
||||
thread.run ()
|
||||
|
||||
static Iris::Memory top_memory
|
||||
static Iris::Directory root
|
||||
static Iris::Elfrun elfrun
|
||||
static List <Program> programs
|
||||
static Iris::Cap sysreq
|
||||
static unsigned to_receive, progs
|
||||
static Serverdevice *sysreq
|
||||
|
||||
static bool name_match (char const *name, unsigned name_len, Iris::String n):
|
||||
char nm[16]
|
||||
@ -255,6 +278,7 @@ static Type types[] = {
|
||||
{ "WDirectory", 10, Iris::WDirectory::ID },
|
||||
{ "Filesystem", 10, Iris::Filesystem::ID },
|
||||
{ "Stream", 6, Iris::Stream::ID },
|
||||
{ "UI", 2, Iris::UI::ID },
|
||||
{ NULL, 0, 0 }
|
||||
}
|
||||
|
||||
@ -275,37 +299,25 @@ static void find_type (char *&line, unsigned &len, unsigned &type, unsigned &ind
|
||||
return
|
||||
Iris::panic (0, "no valid type found")
|
||||
|
||||
static void do_run (char *&start, unsigned &maxlen, bool priv):
|
||||
static bool find_cap (char *&line, unsigned &len, Program *&server, Serverdevice *&dev):
|
||||
char *n
|
||||
unsigned l
|
||||
if !get_name (start, maxlen, n, l):
|
||||
Iris::panic (0, "syntax error in init.config (driver)")
|
||||
if !get_name (line, len, n, l):
|
||||
Iris::panic (0, "no capability name found in init.config")
|
||||
List <Program>::Item *p
|
||||
for p = programs.begin (); p; p = p->next:
|
||||
if string_match ((*p)->name, (*p)->name_len, n, l):
|
||||
break
|
||||
if !p:
|
||||
Iris::panic (0, "program not found for driver")
|
||||
Iris::Cap cap = Iris::my_receiver.create_capability ((unsigned)&**p)
|
||||
if priv:
|
||||
kdebug ("priv ")
|
||||
kdebug ("running ")
|
||||
for unsigned i = 0; i < (*p)->name_len; ++i:
|
||||
kdebug_char ((*p)->name[i])
|
||||
kdebug ("\n")
|
||||
Iris::Caps caps = elfrun.run_caps (top_memory, (*p)->pages, cap.copy (), ((*p)->size + PAGE_SIZE - 1) >> PAGE_BITS)
|
||||
Iris::free_cap (cap)
|
||||
(*p)->thread = caps.get (__thread_num)
|
||||
(*p)->memory = caps.get (__memory_num)
|
||||
if priv:
|
||||
(*p)->thread.make_priv ()
|
||||
(*p)->thread.run ()
|
||||
// TODO: pass arguments.
|
||||
start += maxlen
|
||||
maxlen = 0
|
||||
List <Serverdevice>::Item *d
|
||||
for d = (*p)->server_devices.begin (); d; d = d->next:
|
||||
if string_match (n, l, (*d)->name, (*d)->name_len):
|
||||
server = &**p
|
||||
dev = &**d
|
||||
return true
|
||||
return false
|
||||
|
||||
static void parse_line (char *&line, unsigned maxlen)
|
||||
static void include_caps (Iris::Caps caps, unsigned size):
|
||||
static void include (char const *name, unsigned name_len):
|
||||
unsigned size
|
||||
Iris::Caps caps = load (name, name_len, size)
|
||||
unsigned pages = (size + PAGE_SIZE - 1) >> PAGE_BITS
|
||||
char *config = alloc_space (pages)
|
||||
unsigned pages_slot = caps.use ()
|
||||
@ -321,6 +333,30 @@ static void include_caps (Iris::Caps caps, unsigned size):
|
||||
Iris::free_cap (caps)
|
||||
Iris::free_slot (pages_slot)
|
||||
|
||||
static char *get_filename (char *&line, unsigned &maxlen, unsigned &len):
|
||||
char q = *line++
|
||||
--maxlen
|
||||
len = 0
|
||||
while maxlen && *line != q:
|
||||
++line
|
||||
--maxlen
|
||||
++len
|
||||
if !maxlen:
|
||||
Iris::panic (0, "no closing quote in init.config")
|
||||
return line - len
|
||||
|
||||
static void do_load (char *&line, unsigned &maxlen, bool priv):
|
||||
Program *p = &**programs.insert ()
|
||||
if !get_name (line, maxlen, p->name, p->name_len) || !match (line, maxlen, "=") || !maxlen:
|
||||
Iris::panic (0, "syntax error in init.config (load)")
|
||||
unsigned l
|
||||
char *n = get_filename (line, maxlen, l)
|
||||
p->pages = load (n, l, p->size)
|
||||
p->priv = priv
|
||||
p->num_waiting = 0
|
||||
++line
|
||||
--maxlen
|
||||
|
||||
static void parse_line (char *&line, unsigned maxlen):
|
||||
char *start = line
|
||||
while maxlen && *line != '\n':
|
||||
@ -333,25 +369,10 @@ static void parse_line (char *&line, unsigned maxlen):
|
||||
delspace (start, maxlen)
|
||||
if !maxlen:
|
||||
return
|
||||
if match (start, maxlen, "load"):
|
||||
Program *p = &**programs.insert ()
|
||||
if !get_name (start, maxlen, p->name, p->name_len) || !match (start, maxlen, "=") || !maxlen:
|
||||
Iris::panic (0, "syntax error in init.config (load)")
|
||||
char q = *start++
|
||||
--maxlen
|
||||
unsigned len = 0
|
||||
while maxlen && *start != q:
|
||||
++start
|
||||
--maxlen
|
||||
++len
|
||||
if !maxlen:
|
||||
Iris::panic (0, "no closing quote in init.config")
|
||||
p->pages = load (start - len, len, p->size)
|
||||
p->waiter = Iris::Cap ()
|
||||
++start
|
||||
--maxlen
|
||||
else if match (start, maxlen, "killbootthreads"):
|
||||
Iris::my_parent.init_done ()
|
||||
if match (start, maxlen, "program"):
|
||||
do_load (start, maxlen, false)
|
||||
else if match (start, maxlen, "driver"):
|
||||
do_load (start, maxlen, true)
|
||||
else if match (start, maxlen, "receive"):
|
||||
// receive <name> / <type> [, <index>] = <cap>
|
||||
char *n
|
||||
@ -364,78 +385,53 @@ static void parse_line (char *&line, unsigned maxlen):
|
||||
break
|
||||
if !p:
|
||||
Iris::panic (0, "program not found for receive")
|
||||
if !(*p)->devices.begin ():
|
||||
++progs
|
||||
List <Device>::Item *dev = (*p)->devices.insert ()
|
||||
List <Serverdevice>::Item *dev = (*p)->server_devices.insert ()
|
||||
find_type (start, maxlen, (*dev)->type, (*dev)->index)
|
||||
if !match (start, maxlen, "=") || !get_name (start, maxlen, (*dev)->name, (*dev)->name_len):
|
||||
Iris::panic (1, "syntax error in init.config (receive)")
|
||||
(*dev)->server = &**p
|
||||
++to_receive
|
||||
else if match (start, maxlen, "driver"):
|
||||
do_run (start, maxlen, true)
|
||||
else if match (start, maxlen, "run"):
|
||||
do_run (start, maxlen, false)
|
||||
else if match (start, maxlen, "wait"):
|
||||
kdebug ("waiting for device registration\n")
|
||||
while progs:
|
||||
Iris::wait ()
|
||||
Program *caller = (Program *)Iris::recv.protected_data.l
|
||||
if !caller:
|
||||
Iris::panic (0, "bug in init: no caller")
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::Parent::PROVIDE_DEVICE:
|
||||
if Iris::recv.data[1].h != 0:
|
||||
kdebug ("init: too high device provided\n")
|
||||
continue
|
||||
unsigned type = Iris::recv.data[1].l
|
||||
unsigned index = Iris::recv.data[0].h
|
||||
List <Device>::Item *d
|
||||
for d = caller->devices.begin (); d; d = d->next:
|
||||
if (*d)->type == type && (*d)->index == index:
|
||||
break
|
||||
if !d:
|
||||
Iris::panic (0, "unregistered device provided")
|
||||
(*d)->cap = Iris::get_arg ()
|
||||
Iris::recv.reply.invoke ()
|
||||
--to_receive
|
||||
break
|
||||
case Iris::Parent::INIT_DONE:
|
||||
if caller->waiter.code != Iris::Cap ().code:
|
||||
Iris::panic (0, "caller was already waiting")
|
||||
caller->waiter = Iris::get_reply ()
|
||||
--progs
|
||||
break
|
||||
default:
|
||||
Iris::panic (0, "unexpected request to init")
|
||||
if to_receive:
|
||||
Iris::panic (to_receive, "not all expected devices were registered")
|
||||
for List <Program>::Item *p = programs.begin (); p; p = p->next:
|
||||
if (*p)->waiter.code != Iris::Cap ().code:
|
||||
(*p)->waiter.invoke ()
|
||||
Iris::free_cap ((*p)->waiter)
|
||||
(*p)->waiter = Iris::Cap ()
|
||||
kdebug ("got all devices\n")
|
||||
(*dev)->client = NULL
|
||||
(*dev)->cap = Iris::Cap ()
|
||||
else if match (start, maxlen, "sysreq"):
|
||||
// TODO
|
||||
start += maxlen
|
||||
maxlen = 0
|
||||
Program *server
|
||||
if sysreq:
|
||||
Iris::panic (0, "double registration of sysreq")
|
||||
if !find_cap (start, maxlen, server, sysreq):
|
||||
Iris::panic (0, "capability not found for sysreq")
|
||||
if sysreq->type != Iris::Keyboard::ID:
|
||||
kdebug ("capability for sysreq is not a keyboard\n")
|
||||
else if match (start, maxlen, "give"):
|
||||
// TODO
|
||||
start += maxlen
|
||||
maxlen = 0
|
||||
else if match (start, maxlen, "include"):
|
||||
// give <name> / <type> [, <index>] = <cap>
|
||||
char *n
|
||||
unsigned l
|
||||
if !get_name (start, maxlen, n, l):
|
||||
Iris::panic (0, "syntax error in init.config (include)")
|
||||
if !get_name (start, maxlen, n, l) || !match (start, maxlen, "/") || !maxlen:
|
||||
Iris::panic (0, "syntax error in init.config (give)")
|
||||
List <Program>::Item *p
|
||||
for p = programs.begin (); p; p = p->next:
|
||||
if string_match ((*p)->name, (*p)->name_len, n, l):
|
||||
break
|
||||
if !p:
|
||||
Iris::panic (0, "file not found for include")
|
||||
include_caps ((*p)->pages, (*p)->size)
|
||||
Iris::panic (0, "program not found for give")
|
||||
List <Clientdevice>::Item *d = (*p)->client_devices.insert ()
|
||||
find_type (start, maxlen, (*d)->type, (*d)->index)
|
||||
if !match (start, maxlen, "="):
|
||||
Iris::panic (1, "syntax error in init.config (give)")
|
||||
Program *server
|
||||
if !find_cap (start, maxlen, server, (*d)->dev):
|
||||
Iris::panic (0, "capability not found for give")
|
||||
if (*d)->dev->type != (*d)->type:
|
||||
kdebug ("capability type mismatch for give\n")
|
||||
if (*d)->dev->client:
|
||||
Iris::panic (0, "capability given out twice")
|
||||
(*d)->dev->client = &**p
|
||||
++(*p)->num_waiting
|
||||
kdebug ("registered give device: ")
|
||||
kdebug_num ((*d)->type)
|
||||
kdebug ("\n")
|
||||
else if match (start, maxlen, "include"):
|
||||
unsigned name_len
|
||||
char *name = get_filename (line, maxlen, name_len)
|
||||
include (name, name_len)
|
||||
else:
|
||||
Iris::panic (0, "invalid line in init.config")
|
||||
delspace (start, maxlen)
|
||||
@ -449,24 +445,90 @@ static void parse_line (char *&line, unsigned maxlen):
|
||||
Iris::Num start ():
|
||||
init_alloc ()
|
||||
programs.init ()
|
||||
root = Iris::my_parent.get_device <Iris::Directory> ()
|
||||
elfrun = Iris::my_parent.get_device <Iris::Elfrun> ()
|
||||
root = Iris::my_parent.get_capability <Iris::Directory> ()
|
||||
elfrun = Iris::my_parent.get_capability <Iris::Elfrun> ()
|
||||
sysreq = NULL
|
||||
top_memory = Iris::get_top_memory ()
|
||||
to_receive = 0
|
||||
progs = 0
|
||||
unsigned config_size
|
||||
Iris::Caps config_pages = load ("init.config", 12, config_size)
|
||||
include_caps (config_pages, config_size)
|
||||
include ("init.config", 12)
|
||||
kdebug ("killing boot threads\n")
|
||||
Iris::my_parent.init_done ()
|
||||
for List <Program>::Item *p = programs.begin (); p; p = p->next:
|
||||
if !(*p)->num_waiting:
|
||||
(*p)->run ()
|
||||
if !sysreq:
|
||||
Iris::panic (0, "sysreq not registered")
|
||||
if sysreq->client:
|
||||
Iris::panic (0, "sysreq set to reserved capability")
|
||||
kdebug ("waiting for events.\n")
|
||||
while true:
|
||||
Iris::wait ()
|
||||
Program *caller = (Program *)Iris::recv.protected_data.l
|
||||
if !caller:
|
||||
// System request.
|
||||
// TODO.
|
||||
kdebug ("system request\n")
|
||||
if Iris::recv.protected_data.l == SYSREQ:
|
||||
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
||||
continue
|
||||
kdebug ("sysreq event\n")
|
||||
continue
|
||||
Program *caller = (Program *)Iris::recv.protected_data.l
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::Parent::GET_CAPABILITY:
|
||||
unsigned index = Iris::recv.data[0].h
|
||||
unsigned type = Iris::recv.data[1].l
|
||||
if Iris::recv.data[1].h:
|
||||
Iris::panic (Iris::recv.data[1].h, "high device requested")
|
||||
//kdebug ("requested device ")
|
||||
//kdebug_num (type)
|
||||
//kdebug (":")
|
||||
//kdebug_num (index)
|
||||
//kdebug ("\n")
|
||||
List <Clientdevice>::Item *d
|
||||
for d = caller->client_devices.begin (); d; d = d->next:
|
||||
//kdebug ("checking ")
|
||||
//kdebug_num ((*d)->type)
|
||||
//kdebug (":")
|
||||
//kdebug_num ((*d)->index)
|
||||
//kdebug ("\n")
|
||||
if (*d)->type == type && (*d)->index == index:
|
||||
break
|
||||
if !d:
|
||||
Iris::panic (type, "unregistered device requested")
|
||||
Iris::recv.reply.invoke (0, 0, (*d)->dev->cap)
|
||||
kdebug ("given device ")
|
||||
kdebug_num (type)
|
||||
kdebug (":")
|
||||
kdebug_num (index)
|
||||
kdebug ("\n")
|
||||
break
|
||||
case Iris::Parent::PROVIDE_CAPABILITY:
|
||||
if Iris::recv.data[1].h != 0:
|
||||
kdebug ("init: too high device provided\n")
|
||||
continue
|
||||
unsigned type = Iris::recv.data[1].l
|
||||
unsigned index = Iris::recv.data[0].h
|
||||
List <Serverdevice>::Item *d
|
||||
for d = caller->server_devices.begin (); d; d = d->next:
|
||||
if (*d)->type == type && (*d)->index == index:
|
||||
break
|
||||
if !d:
|
||||
Iris::panic (0, "unregistered device provided")
|
||||
(*d)->cap = Iris::get_arg ()
|
||||
Iris::recv.reply.invoke ()
|
||||
if (*d)->client:
|
||||
if !--(*d)->client->num_waiting:
|
||||
(*d)->client->run ()
|
||||
kdebug ("provided ")
|
||||
kdebug_num ((*d)->type)
|
||||
kdebug (":")
|
||||
kdebug_num ((*d)->index)
|
||||
kdebug ("\n")
|
||||
break
|
||||
case Iris::Parent::INIT_DONE:
|
||||
kdebug ("init done\n")
|
||||
Iris::recv.reply.invoke ()
|
||||
if caller == sysreq->server:
|
||||
Iris::Cap cap = Iris::my_receiver.create_capability (SYSREQ)
|
||||
Iris::Keyboard (sysreq->cap).set_cb (cap.copy ())
|
||||
Iris::free_cap (cap)
|
||||
kdebug ("registered sysreq\n")
|
||||
break
|
||||
default:
|
||||
// TODO.
|
||||
kdebug ("child request: ")
|
||||
@ -475,4 +537,3 @@ Iris::Num start ():
|
||||
for unsigned i = 0; i < caller->name_len; ++i:
|
||||
kdebug_char (caller->name[i])
|
||||
kdebug ("\n")
|
||||
|
||||
|
@ -261,7 +261,7 @@ static unsigned pages
|
||||
static Descriptor descriptor __attribute__ ((aligned (16)))
|
||||
static bool is_on
|
||||
|
||||
static unsigned create (Iris::Memory mem, Iris::Caps caps):
|
||||
static unsigned create (Iris::Memory mem):
|
||||
unsigned physical = mem.alloc_range (pages)
|
||||
unsigned address = 0x15000
|
||||
if physical & ~PAGE_MASK:
|
||||
@ -275,9 +275,8 @@ static unsigned create (Iris::Memory mem, Iris::Caps caps):
|
||||
Iris::free_cap (p)
|
||||
return physical
|
||||
|
||||
static void destroy (unsigned physical, Iris::Caps caps):
|
||||
static void destroy (unsigned physical, Iris::Memory mem):
|
||||
unsigned address = 0x15000
|
||||
Iris::Memory mem = caps.get (1)
|
||||
if physical == ~0:
|
||||
Iris::panic (0, "unable to destroy framebuffer with wrong cap0")
|
||||
if descriptor.frame == physical && is_on:
|
||||
@ -291,7 +290,7 @@ static void destroy (unsigned physical, Iris::Caps caps):
|
||||
mem.destroy (p)
|
||||
Iris::free_cap (p)
|
||||
|
||||
static void use (unsigned physical, Iris::Caps caps):
|
||||
static void use (unsigned physical):
|
||||
if physical == ~0:
|
||||
Iris::panic (0, "unable to use framebuffer with wrong cap0")
|
||||
bool was_unused = descriptor.frame == 0
|
||||
@ -304,7 +303,7 @@ static void use (unsigned physical, Iris::Caps caps):
|
||||
write_reg (BACKLIGHT1, 0x5f)
|
||||
#endif
|
||||
|
||||
static void unuse (unsigned physical, Iris::Caps caps):
|
||||
static void unuse (unsigned physical):
|
||||
if physical == ~0:
|
||||
Iris::panic (0, "unable to unuse framebuffer with wrong cap0")
|
||||
if descriptor.frame == physical:
|
||||
@ -323,29 +322,7 @@ Iris::Num start ():
|
||||
#endif
|
||||
|
||||
pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
|
||||
#if 0
|
||||
unsigned physical = Iris::my_memory.alloc_range (pages)
|
||||
assert (physical & PAGE_MASK && ~physical)
|
||||
for unsigned i = 0; i < pages; ++i:
|
||||
Iris::Page p = Iris::my_memory.create_page ()
|
||||
p.alloc_physical (physical + (i << PAGE_BITS), false, true)
|
||||
Iris::my_memory.map (p, (unsigned)LCD_FRAMEBUFFER_BASE + (i << PAGE_BITS))
|
||||
Iris::free_cap (p)
|
||||
for unsigned y = 0; y < v; ++y:
|
||||
for unsigned x = 0; x < h; ++x:
|
||||
unsigned r = spot (x, y, 100, 160)
|
||||
unsigned g = spot (x, y, 160, 60)
|
||||
unsigned b = spot (x, y, 220, 160)
|
||||
#if defined (TRENDTAC)
|
||||
LCD_FRAMEBUFFER_BASE[y * h + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)
|
||||
#elif defined (NANONOTE)
|
||||
LCD_FRAMEBUFFER_BASE[y * h + x] = (r << 16) | (g << 8) | b
|
||||
#else
|
||||
#error "Define your framebuffer format."
|
||||
#endif
|
||||
#else
|
||||
unsigned physical = 0
|
||||
#endif
|
||||
Iris::Page p = Iris::my_memory.mapping (&descriptor)
|
||||
unsigned paddr = p.physical_address ()
|
||||
physical_descriptor = paddr + ((unsigned)&descriptor & ~PAGE_MASK)
|
||||
@ -364,14 +341,15 @@ Iris::Num start ():
|
||||
#endif
|
||||
|
||||
// Register the backlight device.
|
||||
Iris::Cap backlight = Iris::my_receiver.create_capability (BACKLIGHT)
|
||||
Iris::my_parent.provide_device <Iris::Setting> (backlight.copy ())
|
||||
Iris::Setting backlight = Iris::my_receiver.create_capability (BACKLIGHT)
|
||||
Iris::my_parent.provide_capability <Iris::Setting> (backlight.copy ())
|
||||
Iris::free_cap (backlight)
|
||||
|
||||
// Register the display device.
|
||||
Iris::Display display = Iris::my_receiver.create_capability (LCD)
|
||||
Iris::my_parent.provide_device <Iris::Display> (display.copy ())
|
||||
Iris::my_parent.provide_capability <Iris::Display> (display.copy ())
|
||||
Iris::free_cap (display)
|
||||
|
||||
Iris::my_parent.init_done ()
|
||||
|
||||
Iris::Cap eof_cb
|
||||
@ -441,8 +419,49 @@ Iris::Num start ():
|
||||
reply.invoke ()
|
||||
Iris::free_cap (reply)
|
||||
break
|
||||
case Iris::Display::MAP_FB:
|
||||
unsigned addr = Iris::recv.data[1].l
|
||||
unsigned use = Iris::recv.data[0].h
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
Iris::Memory mem = Iris::get_arg ()
|
||||
unsigned physical = mem.alloc_range (pages)
|
||||
assert (physical & PAGE_MASK && ~physical)
|
||||
Iris::Caps ret = mem.create_caps (pages / 63 + 1)
|
||||
unsigned slot = ret.use ()
|
||||
for unsigned c = 0; c < pages / 63 + 1; ++c:
|
||||
Iris::Caps caps (Iris::Cap (slot, c))
|
||||
unsigned num = pages - 63 * c >= 63 ? 63 : pages - 63 * c
|
||||
Iris::set_recv_arg (caps)
|
||||
mem.create_caps (num)
|
||||
unsigned slot2 = caps.use ()
|
||||
for unsigned i = 0; i < num; ++i:
|
||||
Iris::Page p = Iris::Cap (slot2, i)
|
||||
Iris::set_recv_arg (p)
|
||||
mem.create_page ()
|
||||
p.alloc_physical (physical + ((63 * c + i) << PAGE_BITS), false, true)
|
||||
mem.map (p, addr + ((63 * c + i) << PAGE_BITS))
|
||||
Iris::free_slot (slot2)
|
||||
Iris::free_slot (slot)
|
||||
reply.invoke (0, 0, ret.copy ())
|
||||
Iris::free_cap (ret)
|
||||
Iris::free_cap (mem)
|
||||
Iris::free_cap (reply)
|
||||
if !use:
|
||||
break
|
||||
bool was_unused = descriptor.frame == 0
|
||||
descriptor.frame = physical
|
||||
unsigned dptr = (unsigned)&descriptor
|
||||
__asm__ volatile ("lw $a0, %0\ncache 0x15, 0($a0)" :: "m"(dptr) : "memory", "a0")
|
||||
if was_unused && is_on:
|
||||
lcd_set_ena ()
|
||||
#ifdef NANONOTE:
|
||||
write_reg (BACKLIGHT1, 0x5f)
|
||||
#endif
|
||||
break
|
||||
case Iris::Display::UNMAP_FB:
|
||||
Iris::panic (0, "unmap_fb isn't implemented yet")
|
||||
case Iris::Display::GET_INFO:
|
||||
Iris::panic (0, "get_info isn't defined yet.")
|
||||
Iris::panic (0, "get_info isn't implemented yet.")
|
||||
default:
|
||||
Iris::panic (Iris::recv.data[0].l, "invalid operation for lcd")
|
||||
break
|
||||
|
@ -21,8 +21,8 @@
|
||||
|
||||
Iris::Num start ():
|
||||
Iris::my_parent.init_done ()
|
||||
Iris::Buzzer buzzer = Iris::my_parent.get_device <Iris::Buzzer> ()
|
||||
Iris::Keyboard kbd = Iris::my_parent.get_device <Iris::Keyboard> ()
|
||||
Iris::Buzzer buzzer = Iris::my_parent.get_capability <Iris::Buzzer> ()
|
||||
Iris::Keyboard kbd = Iris::my_parent.get_capability <Iris::Keyboard> ()
|
||||
Iris::Cap key = Iris::my_receiver.create_capability (0)
|
||||
kbd.set_cb (key)
|
||||
// Frequency of the pulse train in millihertz.
|
||||
|
@ -204,8 +204,8 @@ Iris::Num start ():
|
||||
|
||||
Iris::Device dev = Iris::my_receiver.create_capability (KBD_DEV)
|
||||
Iris::Keyboard pw = Iris::my_receiver.create_capability (PWR)
|
||||
Iris::my_parent.provide_device <Iris::Keyboard> (dev.copy (), 0)
|
||||
Iris::my_parent.provide_device <Iris::Keyboard> (pw.copy (), 1)
|
||||
Iris::my_parent.provide_capability <Iris::Keyboard> (dev.copy (), 0)
|
||||
Iris::my_parent.provide_capability <Iris::Keyboard> (pw.copy (), 1)
|
||||
Iris::free_cap (dev)
|
||||
Iris::free_cap (pw)
|
||||
Iris::my_parent.init_done ()
|
||||
|
@ -265,10 +265,10 @@ Iris::Num start ():
|
||||
Pwm pwm
|
||||
|
||||
Iris::Cap c = Iris::my_receiver.create_capability (KEYBOARD)
|
||||
Iris::my_parent.provide_device <Keyboard> (c.copy (), 0)
|
||||
Iris::my_parent.provide_capability <Keyboard> (c.copy (), 0)
|
||||
Iris::free_cap (c)
|
||||
c = Iris::my_receiver.create_capability (TOUCHPAD)
|
||||
Iris::my_parent.provide_device <Keyboard> (c.copy (), 1)
|
||||
Iris::my_parent.provide_capability <Keyboard> (c.copy (), 1)
|
||||
Iris::free_cap (c)
|
||||
Iris::my_parent.init_done ()
|
||||
|
||||
|
116
ui.hhp
Normal file
116
ui.hhp
Normal file
@ -0,0 +1,116 @@
|
||||
#pypp 0
|
||||
#include <iris.hh>
|
||||
#include <devices.hh>
|
||||
|
||||
template <unsigned I, unsigned O> //
|
||||
class UI:
|
||||
struct in_base:
|
||||
UI <I, O> *ui
|
||||
unsigned my_index
|
||||
void (*handle) (in_base *self, void (*cb)(unsigned))
|
||||
void (*send) (in_base *self, Iris::Cap c)
|
||||
in_base () : ui (NULL), my_index (0), handle (NULL), send (NULL):
|
||||
struct out_base:
|
||||
UI <I, O> *ui
|
||||
unsigned my_index
|
||||
void (*send) (out_base *self, Iris::Cap c)
|
||||
out_base () : ui (NULL), my_index (0), send (NULL):
|
||||
|
||||
public:
|
||||
|
||||
void init (Iris::Cap my_cap):
|
||||
Iris::my_parent.provide_capability <Iris::UI> (my_cap)
|
||||
template <typename _T> //
|
||||
class in : public in_base:
|
||||
friend class UI <I, O>
|
||||
_T my_data
|
||||
static void send_impl (in_base *self, Iris::Cap c):
|
||||
c.invoke (self->my_index | Iris::UI::INPUT, reinterpret_cast <in <_T> *> (self)->my_data)
|
||||
static void handle_impl (in_base *self, void (*cb)(unsigned)):
|
||||
in *me = reinterpret_cast <in *> (self)
|
||||
if me->my_data == Iris::recv.data[1].l:
|
||||
return
|
||||
me->my_data = Iris::recv.data[1].l
|
||||
cb (me->my_index)
|
||||
public:
|
||||
void init ():
|
||||
this->send = &send_impl
|
||||
this->handle = &handle_impl
|
||||
operator _T () const:
|
||||
return my_data
|
||||
class in_event : public in_base:
|
||||
friend class UI <I, O>
|
||||
static void send_impl (in_base *self, Iris::Cap c):
|
||||
c.invoke (self->my_index | Iris::UI::INPUT)
|
||||
static void handle_impl (in_base *self, void (*cb)(unsigned)):
|
||||
cb (self->my_index)
|
||||
public:
|
||||
void init ():
|
||||
this->send = &send_impl
|
||||
this->handle = &handle_impl
|
||||
template <typename _T> //
|
||||
class out : public out_base:
|
||||
friend class UI <I, O>
|
||||
_T my_data
|
||||
static void send_impl (out_base *self, Iris::Cap c):
|
||||
c.invoke (self->my_index, reinterpret_cast <out <_T> *> (self)->my_data)
|
||||
public:
|
||||
void init ():
|
||||
this->send = &send_impl
|
||||
out <_T> &operator= (_T const &t):
|
||||
if !this->ui || my_data == t:
|
||||
return *this
|
||||
my_data = t
|
||||
send_impl (this, this->ui->cap)
|
||||
return *this
|
||||
operator _T () const:
|
||||
return my_data
|
||||
class out_event : public out_base:
|
||||
friend class UI <I, O>
|
||||
public:
|
||||
static void send_impl (out_base *self, Iris::Cap c):
|
||||
// Don't send an event. This is only for listing the state.
|
||||
void operator() ():
|
||||
if !this->ui:
|
||||
return
|
||||
this->ui->cap.invoke (this->my_index)
|
||||
void init ():
|
||||
this->send = &send_impl
|
||||
void add_in (in_base *obj, unsigned code):
|
||||
ins[code] = obj
|
||||
obj->ui = this
|
||||
obj->my_index = code
|
||||
void add_out (out_base *obj, unsigned code):
|
||||
outs[code] = obj
|
||||
obj->ui = this
|
||||
obj->my_index = code
|
||||
bool event (void (*cb)(unsigned)):
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::UI::EXIT:
|
||||
Iris::recv.reply.invoke ()
|
||||
return false
|
||||
case Iris::UI::GET_STATE:
|
||||
if cap.code != CAP_NONE:
|
||||
Iris::free_cap (cap)
|
||||
cap = Iris::get_arg ()
|
||||
Iris::recv.reply.invoke ()
|
||||
for unsigned i = 0; i < I; ++i:
|
||||
ins[i]->send (ins[i], cap)
|
||||
for unsigned i = 0; i < O; ++i:
|
||||
outs[i]->send (outs[i], cap)
|
||||
break
|
||||
case Iris::UI::EVENT:
|
||||
Iris::Cap r = Iris::get_reply ()
|
||||
if Iris::recv.data[0].h >= I:
|
||||
Iris::panic (Iris::recv.data[0].h, "invalid input requested by ui")
|
||||
ins[Iris::recv.data[0].h]->handle (ins[Iris::recv.data[0].h], cb)
|
||||
r.invoke ()
|
||||
Iris::free_cap (r)
|
||||
break
|
||||
default:
|
||||
Iris::panic (Iris::recv.data[0].l, "invalid request for ui")
|
||||
return true
|
||||
private:
|
||||
in_base *ins[I]
|
||||
out_base *outs[O]
|
||||
Iris::Cap cap
|
Loading…
Reference in New Issue
Block a user