1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2025-04-21 12:27:27 +03:00

working with new invoke system

This commit is contained in:
Bas Wijnen
2009-09-06 11:04:09 +02:00
parent 4c73b034f8
commit a838dd63c6
16 changed files with 982 additions and 965 deletions

View File

@@ -28,46 +28,53 @@ static unsigned __slots, __caps
static list *__slot_admin, *__cap_admin
static list *__first_free_slot, *__first_free_cap
Receiver __my_receiver
Thread __my_thread
Memory __my_memory
Cap __my_call
Cap __my_parent
namespace Kernel:
Receiver my_receiver
Thread my_thread
Memory my_memory
Cap my_call
Cap my_parent
__recv_data_t recv
void free_slot (unsigned slot):
__slot_admin[slot].prev = NULL
__slot_admin[slot].next = __first_free_slot
if __slot_admin[slot].next:
__slot_admin[slot].next->prev = &__slot_admin[slot]
__first_free_slot = &__slot_admin[slot]
void free_slot (unsigned slot):
__slot_admin[slot].prev = NULL
__slot_admin[slot].next = __first_free_slot
if __slot_admin[slot].next:
__slot_admin[slot].next->prev = &__slot_admin[slot]
__first_free_slot = &__slot_admin[slot]
void free_cap (Cap cap):
list *l = &__cap_admin[cap.idx ()]
l->prev = NULL
l->next = __first_free_cap
if l->next:
l->next->prev = l
__first_free_cap = l
void free_cap (Cap cap):
if cap.slot () != 0:
kdebug ("trying to free capability from non-0 slot\n")
return
list *l = &__cap_admin[cap.idx ()]
l->prev = NULL
l->next = __first_free_cap
if l->next:
l->next->prev = l
__first_free_cap = l
unsigned alloc_slot ():
if !__first_free_slot:
// Out of slots... Probably best to raise an exception. For now, just return NO_SLOT.
return ~0
list *ret = __first_free_slot
__first_free_slot = ret->next
if ret->next:
ret->next->prev = NULL
return ret - __slot_admin
unsigned alloc_slot ():
if !__first_free_slot:
// Out of slots... Probably best to raise an exception. For now, just return NO_SLOT.
kdebug ("out of slots!\n")
return ~0
list *ret = __first_free_slot
__first_free_slot = ret->next
if ret->next:
ret->next->prev = NULL
return ret - __slot_admin
unsigned alloc_cap ():
if !__first_free_cap:
// Out of caps... Probably best to raise an exception. For now, just return NO_CAPABILITY.
return ~0
list *ret = __first_free_cap
__first_free_cap = ret->next
if ret->next:
ret->next->prev = NULL
return ret - __cap_admin
Cap alloc_cap ():
if !__first_free_cap:
// Out of caps... Probably best to raise an exception. For now, just return CAP_NONE
kdebug ("out of capabilities!\n")
return Cap (0, CAP_NONE)
list *ret = __first_free_cap
__first_free_cap = ret->next
if ret->next:
ret->next->prev = NULL
return Cap (0, ret - __cap_admin)
extern "C":
void __main (unsigned slots, unsigned caps, list *slot_admin, list *cap_admin):
@@ -77,18 +84,20 @@ extern "C":
__cap_admin = cap_admin
__first_free_slot = NULL
for unsigned i = 2; i < __slots; ++i:
free_slot (i)
Kernel::free_slot (i)
__first_free_cap = NULL
for unsigned i = 7; i < __caps; ++i:
free_cap (Cap (0, i))
__my_receiver = Cap (0, __receiver_num)
__my_thread = Cap (0, __thread_num)
__my_memory = Cap (0, __memory_num)
__my_call = Cap (0, __call_num)
__my_parent = Cap (0, __parent_num)
Num ret = start ()
__my_parent.invoke (~0, ret)
__my_memory.destroy (__my_thread)
Kernel::free_cap (Kernel::Cap (0, i))
Kernel::my_receiver = Kernel::Cap (0, __receiver_num)
Kernel::my_thread = Kernel::Cap (0, __thread_num)
Kernel::my_memory = Kernel::Cap (0, __memory_num)
Kernel::my_call = Kernel::Cap (0, __call_num)
Kernel::my_parent = Kernel::Cap (0, __parent_num)
Kernel::recv.reply = Kernel::alloc_cap ()
Kernel::recv.arg = Kernel::alloc_cap ()
Kernel::Num ret = start ()
Kernel::my_parent.invoke (~0, ret)
Kernel::my_memory.destroy (Kernel::my_thread)
// The program no longer exists. If it somehow does, generate an address fault.
while true:
*(volatile unsigned *)~0

View File

@@ -24,59 +24,59 @@
// This shouldn't really be here. But where should it be?
// Requests made by initial threads to tell init about themselves.
enum init_requests:
INIT_SET_GPIO
INIT_SET_GPIO = 1
INIT_SET_LCD
// List interface.
template <typename _T> //
struct List : public Cap:
List (Cap c = Cap ()) : Cap (c):
struct List : public Kernel::Cap:
List (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
// TODO
struct String : public Cap:
String (Cap c = Cap ()) : Cap (c):
struct String : public Kernel::Cap:
String (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
// TODO
// Keyboard interface.
struct Keyboard : public Cap:
Keyboard (Cap c = Cap ()) : Cap (c):
struct Keyboard : public Kernel::Cap:
Keyboard (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
enum request:
SET_CB
SET_CB = 1
GET_KEYS
// At event: the callback is called with a keycode. One bit defines if it's a press or release event.
enum constant:
RELEASE = 1 << 31
// Set the event callback. Currently pressed keys emit a key press event to the new callback immediately, plus a ~0 to signal the end of such events.
void set_cb (Cap cb):
void set_cb (Kernel::Cap cb):
ocall (cb, CAP_MASTER_DIRECT | SET_CB)
// Get a list of keys on this keyboard. The key codes start at zero with no gaps.
List <String> get_keys (List <String> ret = Cap (0, alloc_cap ())):
icall (ret, CAP_MASTER_DIRECT | GET_KEYS)
return ret
List <String> get_keys ():
icall (CAP_MASTER_DIRECT | GET_KEYS)
return Kernel::get_arg ()
// Display interface.
struct Display : public Cap:
Display (Cap c = Cap ()) : Cap (c):
struct Display : public Kernel::Cap:
Display (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
enum request:
EOF_CB
EOF_CB = 1
CREATE_FB
USE_FB
GET_INFO
// Register an end-of-frame callback.
// At end of frame, the callback is invoked and forgotten. It must be reregistered to keep a stream of events.
void set_eof_cb (Cap cb):
void set_eof_cb (Kernel::Cap cb):
ocall (cb, CAP_MASTER_DIRECT | EOF_CB)
// Create a framebuffer for the display. When not in use, it can be freed by the user.
// The pages must be cappages holding Page capabilities. They are filled by the display.
// The passed numbers must be 0 or match a mode that the device can use.
// The returned number is the physical address of the framebuffer. It can be used with display_use_framebuffer.
unsigned create_framebuffer (Caps pages, unsigned w = 0, unsigned h = 0, unsigned mode = 0):
return icall (pages, Num (CAP_MASTER_DIRECT | CREATE_FB, 0), Num ((w << 16) | h, mode)).l
unsigned create_framebuffer (unsigned w = 0, unsigned h = 0, unsigned mode = 0):
return icall (Kernel::Num (CAP_MASTER_DIRECT | CREATE_FB, 0), Kernel::Num ((w << 16) | h, mode)).l
// Use a framebuffer. The address must have been returned from display_create_framebuffer.
// w, h and mode must match the values given at creation time.
// unuse_cb is called the next time this operation is requested for this display.
void use_framebuffer (unsigned addr, Cap unuse_cb = Cap (), unsigned w = 0, unsigned h = 0, unsigned mode = 0):
ocall (unuse_cb, Num (CAP_MASTER_DIRECT | USE_FB, addr), Num ((w << 16) | h, mode))
void use_framebuffer (unsigned addr, Kernel::Cap unuse_cb = Kernel::Cap (), unsigned w = 0, unsigned h = 0, unsigned mode = 0):
ocall (unuse_cb, Kernel::Num (CAP_MASTER_DIRECT | USE_FB, addr), Kernel::Num ((w << 16) | h, mode))
// Get information about the display.
void get_info ():
// TODO: Interface is to be designed.
@@ -86,91 +86,95 @@ struct Display : public Cap:
// File system interface.
// filesystem-related interfaces: file, directory, stream, seekable, mappable.
// Normal files implement at least stream or seekable file. Directories implement directory.
struct File : public Cap:
File (Cap c = Cap ()) : Cap (c):
struct File : public Kernel::Cap:
File (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
enum request:
INFO
INFO = 1
CLOSE
MAP_HANDLE
// Get information about the file.
Num get_info (unsigned type, Caps ret = Cap ()):
return icall (ret, Num (CAP_MASTER_DIRECT | INFO, type))
Kernel::Num get_info (unsigned type):
return icall (Kernel::Num (CAP_MASTER_DIRECT | INFO, type))
// Close a file. If this is a directory, it implicitly closes all files opened from it.
void close ():
call (CAP_MASTER_DIRECT | CLOSE)
// Map a file handle. This can be useful for closing all children at once. The new handle itself is a child of the original handle.
File map_handle (File ret):
icall (ret, CAP_MASTER_DIRECT | MAP_HANDLE)
File map_handle ():
icall (CAP_MASTER_DIRECT | MAP_HANDLE)
return Kernel::get_arg ()
// Directory interface.
struct Directory : public File:
Directory (Cap c = Cap ()) : File (c):
Directory (Kernel::Cap c = Kernel::Cap ()) : File (c):
enum request:
GET_SIZE
GET_SIZE = 1
GET_NAME
GET_FILE
GET_FILE_INFO
CREATE_FILE
DELETE_FILE
// Get the number of entries in this directory.
Num get_size ():
Kernel::Num get_size ():
return call (CAP_MASTER_DIRECT | GET_SIZE)
// Get the filename. The return value is the size of the string, the page is filled with the string itself.
void get_name (Num idx, String target):
icall (target, CAP_MASTER_DIRECT | GET_NAME, idx)
String get_name (Kernel::Num idx):
icall (CAP_MASTER_DIRECT | GET_NAME, idx)
return Kernel::get_arg ()
// Get the file.
void get_file (Num idx, File ret):
icall (ret, CAP_MASTER_DIRECT | GET_FILE, idx)
File get_file (Kernel::Num idx):
icall (CAP_MASTER_DIRECT | GET_FILE, idx)
return Kernel::get_arg ()
// Get file info. This returns the same information as file_get_info, without opening the file.
Num get_file_info (Num idx, unsigned type, Caps ret = Cap ()):
return icall (ret, Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx)
Kernel::Num get_file_info (Kernel::Num idx, unsigned type):
return icall (Kernel::Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx)
// Create a new file. After this, any index may map to a different file.
void create_file (String name, File ret):
icall (ret, CAP_MASTER_DIRECT | CREATE_FILE)
File create_file (String name):
icall (CAP_MASTER_DIRECT | CREATE_FILE)
return Kernel::get_arg ()
// Delete a file. After this, any index may map to a different file.
void delete_file (Num idx):
void delete_file (Kernel::Num idx):
call (CAP_MASTER_DIRECT | DELETE_FILE, idx)
// Stream interface.
struct Stream : public File:
Stream (Cap c = Cap ()) : File (c):
Stream (Kernel::Cap c = Kernel::Cap ()) : File (c):
enum request:
READ
READ = 1
WRITE
// Try to read size bytes. Returns the number of bytes successfully read.
Num read (Num size, String ret):
return icall (ret, CAP_MASTER_DIRECT | READ, size)
Kernel::Num read (Kernel::Num size):
return icall (CAP_MASTER_DIRECT | READ, size)
// Try to write size bytes. Returns the number of bytes successfully written.
Num write (String s, Num size):
Kernel::Num write (String s, Kernel::Num size):
return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
// Seekable file interface.
struct Seekable : public File:
Seekable (Cap c = Cap ()) : File (c):
Seekable (Kernel::Cap c = Kernel::Cap ()) : File (c):
enum request:
READ
READ = 1
WRITE
TRUNCATE
// Try to read size bytes from position idx. Returns the number of bytes successfully read.
Num read (Num idx, unsigned size, String ret):
return icall (ret, Num (CAP_MASTER_DIRECT | READ, size), idx)
Kernel::Num read (Kernel::Num idx, unsigned size):
return icall (Kernel::Num (CAP_MASTER_DIRECT | READ, size), idx)
// Try to write size bytes at position idx; the file is extended with zeroes if the write is past the end. Returns the number of bytes successfully written.
Num write (Num idx, String s):
Kernel::Num write (Kernel::Num idx, String s):
return ocall (s, CAP_MASTER_DIRECT | WRITE, idx)
// Truncate file to size idx. The file is extended with zeroes if it gets longer.
void truncate (Num idx):
void truncate (Kernel::Num idx):
call (CAP_MASTER_DIRECT | TRUNCATE, idx)
// Mappable file interface.
struct Mappable : public Seekable:
Mappable (Cap c = Cap ()) : Seekable (c):
Mappable (Kernel::Cap c = Kernel::Cap ()) : Seekable (c):
// TODO: to be designed.
// Block device interface.
struct Block_device : public Mappable:
Block_device (Cap c = Cap ()) : Mappable (c):
Block_device (Kernel::Cap c = Kernel::Cap ()) : Mappable (c):
// TODO: to be designed.

View File

@@ -59,29 +59,14 @@ enum cap_type:
CAP_LOCKLEDS
CAP_PWM
static unsigned events
static Caps event_caps
static Kernel::Cap events[NUM_EVENTS]
static void event (event_type type, unsigned data):
kdebug ("event t/d/e=")
kdebug_num (type)
kdebug_char ('/')
kdebug_num (data)
kdebug_char ('/')
kdebug_num (events)
kdebug_char ('\n')
Cap (events, type).invoke (data)
events[type].invoke (data)
static void set_cb (Cap cap, event_type type):
kdebug ("gpio set cb ")
kdebug_num (type)
kdebug_char ('\n')
for unsigned i = 0; i < NUM_EVENTS; ++i:
event_caps.print (i)
cap.clone (Cap (events, type))
kdebug ("after:\n")
for unsigned i = 0; i < NUM_EVENTS; ++i:
event_caps.print (i)
static void set_cb (event_type type):
Kernel::free_cap (events[type])
events[type] = Kernel::get_arg ()
class DevKeyboard:
static unsigned const encode[GPIO_KBD_NUM_COLS][GPIO_KBD_NUM_ROWS]
@@ -159,7 +144,6 @@ class DevKeyboard:
for unsigned col = 0; col < GPIO_KBD_NUM_COLS; ++col:
keys[col] = 0xff
scan ()
event (KEYBOARD_EVENT, ~0)
enum Keys:
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9
@@ -225,7 +209,6 @@ class Touchpad:
void send_initial ():
old_state = 0
check_events ()
event (TOUCHPAD_EVENT, ~0)
class Lockleds:
// Note that num lock is in port 2. The others are in port 0.
@@ -269,49 +252,50 @@ class Pwm:
GPIO_GPDR (GPIO_PWM_ENABLE_PORT) &= ~(1 << GPIO_PWM_ENABLE)
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
Num start ():
Kernel::Num start ():
Kernel::schedule ()
map_gpio ()
map_pwm0 ()
event_caps = __my_memory.create_caps (NUM_EVENTS)
events = event_caps.use ()
for unsigned i = 0; i < NUM_EVENTS; ++i:
events[i] = Kernel::alloc_cap ()
DevKeyboard kbd
Touchpad tp
Lockleds leds
Pwm pwm
Caps c = __my_memory.create_caps (4)
Kernel::Caps c = Kernel::my_memory.create_caps (4)
unsigned init_slot = c.use ()
__my_receiver.create_capability (CAP_KEYBOARD, Cap (init_slot, 0))
__my_receiver.create_capability (CAP_TOUCHPAD, Cap (init_slot, 1))
__my_receiver.create_capability (CAP_LOCKLEDS, Cap (init_slot, 2))
__my_receiver.create_capability (CAP_PWM, Cap (init_slot, 3))
Kernel::set_recv_arg (Kernel::Cap (init_slot, 0))
Kernel::my_receiver.create_capability (CAP_KEYBOARD)
Kernel::set_recv_arg (Kernel::Cap (init_slot, 1))
Kernel::my_receiver.create_capability (CAP_TOUCHPAD)
Kernel::set_recv_arg (Kernel::Cap (init_slot, 2))
Kernel::my_receiver.create_capability (CAP_LOCKLEDS)
Kernel::set_recv_arg (Kernel::Cap (init_slot, 3))
Kernel::my_receiver.create_capability (CAP_PWM)
__my_parent.ocall (c, INIT_SET_GPIO)
Kernel::my_parent.ocall (c, INIT_SET_GPIO)
free_cap (c)
free_slot (init_slot)
Kernel::free_slot (init_slot)
if kbd.is_scanning ():
__my_receiver.set_alarm (ALARM_INTERVAL)
Kernel::my_receiver.set_alarm (ALARM_INTERVAL)
// Enable interrupts. All are in port 0.
GPIO_GPIER (GPIO_KBD_ROW_PORT) = (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT) | GPIO_KBD_ROW_MASK
Kernel::register_interrupt (IRQ_GPIO0)
kdebug ("gpio ready\n")
unsigned slot = alloc_slot ()
while true:
Kernel::schedule ()
Cap::OMessage msg
Kernel::wait (&msg, slot)
switch (unsigned)msg.cap_protected.value ():
Kernel::wait ()
switch Kernel::recv.protected_data.l:
case ~0:
// Alarm.
kbd.scan ()
if kbd.is_scanning ():
__my_receiver.set_alarm (ALARM_INTERVAL)
Kernel::my_receiver.set_alarm (ALARM_INTERVAL)
break
case IRQ_GPIO0:
// Always scan keyboard and touchpad on any interrupt.
@@ -321,20 +305,29 @@ Num start ():
Kernel::register_interrupt (IRQ_GPIO0)
break
case CAP_KEYBOARD:
set_cb (Cap (slot, 1), KEYBOARD_EVENT)
Cap (slot, 0).invoke ()
kdebug ("gpio: keyboard callback registered.\n")
set_cb (KEYBOARD_EVENT)
Kernel::recv.reply.invoke ()
kbd.send_initial ()
event (KEYBOARD_EVENT, ~0)
break
case CAP_TOUCHPAD:
set_cb (Cap (slot, 1), TOUCHPAD_EVENT)
Cap (slot, 0).invoke ()
kdebug ("gpio: touchpad callback registered.\n")
set_cb (TOUCHPAD_EVENT)
Kernel::recv.reply.invoke ()
tp.send_initial ()
event (TOUCHPAD_EVENT, ~0)
break
case CAP_LOCKLEDS:
leds.set (msg.data[0].l)
Cap (slot, 0).invoke ()
leds.set (Kernel::recv.data[0].l)
Kernel::recv.reply.invoke ()
break
case CAP_PWM:
pwm.set_backlight (msg.data[0].l)
Cap (slot, 0).invoke ()
pwm.set_backlight (Kernel::recv.data[0].l)
Kernel::recv.reply.invoke ()
break
default:
kdebug ("invalid gpio operation ")
kdebug_num (Kernel::recv.protected_data.l)
kdebug ("\n")
break

View File

@@ -21,7 +21,7 @@
static Keyboard kbd, tp
static Display lcd
static Cap lockleds, pwm
static Kernel::Cap lockleds, pwm
// Event types.
enum type:
@@ -30,71 +30,63 @@ enum type:
static void setup ():
unsigned state = 0
unsigned slot = alloc_slot ()
Kernel::recv.arg = Kernel::alloc_cap ()
while true:
Cap::OMessage msg
Kernel::wait (&msg, slot)
switch msg.data[0].value ():
Kernel::wait ()
switch Kernel::recv.data[0].value ():
case INIT_SET_GPIO:
kdebug ("gpio\n")
Caps caps = Cap (slot, 1)
Kernel::Caps caps = Kernel::get_arg ()
Kernel::Cap reply = Kernel::get_reply ()
unsigned gpio_slot = caps.use ()
Cap (slot, 0).invoke ()
kbd = Cap (gpio_slot, 0)
tp = Cap (gpio_slot, 1)
lockleds = Cap (gpio_slot, 2)
pwm = Cap (gpio_slot, 3)
kbd = Kernel::Cap (gpio_slot, 0)
tp = Kernel::Cap (gpio_slot, 1)
lockleds = Kernel::Cap (gpio_slot, 2)
pwm = Kernel::Cap (gpio_slot, 3)
reply.invoke ()
Kernel::free_cap (reply)
++state
break
case INIT_SET_LCD:
kdebug ("lcd\n")
lcd = Cap (slot, 1).clone ()
Cap (slot, 0).invoke ()
lcd = Kernel::get_arg ()
Kernel::recv.reply.invoke ()
++state
break
if state == 2:
break
Caps caps = __my_memory.create_caps (2)
Cap kc = __my_receiver.create_capability (KBD, Cap (slot, 0))
kdebug ("init0: ")
caps.print (0)
Kernel::schedule ()
kdebug ("init registering keyboard\n")
Kernel::Cap kc = Kernel::my_receiver.create_capability (KBD)
kbd.set_cb (kc)
kdebug ("init1: ")
caps.print (0)
Cap tc = __my_receiver.create_capability (TP, Cap (slot, 1))
kdebug ("init2: ")
caps.print (1)
Kernel::Cap tc = Kernel::my_receiver.create_capability (TP)
tp.set_cb (tc)
kdebug ("init3: ")
caps.print (1)
pwm.call (1)
free_slot (slot)
char const *decode_kbd = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*() T\n[],.-=/\\;|`'UDLREIKBPFZMS{}CA\":"
Num start ():
Kernel::Num start ():
// Set up lcd first
Kernel::schedule ()
kdebug ("start init\n")
setup ()
kdebug ("run init\n")
while true:
Cap::OMessage msg
Kernel::wait (&msg)
switch msg.cap_protected.value ():
Kernel::wait ()
switch Kernel::recv.protected_data.value ():
case KBD:
unsigned code = msg.data[0].l
unsigned code = Kernel::recv.data[0].l
if code & Keyboard::RELEASE:
break
kdebug_char (decode_kbd[code])
break
case TP:
unsigned leds = 0
if msg.data[0].l & 1:
if Kernel::recv.data[0].l & 1:
leds |= 0x1
else:
leds |= 0x4
if !(msg.data[0].l & Keyboard::RELEASE):
if !(Kernel::recv.data[0].l & Keyboard::RELEASE):
leds |= 0x2
lockleds.call (leds)
break

View File

@@ -103,7 +103,7 @@ static void log_str (char const *str):
while *str:
log_char (*str++)
static void log_num (Num n):
static void log_num (Kernel::Num n):
char const *encode = "0123456789abcdef"
log_char ('[')
for unsigned i = 0; i < 8; ++i:
@@ -113,27 +113,27 @@ static void log_num (Num n):
log_char (encode[(n.l >> (4 * (7 - i))) & 0xf])
log_char (']')
static void log_msg (Cap::OMessage *msg):
log_str ("cap_prot:")
log_num (msg->cap_protected)
static void log_msg ():
log_str ("prot:")
log_num (Kernel::recv.protected_data)
log_str ("data:")
for unsigned i = 0; i < 2; ++i:
log_num (msg->data[i])
log_num (Kernel::recv.data[i])
log_char ('\n')
Num start ():
Kernel::Num start ():
map_lcd ()
map_cpm ()
Descriptor descriptor __attribute__ ((aligned (16)))
unsigned pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
unsigned physical = __my_memory.alloc_range (pages)
unsigned physical = Kernel::my_memory.alloc_range (pages)
assert (physical & PAGE_MASK && ~physical)
for unsigned i = 0; i < pages; ++i:
Page p = __my_memory.create_page ()
Kernel::Page p = Kernel::my_memory.create_page ()
p.alloc_physical (physical + i * PAGE_SIZE, false, true)
__my_memory.map (p, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE)
free_cap (p)
Kernel::my_memory.map (p, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE)
Kernel::free_cap (p)
for unsigned y = 0; y < 480; ++y:
unsigned g = (y << 6) / 480
unsigned olr = 0, ob = ((25 * y * y) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
@@ -150,9 +150,9 @@ Num start ():
ob = b
b = 0x1f
LCD_FRAMEBUFFER_BASE[y * 800 + x] = (r << 11) | (g << 5) | (b)
Page p = __my_memory.mapping (&descriptor)
Kernel::Page p = Kernel::my_memory.mapping (&descriptor)
physical_descriptor = p.physical_address () + ((unsigned)&descriptor & ~PAGE_MASK)
free_cap (p)
Kernel::free_cap (p)
descriptor.next = physical_descriptor
descriptor.frame = physical
descriptor.id = 0xdeadbeef
@@ -161,28 +161,32 @@ Num start ():
__asm__ volatile ("lw $a0, %0\ncache 0x15, 0($a0)" :: "m"(dptr) : "memory", "a0")
reset ()
Cap logcap = __my_receiver.create_capability (LCD_LOG)
Kernel::Cap logcap = Kernel::my_receiver.create_capability (LCD_LOG)
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
Cap set_eof_cb = __my_receiver.create_capability (LCD_EOF_CB)
__my_parent.ocall (set_eof_cb, INIT_SET_LCD)
Kernel::Cap set_eof_cb = Kernel::my_receiver.create_capability (LCD_EOF_CB)
Kernel::my_parent.ocall (set_eof_cb, INIT_SET_LCD)
unsigned slot = alloc_slot ()
Cap eof_cb (0, alloc_cap ())
unsigned slot = Kernel::alloc_slot ()
Kernel::Cap eof_cb = Kernel::alloc_cap ()
while true:
Cap::OMessage msg
Kernel::wait (&msg, slot)
//log_msg (&msg)
switch msg.cap_protected.value ():
Kernel::wait ()
//log_msg ()
switch Kernel::recv.protected_data.l:
case IRQ_LCD:
lcd_clr_eof ()
eof_cb.invoke ()
break
case LCD_EOF_CB:
Cap (slot, 1).clone (eof_cb)
Cap (slot, 0).invoke ()
Kernel::free_cap (eof_cb)
eof_cb = Kernel::recv.arg
Kernel::recv.arg = Kernel::alloc_cap ()
Kernel::recv.reply.invoke ()
Kernel::register_interrupt (IRQ_LCD)
break
case LCD_LOG:
log_char (msg.data[0].l)
log_char (Kernel::recv.data[0].l)
break
default:
log_char ('~')
break