mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
usb-booting alarm clock, with split gui
This commit is contained in:
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 ()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user