mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
make things work with terminals
This commit is contained in:
@@ -105,7 +105,7 @@ extern "C":
|
||||
__slot_admin = slot_admin
|
||||
__cap_admin = cap_admin
|
||||
__first_free_slot = NULL
|
||||
for unsigned i = 2; i < __slots; ++i:
|
||||
for unsigned i = 1; i < __slots; ++i:
|
||||
Kernel::free_slot (i)
|
||||
__first_free_cap = NULL
|
||||
for unsigned i = 7; i < __caps; ++i:
|
||||
|
||||
@@ -20,9 +20,13 @@
|
||||
#include "iris.hh"
|
||||
#include <elf.h>
|
||||
|
||||
#define NUM_SLOTS 4
|
||||
#define NUM_SLOTS 8
|
||||
#define NUM_CAPS 32
|
||||
|
||||
enum Cap_codes:
|
||||
SYSREQ = 1 << 16
|
||||
THREAD
|
||||
|
||||
static unsigned _free
|
||||
extern unsigned _end
|
||||
|
||||
@@ -71,6 +75,10 @@ static unsigned slot
|
||||
static unsigned max_pages
|
||||
static char *mapping
|
||||
static unsigned current_thread
|
||||
static Kernel::Caps terminals
|
||||
static unsigned terminal_slot
|
||||
static Kernel::Caps memories
|
||||
static unsigned memory_slot
|
||||
|
||||
// Get the initial block device and filesystem.
|
||||
static Directory receive_devices ():
|
||||
@@ -175,8 +183,10 @@ static void sort ():
|
||||
index[i + 1] = index[i]
|
||||
index[i + 1] = f
|
||||
|
||||
static void run (file *f, bool priv):
|
||||
Kernel::Memory mem = top_memory.create_memory ()
|
||||
static void run (file *f, bool priv, int id):
|
||||
Kernel::Memory mem = Kernel::Cap (memory_slot, id)
|
||||
Kernel::set_recv_arg (mem)
|
||||
top_memory.create_memory ()
|
||||
unsigned num_pages = (f->size + PAGE_SIZE - 1) >> PAGE_BITS
|
||||
for unsigned p = 0; p < num_pages; ++p:
|
||||
//kdebug_num (p)
|
||||
@@ -310,7 +320,7 @@ static void run (file *f, bool priv):
|
||||
Kernel::Receiver receiver = mem.create_receiver ()
|
||||
receiver.set_owner (thread.copy ())
|
||||
Kernel::Cap call = receiver.create_call_capability ()
|
||||
Kernel::Cap parent = Kernel::my_receiver.create_capability (++current_thread)
|
||||
Kernel::Cap parent = Kernel::my_receiver.create_capability (Kernel::Num (current_thread++, THREAD))
|
||||
caps.set (__receiver_num, receiver.copy ())
|
||||
caps.set (__thread_num, thread.copy ())
|
||||
caps.set (__memory_num, mem.copy ())
|
||||
@@ -319,7 +329,6 @@ static void run (file *f, bool priv):
|
||||
thread.run ()
|
||||
Kernel::free_cap (receiver)
|
||||
Kernel::free_cap (thread)
|
||||
Kernel::free_cap (mem)
|
||||
Kernel::free_cap (call)
|
||||
Kernel::free_cap (parent)
|
||||
Kernel::free_cap (caps)
|
||||
@@ -331,10 +340,13 @@ static void kdebug_name (char const *t, file *f):
|
||||
kdebug_char (f->name[j])
|
||||
kdebug ("...")
|
||||
|
||||
static Device sysreq_dev
|
||||
|
||||
struct Dev:
|
||||
static Dev *devs
|
||||
static unsigned num_devs
|
||||
Dev *next
|
||||
unsigned code, idx
|
||||
unsigned code, idx, id
|
||||
Device dev
|
||||
static Dev *find (unsigned c, unsigned i):
|
||||
for Dev *d = devs; d; d = d->next:
|
||||
@@ -342,6 +354,9 @@ struct Dev:
|
||||
return d
|
||||
return NULL
|
||||
static void add (unsigned c, unsigned i, Kernel::Cap cap):
|
||||
if c == Keyboard::ID && i == 1:
|
||||
sysreq_dev = cap
|
||||
return
|
||||
while find (c, i):
|
||||
++i
|
||||
Dev *d = new Dev ()
|
||||
@@ -350,6 +365,7 @@ struct Dev:
|
||||
d->idx = i
|
||||
d->dev = cap
|
||||
devs = d
|
||||
d->id = num_devs++
|
||||
static void kdebug_list ():
|
||||
for Dev *d = devs; d; d = d->next:
|
||||
kdebug (">")
|
||||
@@ -358,8 +374,9 @@ struct Dev:
|
||||
kdebug_num (d->idx)
|
||||
|
||||
Dev *Dev::devs
|
||||
unsigned Dev::num_devs
|
||||
|
||||
void handle_init ():
|
||||
static void handle_init (unsigned id):
|
||||
while true:
|
||||
Kernel::wait ()
|
||||
switch Kernel::recv.data[0].l:
|
||||
@@ -368,46 +385,55 @@ void handle_init ():
|
||||
kdebug_num (Kernel::recv.data[1].l)
|
||||
kdebug (":")
|
||||
kdebug_num (Kernel::recv.data[0].h)
|
||||
kdebug (" as ")
|
||||
kdebug_num (Dev::num_devs)
|
||||
kdebug ("\n")
|
||||
Kernel::Cap reply = Kernel::get_reply ()
|
||||
Dev::add (Kernel::recv.data[1].l, Kernel::recv.data[0].h, Kernel::get_arg ())
|
||||
reply.invoke ()
|
||||
Kernel::free_cap (reply)
|
||||
break
|
||||
case Parent::GET_DEVICE:
|
||||
Kernel::Cap reply = Kernel::get_reply ()
|
||||
Dev *d = Dev::find (Kernel::recv.data[1].l, Kernel::recv.data[0].h)
|
||||
if d:
|
||||
kdebug ("giving dev ")
|
||||
kdebug_num (Kernel::recv.data[1].l)
|
||||
kdebug (":")
|
||||
kdebug_num (Kernel::recv.data[0].h)
|
||||
kdebug ("\n")
|
||||
Kernel::Cap cap = d->dev.create_user (Kernel::my_memory)
|
||||
d->dev.use (cap)
|
||||
reply.invoke (0, 0, cap.copy ())
|
||||
Kernel::free_cap (cap)
|
||||
else:
|
||||
kdebug ("device not found: ")
|
||||
kdebug_num (Kernel::recv.data[1].l)
|
||||
kdebug (":")
|
||||
kdebug_num (Kernel::recv.data[0].h)
|
||||
Dev::kdebug_list ()
|
||||
kdebug ("\n")
|
||||
reply.invoke (~0, ~0)
|
||||
Kernel::panic (0)
|
||||
Kernel::free_cap (reply)
|
||||
break
|
||||
case Parent::INIT_DONE:
|
||||
memories.set (id + num_files, Kernel::get_reply ())
|
||||
return
|
||||
default:
|
||||
kdebug ("unknown init request\n")
|
||||
Kernel::panic (0)
|
||||
Kernel::panic (Kernel::recv.data[0].l)
|
||||
|
||||
static void get_device ():
|
||||
Kernel::Cap reply = Kernel::get_reply ()
|
||||
unsigned id = Kernel::recv.protected_data.l
|
||||
Dev *d = Dev::find (Kernel::recv.data[1].l, Kernel::recv.data[0].h)
|
||||
if d:
|
||||
kdebug ("giving dev ")
|
||||
kdebug_num (Kernel::recv.data[1].l)
|
||||
kdebug (":")
|
||||
kdebug_num (Kernel::recv.data[0].h)
|
||||
kdebug (" = ")
|
||||
kdebug_num (d->id)
|
||||
kdebug (" to ")
|
||||
kdebug_num (id)
|
||||
kdebug ("\n")
|
||||
Kernel::Cap cap = Kernel::Caps (terminal_slot, id).get (d->id)
|
||||
d->dev.use (cap)
|
||||
reply.invoke (0, 0, cap.copy ())
|
||||
Kernel::free_cap (cap)
|
||||
else:
|
||||
kdebug ("device not found: ")
|
||||
kdebug_num (Kernel::recv.data[1].l)
|
||||
kdebug (":")
|
||||
kdebug_num (Kernel::recv.data[0].h)
|
||||
Dev::kdebug_list ()
|
||||
kdebug ("\n")
|
||||
reply.invoke (~0, ~0)
|
||||
Kernel::panic (0)
|
||||
Kernel::free_cap (reply)
|
||||
|
||||
Kernel::Num start ():
|
||||
// Wait for the debugging device to be active, in case there is one.
|
||||
Kernel::schedule ()
|
||||
Dev::devs = NULL
|
||||
Dev::num_devs = 0
|
||||
init_alloc ()
|
||||
top_memory = Kernel::get_top_memory ()
|
||||
Directory root = receive_devices ()
|
||||
@@ -417,16 +443,66 @@ Kernel::Num start ():
|
||||
Kernel::Caps caps = Kernel::my_memory.create_caps (max_pages)
|
||||
slot = caps.use ()
|
||||
mapping = alloc_space (max_pages)
|
||||
terminals = Kernel::my_memory.create_caps (num_files)
|
||||
terminal_slot = terminals.use ()
|
||||
// Two times, because it holds the memory and the init_done reply for each task.
|
||||
memories = Kernel::my_memory.create_caps (num_files * 2)
|
||||
memory_slot = memories.use ()
|
||||
for unsigned i = 0; i < num_files; ++i:
|
||||
kdebug_name ("loading ", &files[index[i]])
|
||||
run (&files[index[i]], files[index[i]].name[0] == '#')
|
||||
run (&files[index[i]], files[index[i]].name[0] == '#', i)
|
||||
kdebug ("running\n")
|
||||
handle_init ()
|
||||
handle_init (i)
|
||||
// Notify all programs that they may start.
|
||||
for unsigned i = 0; i < num_files; ++i:
|
||||
Kernel::Cap (memory_slot, i + num_files).invoke ()
|
||||
// create terminals.
|
||||
for unsigned i = 0; i < num_files; ++i:
|
||||
Kernel::Caps term (terminal_slot, i)
|
||||
Kernel::Memory mem (memory_slot, i)
|
||||
Kernel::set_recv_arg (term)
|
||||
mem.create_caps (Dev::num_devs)
|
||||
unsigned termslot = term.use ()
|
||||
for Dev *d = Dev::devs; d; d = d->next:
|
||||
Kernel::set_recv_arg (Kernel::Cap (termslot, d->id))
|
||||
// The 0x15000 is for the Display; the others don't care about it.
|
||||
d->dev.create_user (mem, 0, 0x15000)
|
||||
Kernel::free_slot (termslot)
|
||||
// set up system request.
|
||||
Keyboard sysreq = sysreq_dev.create_user (Kernel::my_memory)
|
||||
sysreq_dev.use (sysreq)
|
||||
Kernel::free_cap (sysreq_dev)
|
||||
Kernel::Cap cap = Kernel::my_receiver.create_capability (Kernel::Num (0, SYSREQ))
|
||||
sysreq.set_cb (cap.copy ())
|
||||
Kernel::free_cap (sysreq)
|
||||
Kernel::free_cap (cap)
|
||||
kdebug ("init done\n")
|
||||
root.unlock_ro ()
|
||||
Kernel::free_slot (slot)
|
||||
Kernel::my_memory.destroy (caps)
|
||||
while true:
|
||||
handle_init ()
|
||||
//Kernel::wait ()
|
||||
//kdebug ("request!\n")
|
||||
Kernel::wait ()
|
||||
switch Kernel::recv.protected_data.h:
|
||||
case SYSREQ:
|
||||
// System request.
|
||||
if Kernel::recv.data[0].l & Keyboard::RELEASE:
|
||||
continue
|
||||
kdebug ("system request...\n")
|
||||
continue
|
||||
case THREAD:
|
||||
// Request for something from a child thread.
|
||||
switch Kernel::recv.data[0].l:
|
||||
case Parent::INIT_DONE:
|
||||
Kernel::panic (Kernel::recv.protected_data.l, "double init_done")
|
||||
case Parent::PROVIDE_DEVICE:
|
||||
Kernel::panic (Kernel::recv.protected_data.l, "too late now for provide")
|
||||
case Parent::GET_DEVICE:
|
||||
get_device ()
|
||||
break
|
||||
case Parent::EXIT:
|
||||
Kernel::panic (Kernel::recv.protected_data.l, "exit is not supported")
|
||||
default:
|
||||
Kernel::panic (Kernel::recv.data[0].l, "invalid operation from child")
|
||||
break
|
||||
default:
|
||||
Kernel::panic (Kernel::recv.protected_data.h, "unknown source of request")
|
||||
|
||||
Reference in New Issue
Block a user