1
0
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:
Bas Wijnen
2010-01-24 21:34:24 +01:00
parent 5ef2934bf8
commit 06390fd2d1
23 changed files with 854 additions and 487 deletions

View File

@@ -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:

View File

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