1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-06-28 18:52:02 +03:00

improve init; make destroy simpler

This commit is contained in:
Bas Wijnen 2010-05-03 16:46:14 +02:00
parent 12bfb320f7
commit c8f7b1c678
6 changed files with 138 additions and 80 deletions

View File

@ -379,10 +379,6 @@ void kMemory::free_receiver (kReceiver *receiver):
while receiver->messages:
free_message (receiver, receiver->messages)
free_obj (receiver, (void **)&receivers)
if receiver == reply_target:
reply_target = NULL
// Signal that it is correct to not reply here.
reply_protected.l = 1
void kReceiver::orphan ():
if prev_owned:

View File

@ -295,7 +295,7 @@ Iris::Num start ():
Iris::Elfrun elfrun_cap = elfrun.get (0)
Iris::free_cap (elfrun)
Iris::String init_string = find (root, INIT_NAME)
Iris::Caps init_caps = elfrun_cap.run_string (top_memory.copy (), init_string.copy (), parent_cap.copy ())
Iris::Caps init_caps = elfrun_cap.run_string (top_memory.copy (), init_string.copy (), parent_cap.copy (), 8, 63)
Iris::Thread init = init_caps.get (__thread_num)
init.make_priv ()

View File

@ -1,8 +1,8 @@
# load <name> = '<filename>' load a file into memory. Don't use this after killbootthreads.
load session = "session.config"
#load session = "session.config"
load driver_lcd = "lcd.elf"
load driver_buzzer = "buzzer.elf"
load driver_gpio = "gpio.elf"
#load driver_buzzer = "buzzer.elf"
#load driver_gpio = "gpio.elf"
# load driver_audio = "audio.elf"
# load driver_udc = "udc.elf"
# load driver_nand = "nand.elf"
@ -19,17 +19,17 @@
# 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
#receive driver_buzzer / Buzzer = buzzer
#receive driver_gpio / Keyboard , 0 = keyboard
#receive driver_gpio / Keyboard , 1 = sysreq
# receive driver_audio / Audio = audio
# receive driver_udc / Udc = udc
# receive driver_nand / WString = nand
# driver <name> run a previously loaded program priviledged.
driver driver_lcd
driver driver_buzzer
driver driver_gpio
#driver driver_buzzer
#driver driver_gpio
# driver driver_audio
# driver driver_udc
# driver driver_nand
@ -56,4 +56,4 @@
# run emu_udc
# include <name> include a loaded file as another config file.
include session
#include session

View File

@ -168,10 +168,8 @@ static void reply_num (Iris::Num num):
c.data[1] = 0
if reply_target:
reply_target->send_message (reply_protected, &c)
else if reply_protected.l == 0:
else
dpanic (0, "nothing to reply to")
else:
kdebug ("not replying, because receiver was destroyed in the operation\n")
static void reply_num (unsigned num1, unsigned num2 = 0, unsigned num3 = 0):
kCapability::Context c
@ -179,17 +177,12 @@ static void reply_num (unsigned num1, unsigned num2 = 0, unsigned num3 = 0):
c.data[1] = num3
if reply_target:
reply_target->send_message (reply_protected, &c)
else if reply_protected.l == 0:
else
dpanic (0, "nothing to reply to")
else:
kdebug ("not replying, because receiver was destroyed in the operation\n")
static void reply_cap (unsigned target, Iris::Num protected_data, kCapRef *ref, unsigned num = 0):
if !reply_target:
if reply_protected.l == 0:
dpanic (0, "nothing to reply to")
else:
kdebug ("not replying, because receiver was destroyed in the operation\n")
dpanic (0, "nothing to reply to")
return
replied_caps.set (0, (kReceiver *)target, protected_data, kCapRef (), ref)
kCapability::Context c
@ -333,6 +326,8 @@ static void memory_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
if !c->arg.valid () || (unsigned)c->arg->target & ~KERNEL_MASK || !c->arg->target || ((kObject *)c->arg->protected_data.l)->address_space != mem:
reply_num (Iris::ERR_INVALID_ARGUMENT)
return
// Send the reply before destroying things, because the target may be destroyed.
reply_num (0)
switch (unsigned)c->arg->target & CAPTYPE_MASK:
case CAPTYPE_RECEIVER:
mem->free_receiver ((kReceiver *)c->arg->protected_data.l)
@ -352,7 +347,7 @@ static void memory_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
default:
panic (0x55228930, "invalid case")
return
break
return
case Iris::Memory::LIST & REQUEST_MASK:
// TODO
break

View File

@ -30,10 +30,11 @@ static void clear_page (unsigned page, unsigned num = 1):
kdebug ('\n')
#endif
page = (page & ~0xc0000000) | 0xa0000000
for unsigned i = 0; i < (num << (PAGE_BITS - 2)); ++i:
arch_uncache_page (page - 0x20000000)
// Clear page.
((unsigned *)page)[i] = 0
for unsigned p = 0; p < num; ++p:
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:
dpanic (0, "clear_page didn't work")

View File

@ -115,11 +115,14 @@ struct Program:
Iris::Memory memory
Iris::Thread thread
List <Device> devices
Iris::Cap waiter
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 bool name_match (char const *name, unsigned name_len, Iris::String n):
char nm[16]
@ -272,6 +275,52 @@ 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):
char *n
unsigned l
if !get_name (start, maxlen, n, l):
Iris::panic (0, "syntax error in init.config (driver)")
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
static void parse_line (char *&line, unsigned maxlen)
static void include_caps (Iris::Caps caps, unsigned size):
unsigned pages = (size + PAGE_SIZE - 1) >> PAGE_BITS
char *config = alloc_space (pages)
unsigned pages_slot = caps.use ()
for unsigned p = 0; p < pages; ++p:
Iris::Page page (pages_slot, p)
Iris::my_memory.map (page, (unsigned)&config[p << PAGE_BITS])
char *ptr = config
while ptr - config < size:
parse_line (ptr, config + size - ptr)
for unsigned p = 0; p < pages; ++p:
Iris::my_memory.destroy (Iris::Cap (pages_slot, p))
Iris::my_memory.destroy (caps)
Iris::free_cap (caps)
Iris::free_slot (pages_slot)
static void parse_line (char *&line, unsigned maxlen):
char *start = line
while maxlen && *line != '\n':
@ -298,6 +347,7 @@ static void parse_line (char *&line, unsigned maxlen):
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"):
@ -314,39 +364,58 @@ 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 ()
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"):
char *n
unsigned l
if !get_name (start, maxlen, n, l):
Iris::panic (0, "syntax error in init.config (driver)")
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)
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)
(*p)->thread.make_priv ()
(*p)->thread.run ()
// TODO: pass arguments.
start += maxlen
maxlen = 0
do_run (start, maxlen, true)
else if match (start, maxlen, "run"):
do_run (start, maxlen, false)
else if match (start, maxlen, "wait"):
// TODO
start += maxlen
maxlen = 0
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")
else if match (start, maxlen, "sysreq"):
// TODO
start += maxlen
@ -355,14 +424,18 @@ static void parse_line (char *&line, unsigned maxlen):
// TODO
start += maxlen
maxlen = 0
else if match (start, maxlen, "run"):
// TODO
start += maxlen
maxlen = 0
else if match (start, maxlen, "include"):
// TODO
start += maxlen
maxlen = 0
char *n
unsigned l
if !get_name (start, maxlen, n, l):
Iris::panic (0, "syntax error in init.config (include)")
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)
else:
Iris::panic (0, "invalid line in init.config")
delspace (start, maxlen)
@ -379,24 +452,11 @@ Iris::Num start ():
root = Iris::my_parent.get_device <Iris::Directory> ()
elfrun = Iris::my_parent.get_device <Iris::Elfrun> ()
top_memory = Iris::get_top_memory ()
to_receive = 0
progs = 0
unsigned config_size
Iris::Caps config_pages = load ("init.config", 12, config_size)
unsigned pages = (config_size + PAGE_SIZE - 1) >> PAGE_BITS
char *config = alloc_space (pages)
unsigned pages_slot = config_pages.use ()
for unsigned p = 0; p < pages; ++p:
Iris::Page page (pages_slot, p)
Iris::my_memory.map (page, (unsigned)&config[p << PAGE_BITS])
char *ptr = config
kdebug ("parsing config\n")
while ptr - config < config_size:
parse_line (ptr, config + config_size - ptr)
kdebug ("destroying pages\n")
for unsigned p = 0; p < pages; ++p:
Iris::my_memory.destroy (Iris::Cap (pages_slot, p))
Iris::my_memory.destroy (config_pages)
Iris::free_cap (config_pages)
Iris::free_slot (pages_slot)
include_caps (config_pages, config_size)
kdebug ("waiting for events.\n")
while true:
Iris::wait ()
@ -409,4 +469,10 @@ Iris::Num start ():
switch Iris::recv.data[0].l:
default:
// TODO.
kdebug ("child request\n")
kdebug ("child request: ")
kdebug_num (Iris::recv.data[0].l)
kdebug (" from ")
for unsigned i = 0; i < caller->name_len; ++i:
kdebug_char (caller->name[i])
kdebug ("\n")