mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-16 17:20:36 +02:00
working device swapping
This commit is contained in:
parent
cba0cf31e5
commit
7a8d7c28c4
@ -85,8 +85,7 @@ static unsigned *inuse
|
|||||||
|
|
||||||
// Get the initial block device and filesystem.
|
// Get the initial block device and filesystem.
|
||||||
static Directory receive_devices ():
|
static Directory receive_devices ():
|
||||||
String data
|
Kernel::Caps data, fs
|
||||||
Filesystem fs
|
|
||||||
bool have_data = false, have_fs = false
|
bool have_data = false, have_fs = false
|
||||||
Device fs_dev, data_dev
|
Device fs_dev, data_dev
|
||||||
for unsigned i = 0; i < 2; ++i:
|
for unsigned i = 0; i < 2; ++i:
|
||||||
@ -115,9 +114,11 @@ static Directory receive_devices ():
|
|||||||
data_dev.use (data)
|
data_dev.use (data)
|
||||||
fs = fs_dev.create_user (Kernel::my_memory)
|
fs = fs_dev.create_user (Kernel::my_memory)
|
||||||
fs_dev.use (fs)
|
fs_dev.use (fs)
|
||||||
Directory root = fs.use_device_ro (data.copy ())
|
Filesystem fs_cap = fs.get (0)
|
||||||
|
Directory root = fs_cap.use_device_ro (data.copy ())
|
||||||
Kernel::free_cap (data)
|
Kernel::free_cap (data)
|
||||||
Kernel::free_cap (fs)
|
Kernel::free_cap (fs)
|
||||||
|
Kernel::free_cap (fs_cap)
|
||||||
Kernel::free_cap (data_dev)
|
Kernel::free_cap (data_dev)
|
||||||
Kernel::free_cap (fs_dev)
|
Kernel::free_cap (fs_dev)
|
||||||
return root
|
return root
|
||||||
@ -371,7 +372,9 @@ static void handle_init (unsigned id):
|
|||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
break
|
break
|
||||||
case Parent::INIT_DONE:
|
case Parent::INIT_DONE:
|
||||||
memories.set (id + num_files, Kernel::get_reply ())
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
memories.set (id + num_files, reply.copy ())
|
||||||
|
Kernel::free_cap (reply)
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
kdebug ("unknown init request\n")
|
kdebug ("unknown init request\n")
|
||||||
@ -393,14 +396,16 @@ static void get_device ():
|
|||||||
kdebug (" to ")
|
kdebug (" to ")
|
||||||
kdebug_num (id)
|
kdebug_num (id)
|
||||||
kdebug ("\n")
|
kdebug ("\n")
|
||||||
Kernel::Cap cap = d->dev.create_user (Kernel::Memory (memory_slot, id), 0, 0x15000)
|
Kernel::Caps cap = d->dev.create_user (Kernel::Memory (memory_slot, id), 0, 0x15000)
|
||||||
Kernel::Caps (terminal_slot, id).set (d->id, cap.copy ())
|
Kernel::Caps (terminal_slot, id).set (d->id, cap.copy ())
|
||||||
for unsigned i = 0; i < num_files; ++i:
|
for unsigned i = 0; i < num_files; ++i:
|
||||||
if inuse[i * Dev::num_devs + d->id] == 2:
|
if inuse[i * Dev::num_devs + d->id] == 2:
|
||||||
inuse[i * Dev::num_devs + d->id] = 1
|
inuse[i * Dev::num_devs + d->id] = 1
|
||||||
inuse[id * Dev::num_devs + d->id] = 2
|
inuse[id * Dev::num_devs + d->id] = 2
|
||||||
d->dev.use (cap)
|
d->dev.use (cap)
|
||||||
reply.invoke (0, 0, cap.copy ())
|
Kernel::Cap ret = cap.get (0)
|
||||||
|
reply.invoke (0, 0, ret.copy ())
|
||||||
|
Kernel::free_cap (ret)
|
||||||
Kernel::free_cap (cap)
|
Kernel::free_cap (cap)
|
||||||
else:
|
else:
|
||||||
kdebug ("device not found: ")
|
kdebug ("device not found: ")
|
||||||
@ -451,9 +456,11 @@ Kernel::Num start ():
|
|||||||
Kernel::set_recv_arg (term)
|
Kernel::set_recv_arg (term)
|
||||||
mem.create_caps (Dev::num_devs)
|
mem.create_caps (Dev::num_devs)
|
||||||
// set up system request.
|
// set up system request.
|
||||||
Keyboard sysreq = sysreq_dev.create_user (Kernel::my_memory)
|
Kernel::Caps sysreq_caps = sysreq_dev.create_user (Kernel::my_memory)
|
||||||
sysreq_dev.use (sysreq)
|
sysreq_dev.use (sysreq_caps)
|
||||||
|
Keyboard sysreq = sysreq_caps.get (0)
|
||||||
Kernel::free_cap (sysreq_dev)
|
Kernel::free_cap (sysreq_dev)
|
||||||
|
Kernel::free_cap (sysreq_caps)
|
||||||
Kernel::Cap cap = Kernel::my_receiver.create_capability (Kernel::Num (0, SYSREQ))
|
Kernel::Cap cap = Kernel::my_receiver.create_capability (Kernel::Num (0, SYSREQ))
|
||||||
sysreq.set_cb (cap.copy ())
|
sysreq.set_cb (cap.copy ())
|
||||||
Kernel::free_cap (sysreq)
|
Kernel::free_cap (sysreq)
|
||||||
@ -462,11 +469,13 @@ Kernel::Num start ():
|
|||||||
Dev *display_dev = Dev::find (Display::ID, 0)
|
Dev *display_dev = Dev::find (Display::ID, 0)
|
||||||
if !display_dev:
|
if !display_dev:
|
||||||
Kernel::panic (0, "no display")
|
Kernel::panic (0, "no display")
|
||||||
Display display = display_dev->dev.create_user (Kernel::my_memory, 0, 0x15000)
|
Kernel::Caps display_caps = display_dev->dev.create_user (Kernel::my_memory, 0, 0x15000)
|
||||||
|
Display display = display_caps.get (0)
|
||||||
Dev *keyboard_dev = Dev::find (Keyboard::ID, 0)
|
Dev *keyboard_dev = Dev::find (Keyboard::ID, 0)
|
||||||
if !keyboard_dev:
|
if !keyboard_dev:
|
||||||
Kernel::panic (0, "no keyboard")
|
Kernel::panic (0, "no keyboard")
|
||||||
Keyboard keyboard = keyboard_dev->dev.create_user (Kernel::my_memory, 0, 0x15000)
|
Kernel::Caps keyboard_caps = keyboard_dev->dev.create_user (Kernel::my_memory, 0, 0x15000)
|
||||||
|
Keyboard keyboard = keyboard_caps.get (0)
|
||||||
kdebug ("init done\n")
|
kdebug ("init done\n")
|
||||||
root.unlock_ro ()
|
root.unlock_ro ()
|
||||||
Kernel::free_slot (slot)
|
Kernel::free_slot (slot)
|
||||||
@ -481,8 +490,8 @@ Kernel::Num start ():
|
|||||||
// System request.
|
// System request.
|
||||||
if Kernel::recv.data[0].l & Keyboard::RELEASE:
|
if Kernel::recv.data[0].l & Keyboard::RELEASE:
|
||||||
continue
|
continue
|
||||||
keyboard_dev->dev.use (keyboard)
|
keyboard_dev->dev.use (keyboard_caps)
|
||||||
display_dev->dev.use (display)
|
display_dev->dev.use (display_caps)
|
||||||
keyboard.set_cb (keyboard_cb)
|
keyboard.set_cb (keyboard_cb)
|
||||||
in_system = true
|
in_system = true
|
||||||
continue
|
continue
|
||||||
@ -540,15 +549,34 @@ Kernel::Num start ():
|
|||||||
break
|
break
|
||||||
if Kernel::recv.data[0].l & Keyboard::RELEASE:
|
if Kernel::recv.data[0].l & Keyboard::RELEASE:
|
||||||
continue
|
continue
|
||||||
|
unsigned const r = 50
|
||||||
|
unsigned which = 0
|
||||||
switch Kernel::recv.data[0].l:
|
switch Kernel::recv.data[0].l:
|
||||||
case Key::UP:
|
|
||||||
case Key::DOWN:
|
|
||||||
case Key::LEFT:
|
|
||||||
case Key::RIGHT:
|
|
||||||
case Key::VOLUME_UP:
|
|
||||||
case Key::VOLUME_DOWN:
|
case Key::VOLUME_DOWN:
|
||||||
kdebug ("key pressed.\n")
|
// Set ball.
|
||||||
|
for int y = -r; y < r; ++y:
|
||||||
|
for int x = -r; x < r; ++x:
|
||||||
|
if x * x + y * y > r * r:
|
||||||
|
((unsigned *)0x15000)[(120 + y) * 320 + 160 + x] = 0x000000
|
||||||
|
else:
|
||||||
|
((unsigned *)0x15000)[(120 + y) * 320 + 160 + x] = 0xffffff
|
||||||
|
which = 2
|
||||||
break
|
break
|
||||||
|
case Key::VOLUME_UP:
|
||||||
|
// Set square.
|
||||||
|
for int y = -r; y < r; ++y:
|
||||||
|
for int x = -r; x < r; ++x:
|
||||||
|
((unsigned *)0x15000)[(120 + y) * 320 + 160 + x] = 0xffffff
|
||||||
|
which = 1
|
||||||
|
break
|
||||||
|
if which != 0:
|
||||||
|
for Dev *d = Dev::devs; d; d = d->next:
|
||||||
|
if d->code != Display::ID || d->idx != 0:
|
||||||
|
continue
|
||||||
|
for unsigned f = 0; f < num_files; ++f:
|
||||||
|
if inuse[f * Dev::num_devs + d->id] == 0:
|
||||||
|
continue
|
||||||
|
inuse[f * Dev::num_devs + d->id] = (--which ? 2 : 1)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
Kernel::panic (Kernel::recv.protected_data.h, "unknown source of request")
|
Kernel::panic (Kernel::recv.protected_data.h, "unknown source of request")
|
||||||
|
@ -567,8 +567,8 @@ Kernel::Num start ():
|
|||||||
map_cpm ()
|
map_cpm ()
|
||||||
Udc udc
|
Udc udc
|
||||||
|
|
||||||
//Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG)
|
Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG)
|
||||||
//__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
||||||
udc.init ()
|
udc.init ()
|
||||||
Kernel::register_interrupt (IRQ_UDC)
|
Kernel::register_interrupt (IRQ_UDC)
|
||||||
Device fs_dev = Kernel::my_receiver.create_capability (FS)
|
Device fs_dev = Kernel::my_receiver.create_capability (FS)
|
||||||
|
61
devices.hhp
61
devices.hhp
@ -99,34 +99,75 @@ struct Device : public Kernel::Cap:
|
|||||||
void use (Kernel::Cap user):
|
void use (Kernel::Cap user):
|
||||||
ocall (user, CAP_MASTER_DIRECT | USE)
|
ocall (user, CAP_MASTER_DIRECT | USE)
|
||||||
// Convenience function for threads implementing a device.
|
// Convenience function for threads implementing a device.
|
||||||
static void host (unsigned id, unsigned ¤t_user, Kernel::Cap &reply, Kernel::Cap &arg):
|
static void host (unsigned id, unsigned ¤t_user, Kernel::Cap &reply, Kernel::Cap &arg, unsigned capssize = 3, unsigned (*create)(Kernel::Memory mem, Kernel::Caps caps) = NULL, void (*destroy)(unsigned id, Kernel::Caps caps) = NULL, void (*use)(unsigned id, Kernel::Caps caps) = NULL, void (*unuse)(unsigned id, Kernel::Caps caps) = NULL):
|
||||||
static unsigned last_user
|
static unsigned last_user
|
||||||
switch Kernel::recv.data[0].l:
|
switch Kernel::recv.data[0].l:
|
||||||
case Device::CREATE_USER:
|
case Device::CREATE_USER:
|
||||||
// Increment last_user; skip 0.
|
Kernel::Memory mem (arg)
|
||||||
// FIXME: if this really wraps, it is possible that two users share their id.
|
Kernel::Caps caps = mem.create_caps (capssize)
|
||||||
if !++last_user:
|
unsigned user
|
||||||
++last_user
|
if create:
|
||||||
Kernel::Cap c = Kernel::my_receiver.create_capability (Kernel::Num (last_user, id))
|
user = create (mem, caps)
|
||||||
reply.invoke (0, 0, c.copy ())
|
else:
|
||||||
|
// Increment last_user; skip 0.
|
||||||
|
// FIXME: if this really wraps, it is possible that two users share their id.
|
||||||
|
if !++last_user:
|
||||||
|
++last_user
|
||||||
|
user = last_user
|
||||||
|
Kernel::Cap c = Kernel::my_receiver.create_capability (Kernel::Num (user, id))
|
||||||
|
caps.set (0, c.copy ())
|
||||||
|
caps.set (1, mem.copy ())
|
||||||
|
reply.invoke (0, 0, caps.copy ())
|
||||||
Kernel::free_cap (c)
|
Kernel::free_cap (c)
|
||||||
|
Kernel::free_cap (caps)
|
||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
Kernel::free_cap (arg)
|
Kernel::free_cap (arg)
|
||||||
break
|
break
|
||||||
case Device::DESTROY_USER:
|
case Device::DESTROY_USER:
|
||||||
|
Kernel::Caps caps (arg)
|
||||||
|
Kernel::Cap c = caps.get (0)
|
||||||
|
Kernel::Num user = Kernel::my_receiver.get_protected (c)
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
if user.h != id:
|
||||||
|
Kernel::panic (user.h, "invalid id for destroy")
|
||||||
|
// TODO: unuse.
|
||||||
|
if destroy:
|
||||||
|
destroy (user.l, caps)
|
||||||
reply.invoke ()
|
reply.invoke ()
|
||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
Kernel::free_cap (arg)
|
Kernel::free_cap (arg)
|
||||||
break
|
break
|
||||||
case Device::USE:
|
case Device::USE:
|
||||||
current_user = Kernel::my_receiver.get_protected (arg).l
|
Kernel::Caps caps (arg)
|
||||||
|
Kernel::Cap c = caps.get (0)
|
||||||
|
Kernel::Num user = Kernel::my_receiver.get_protected (c)
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
if user.h != id:
|
||||||
|
Kernel::panic (user.h, "invalid id for use")
|
||||||
|
// TODO: send unuse signal.
|
||||||
|
current_user = user.l
|
||||||
|
if use:
|
||||||
|
use (user.l, caps)
|
||||||
|
c = caps.get (2)
|
||||||
|
c.invoke (1)
|
||||||
|
Kernel::free_cap (c)
|
||||||
reply.invoke ()
|
reply.invoke ()
|
||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
Kernel::free_cap (arg)
|
Kernel::free_cap (arg)
|
||||||
break
|
break
|
||||||
case Device::UNUSE:
|
case Device::UNUSE:
|
||||||
Kernel::Num p = Kernel::my_receiver.get_protected (arg)
|
Kernel::Caps caps (arg)
|
||||||
if p.h == id && current_user == p.l:
|
Kernel::Cap c = caps.get (0)
|
||||||
|
Kernel::Num user = Kernel::my_receiver.get_protected (c)
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
if user.h != id:
|
||||||
|
Kernel::panic (user.h, "invalid id for unuse")
|
||||||
|
if unuse:
|
||||||
|
unuse (user.l, caps)
|
||||||
|
if user.l == current_user:
|
||||||
|
c = caps.get (2)
|
||||||
|
c.invoke (0)
|
||||||
|
Kernel::free_cap (c)
|
||||||
current_user = 0
|
current_user = 0
|
||||||
reply.invoke ()
|
reply.invoke ()
|
||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
|
@ -296,9 +296,9 @@ static void memory_invoke (unsigned cmd, unsigned target, Kernel::Num protected_
|
|||||||
kThread *ret = mem->alloc_thread (c->data[1].l)
|
kThread *ret = mem->alloc_thread (c->data[1].l)
|
||||||
if ret:
|
if ret:
|
||||||
reply_cap (CAPTYPE_THREAD | CAP_MASTER, (unsigned)ret, &ret->refs)
|
reply_cap (CAPTYPE_THREAD | CAP_MASTER, (unsigned)ret, &ret->refs)
|
||||||
kdebug ("created thread: ")
|
kdebug ("(created thread ")
|
||||||
kdebug_num ((unsigned)ret)
|
kdebug_num ((unsigned)ret)
|
||||||
kdebug ("\n")
|
kdebug (")")
|
||||||
else:
|
else:
|
||||||
dpanic (0x23311992, "out of memory creating thread")
|
dpanic (0x23311992, "out of memory creating thread")
|
||||||
reply_num (Kernel::ERR_OUT_OF_MEMORY)
|
reply_num (Kernel::ERR_OUT_OF_MEMORY)
|
||||||
|
@ -27,9 +27,9 @@ LDFLAGS = --omagic -Ttext $(load)
|
|||||||
|
|
||||||
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||||
boot_sources = mips/init.cc mips/nanonote/board.cc
|
boot_sources = mips/init.cc mips/nanonote/board.cc
|
||||||
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh devices.hh
|
||||||
boot_threads = init udc
|
boot_threads = init udc
|
||||||
programs = \#nanonote-gpio \#buzzer \#lcd metronome ball display-emu
|
programs = \#nanonote-gpio \#lcd display-emu bsquare display-emu2 ball
|
||||||
|
|
||||||
all: test
|
all: test
|
||||||
|
|
||||||
|
@ -141,8 +141,8 @@ void panic_impl (unsigned n, const char *line, char const *name, char const *mes
|
|||||||
if arch_interrupt_receiver[i] && arch_interrupt_receiver[i]->owner:
|
if arch_interrupt_receiver[i] && arch_interrupt_receiver[i]->owner:
|
||||||
arch_interrupt_receiver[i]->owner->unrun ()
|
arch_interrupt_receiver[i]->owner->unrun ()
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// If a log capability is registered, run its owner.
|
|
||||||
panic_message (n, line, name, message)
|
panic_message (n, line, name, message)
|
||||||
|
// If a log capability is registered, run its owner.
|
||||||
#ifndef USE_SERIAL
|
#ifndef USE_SERIAL
|
||||||
if dbg_cap.valid () && dbg_cap->target->owner:
|
if dbg_cap.valid () && dbg_cap->target->owner:
|
||||||
dbg_cap->target->owner->run ()
|
dbg_cap->target->owner->run ()
|
||||||
|
@ -74,32 +74,9 @@ Kernel::Num start ():
|
|||||||
switch Kernel::recv.protected_data.l:
|
switch Kernel::recv.protected_data.l:
|
||||||
case BUZZER:
|
case BUZZER:
|
||||||
// Buzzer device control request.
|
// Buzzer device control request.
|
||||||
switch Kernel::recv.data[0].l:
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
case Device::CREATE_USER:
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
Kernel::Cap reply = Kernel::get_reply ()
|
Device::host (BUZZER, user, reply, arg)
|
||||||
Keyboard cap = Kernel::my_receiver.create_capability (Kernel::Num (next_user++, BUZZER))
|
|
||||||
reply.invoke (0, 0, cap.copy ())
|
|
||||||
Kernel::free_cap (cap)
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
break
|
|
||||||
case Device::DESTROY_USER:
|
|
||||||
Kernel::recv.reply.invoke ()
|
|
||||||
break
|
|
||||||
case Device::UNUSE:
|
|
||||||
buzzer.stop ()
|
|
||||||
Kernel::recv.reply.invoke ()
|
|
||||||
break
|
|
||||||
case Device::USE:
|
|
||||||
Kernel::Cap reply = Kernel::get_reply ()
|
|
||||||
user = Kernel::my_receiver.get_protected (Kernel::recv.arg).l
|
|
||||||
reply.invoke ()
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
kdebug ("invalid buzzer control command: ")
|
|
||||||
kdebug_num (Kernel::recv.data[0].l)
|
|
||||||
kdebug ("\n")
|
|
||||||
break
|
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
kdebug ("invalid buzzer request\n")
|
kdebug ("invalid buzzer request\n")
|
||||||
|
146
source/#lcd.ccp
146
source/#lcd.ccp
@ -257,6 +257,63 @@ static unsigned spot (unsigned x, unsigned y, unsigned cx, unsigned cy):
|
|||||||
return 0
|
return 0
|
||||||
return ((l * l - d2 - 1) << 8) / (l * l)
|
return ((l * l - d2 - 1) << 8) / (l * l)
|
||||||
|
|
||||||
|
static unsigned pages
|
||||||
|
static Descriptor descriptor __attribute__ ((aligned (16)))
|
||||||
|
static bool is_on
|
||||||
|
|
||||||
|
static unsigned create (Kernel::Memory mem, Kernel::Caps caps):
|
||||||
|
unsigned physical = mem.alloc_range (pages)
|
||||||
|
unsigned address = 0x15000
|
||||||
|
if physical & ~PAGE_MASK:
|
||||||
|
Kernel::panic (0, "can't allocate framebuffer")
|
||||||
|
assert (physical & PAGE_MASK && ~physical)
|
||||||
|
for unsigned i = 0; i < pages; ++i:
|
||||||
|
Kernel::Page p = mem.create_page ()
|
||||||
|
p.alloc_physical (physical + (i << PAGE_BITS), false, true)
|
||||||
|
if address != ~0:
|
||||||
|
mem.map (p, address + (i << PAGE_BITS))
|
||||||
|
Kernel::free_cap (p)
|
||||||
|
return physical
|
||||||
|
|
||||||
|
static void destroy (unsigned physical, Kernel::Caps caps):
|
||||||
|
unsigned address = 0x15000
|
||||||
|
Kernel::Memory mem = caps.get (1)
|
||||||
|
if physical == ~0:
|
||||||
|
Kernel::panic (0, "unable to destroy framebuffer with wrong cap0")
|
||||||
|
if descriptor.frame == physical && is_on:
|
||||||
|
lcd_clr_ena ()
|
||||||
|
#ifdef NANONOTE
|
||||||
|
write_reg (BACKLIGHT1, 0x5e)
|
||||||
|
#endif
|
||||||
|
if address != ~0:
|
||||||
|
for unsigned i = 0; i < pages; ++i:
|
||||||
|
Kernel::Page p = mem.mapping ((void *)(address + (i << PAGE_BITS)))
|
||||||
|
mem.destroy (p)
|
||||||
|
Kernel::free_cap (p)
|
||||||
|
|
||||||
|
static void use (unsigned physical, Kernel::Caps caps):
|
||||||
|
if physical == ~0:
|
||||||
|
Kernel::panic (0, "unable to use framebuffer with wrong cap0")
|
||||||
|
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
|
||||||
|
|
||||||
|
static void unuse (unsigned physical, Kernel::Caps caps):
|
||||||
|
if physical == ~0:
|
||||||
|
Kernel::panic (0, "unable to unuse framebuffer with wrong cap0")
|
||||||
|
if descriptor.frame == physical:
|
||||||
|
lcd_clr_ena ()
|
||||||
|
#ifdef NANONOTE
|
||||||
|
write_reg (BACKLIGHT1, 0x5e)
|
||||||
|
#endif
|
||||||
|
descriptor.frame = 0
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
Kernel::schedule ()
|
Kernel::schedule ()
|
||||||
map_lcd ()
|
map_lcd ()
|
||||||
@ -265,8 +322,7 @@ Kernel::Num start ():
|
|||||||
map_gpio ()
|
map_gpio ()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Descriptor descriptor __attribute__ ((aligned (16)))
|
pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
|
||||||
unsigned pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
|
|
||||||
#if 0
|
#if 0
|
||||||
unsigned physical = Kernel::my_memory.alloc_range (pages)
|
unsigned physical = Kernel::my_memory.alloc_range (pages)
|
||||||
assert (physical & PAGE_MASK && ~physical)
|
assert (physical & PAGE_MASK && ~physical)
|
||||||
@ -320,8 +376,8 @@ Kernel::Num start ():
|
|||||||
|
|
||||||
Kernel::Cap eof_cb
|
Kernel::Cap eof_cb
|
||||||
bool have_eof = false
|
bool have_eof = false
|
||||||
bool is_on = true
|
is_on = true
|
||||||
unsigned backlight_user = 0
|
unsigned lcd_user = 0
|
||||||
unsigned current_backlight = 0
|
unsigned current_backlight = 0
|
||||||
while true:
|
while true:
|
||||||
Kernel::wait ()
|
Kernel::wait ()
|
||||||
@ -347,87 +403,7 @@ Kernel::Num start ():
|
|||||||
case LCD:
|
case LCD:
|
||||||
Kernel::Cap reply = Kernel::get_reply ()
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
Kernel::Cap arg = Kernel::get_arg ()
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
switch Kernel::recv.data[0].l:
|
Device::host (LCD, lcd_user, reply, arg, 3, create, destroy, use, unuse)
|
||||||
case Device::CREATE_USER:
|
|
||||||
Kernel::Memory mem (arg)
|
|
||||||
unsigned width = Kernel::recv.data[0].h >> 16
|
|
||||||
unsigned height = Kernel::recv.data[0].h & 0xffff
|
|
||||||
unsigned mode = Kernel::recv.data[1].l & ~PAGE_MASK
|
|
||||||
unsigned address = Kernel::recv.data[1].l & PAGE_MASK
|
|
||||||
if (width != 0 && width != h) || (height != 0 && height != v) || mode != 0:
|
|
||||||
reply.invoke (Kernel::ERR_INVALID_ARGUMENT)
|
|
||||||
kdebug ("invalid framebuffer requested\n")
|
|
||||||
Kernel::panic (0)
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
Kernel::free_cap (arg)
|
|
||||||
break
|
|
||||||
unsigned physical = mem.alloc_range (pages)
|
|
||||||
if physical & ~PAGE_MASK:
|
|
||||||
kdebug ("can't allocate framebuffer\n")
|
|
||||||
Kernel::panic (0)
|
|
||||||
assert (physical & PAGE_MASK && ~physical)
|
|
||||||
Kernel::Cap ret = Kernel::my_receiver.create_capability (Kernel::Num (physical, LCD))
|
|
||||||
for unsigned i = 0; i < pages; ++i:
|
|
||||||
Kernel::Page p = mem.create_page ()
|
|
||||||
p.alloc_physical (physical + (i << PAGE_BITS), false, true)
|
|
||||||
if address != ~0:
|
|
||||||
//Kernel::panic (0xdeaddead)
|
|
||||||
mem.map (p, address + (i << PAGE_BITS))
|
|
||||||
Kernel::free_cap (p)
|
|
||||||
reply.invoke (0, 0, ret.copy ())
|
|
||||||
Kernel::free_cap (ret)
|
|
||||||
break
|
|
||||||
case Device::DESTROY_USER:
|
|
||||||
//Kernel::Memory mem (arg)
|
|
||||||
unsigned address = Kernel::recv.data[1].l & PAGE_MASK
|
|
||||||
unsigned physical = Kernel::my_receiver.get_protected (arg).l
|
|
||||||
if physical == ~0:
|
|
||||||
kdebug ("unable to destroy framebuffer with wrong cap0\n")
|
|
||||||
Kernel::panic (0)
|
|
||||||
break
|
|
||||||
if descriptor.frame == physical && is_on:
|
|
||||||
lcd_clr_ena ()
|
|
||||||
#ifdef NANONOTE
|
|
||||||
write_reg (BACKLIGHT1, 0x5e)
|
|
||||||
#endif
|
|
||||||
//for unsigned i = 0; i < pages; ++i:
|
|
||||||
//if address != ~0:
|
|
||||||
//Kernel::Page p = mem.mapping ((void *)(address + (i << PAGE_BITS)))
|
|
||||||
//mem.destroy (p)
|
|
||||||
//Kernel::free_cap (p)
|
|
||||||
reply.invoke ()
|
|
||||||
break
|
|
||||||
case Device::USE:
|
|
||||||
unsigned physical = Kernel::my_receiver.get_protected (arg).l
|
|
||||||
if physical == ~0:
|
|
||||||
Kernel::panic (0, "unable to use framebuffer with wrong cap0")
|
|
||||||
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
|
|
||||||
reply.invoke ()
|
|
||||||
break
|
|
||||||
case Device::UNUSE:
|
|
||||||
unsigned physical = Kernel::my_receiver.get_protected (arg).l
|
|
||||||
if physical == ~0:
|
|
||||||
Kernel::panic (0, "unable to unuse framebuffer with wrong cap0")
|
|
||||||
if descriptor.frame == physical:
|
|
||||||
lcd_clr_ena ()
|
|
||||||
#ifdef NANONOTE
|
|
||||||
write_reg (BACKLIGHT1, 0x5e)
|
|
||||||
#endif
|
|
||||||
descriptor.frame = 0
|
|
||||||
reply.invoke ()
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
Kernel::panic (0, "invalid operation for lcd device")
|
|
||||||
Kernel::free_cap (arg)
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
Kernel::panic (Kernel::recv.protected_data.l, "invalid operation for master lcd")
|
Kernel::panic (Kernel::recv.protected_data.l, "invalid operation for master lcd")
|
||||||
|
43
source/bsquare.ccp
Normal file
43
source/bsquare.ccp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pypp 0
|
||||||
|
#include <iris.hh>
|
||||||
|
#include <devices.hh>
|
||||||
|
|
||||||
|
static unsigned *framebuffer
|
||||||
|
static int const r = 10
|
||||||
|
static int colour
|
||||||
|
|
||||||
|
void square (int x, int y, bool print):
|
||||||
|
for int ty = y - r; ty < y + r; ++ty:
|
||||||
|
if ty < 0 || ty >= 240:
|
||||||
|
continue
|
||||||
|
for int tx = x - r; tx < x + r; ++tx:
|
||||||
|
if tx < 0 || tx >= 320:
|
||||||
|
continue
|
||||||
|
framebuffer[ty * 320 + tx] = (print ? colour : 0)
|
||||||
|
|
||||||
|
Kernel::Num start ():
|
||||||
|
Kernel::my_parent.init_done ()
|
||||||
|
colour = 0xffffff
|
||||||
|
framebuffer = (unsigned *)0x15000
|
||||||
|
Display display = Kernel::my_parent.get_device <Display> (0x10001)
|
||||||
|
int x = r, y = r, dx = 3, dy = 3
|
||||||
|
Kernel::Cap eof = Kernel::my_receiver.create_capability (0)
|
||||||
|
while true:
|
||||||
|
display.set_eof_cb (eof)
|
||||||
|
Kernel::wait ()
|
||||||
|
square (x, y, false)
|
||||||
|
x += dx
|
||||||
|
y += dy
|
||||||
|
if y + r >= 240:
|
||||||
|
dy = -dy
|
||||||
|
y = 240 - r
|
||||||
|
if x - r < 0:
|
||||||
|
x = r
|
||||||
|
dx = -dx
|
||||||
|
if x + r >= 320:
|
||||||
|
x = 320 - r
|
||||||
|
dx = -dx
|
||||||
|
if y - r < 0:
|
||||||
|
y = r
|
||||||
|
dy = -dy
|
||||||
|
square (x, y, true)
|
@ -17,7 +17,11 @@ Kernel::Num start ():
|
|||||||
switch Kernel::recv.data[0].l:
|
switch Kernel::recv.data[0].l:
|
||||||
case Device::CREATE_USER:
|
case Device::CREATE_USER:
|
||||||
Kernel::Memory mem (arg)
|
Kernel::Memory mem (arg)
|
||||||
|
Kernel::Caps ret = mem.create_caps (3)
|
||||||
Kernel::Cap target = Kernel::my_receiver.create_capability (Kernel::Num (0, 1))
|
Kernel::Cap target = Kernel::my_receiver.create_capability (Kernel::Num (0, 1))
|
||||||
|
ret.set (0, target.copy ())
|
||||||
|
ret.set (1, mem)
|
||||||
|
Kernel::free_cap (target)
|
||||||
for unsigned i = 0; i < 320 * 240 * 4; i += PAGE_SIZE:
|
for unsigned i = 0; i < 320 * 240 * 4; i += PAGE_SIZE:
|
||||||
Kernel::Page p = Kernel::my_memory.mapping ((void *)(0x15000 + i))
|
Kernel::Page p = Kernel::my_memory.mapping ((void *)(0x15000 + i))
|
||||||
Kernel::Page t = mem.create_page ()
|
Kernel::Page t = mem.create_page ()
|
||||||
@ -27,8 +31,8 @@ Kernel::Num start ():
|
|||||||
Kernel::my_memory.destroy (t)
|
Kernel::my_memory.destroy (t)
|
||||||
Kernel::free_cap (t)
|
Kernel::free_cap (t)
|
||||||
Kernel::free_cap (p)
|
Kernel::free_cap (p)
|
||||||
reply.invoke (0, 0, target)
|
reply.invoke (0, 0, ret.copy ())
|
||||||
Kernel::free_cap (target)
|
Kernel::free_cap (ret)
|
||||||
break
|
break
|
||||||
case Device::DESTROY_USER:
|
case Device::DESTROY_USER:
|
||||||
Kernel::panic (0, "destroying emulation user")
|
Kernel::panic (0, "destroying emulation user")
|
||||||
|
1
source/display-emu2.ccp
Symbolic link
1
source/display-emu2.ccp
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
display-emu.ccp
|
Loading…
Reference in New Issue
Block a user