1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2025-04-21 12:27:27 +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

@@ -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")