1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-09-28 22:02:54 +03:00

work on device swapping

This commit is contained in:
Bas Wijnen 2010-01-30 09:21:56 +01:00
parent 06390fd2d1
commit cba0cf31e5
11 changed files with 208 additions and 108 deletions

View File

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Define some variables.
SERIAL = /dev/ttyUSB0
CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -nostdinc $(ARCH_CXXFLAGS) -ggdb3
CPPFLAGS = -O5 -fno-inline $(ARCH_CPPFLAGS)
CC = $(CROSS)gcc
@ -54,8 +55,8 @@ clean:
rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES)
debug:
stty -F /dev/ttyS0 raw 9600
cat /dev/ttyS0
stty -F $(SERIAL) raw 9600
cat $(SERIAL)
.PHONY: clean
.PRECIOUS: iris.hh kernel.hh boot-programs/crt0.o

View File

@ -18,6 +18,7 @@
#include "devices.hh"
#include "iris.hh"
#include "keys.hh"
#include <elf.h>
#define NUM_SLOTS 8
@ -26,6 +27,7 @@
enum Cap_codes:
SYSREQ = 1 << 16
THREAD
KEYBOARD
static unsigned _free
extern unsigned _end
@ -79,6 +81,7 @@ static Kernel::Caps terminals
static unsigned terminal_slot
static Kernel::Caps memories
static unsigned memory_slot
static unsigned *inuse
// Get the initial block device and filesystem.
static Directory receive_devices ():
@ -89,30 +92,24 @@ static Directory receive_devices ():
for unsigned i = 0; i < 2; ++i:
Kernel::wait ()
if Kernel::recv.data[0].l != Parent::PROVIDE_DEVICE:
kdebug ("Invalid bootstrap request.\n")
Kernel::panic (0)
Kernel::panic (Kernel::recv.data[0].l, "Invalid bootstrap request.")
switch Kernel::recv.data[1].l:
case String::ID:
if have_data:
kdebug ("duplicate device.\n")
Kernel::panic (0)
Kernel::panic (0, "duplicate device.")
data_dev = Kernel::get_arg ()
Kernel::recv.reply.invoke ()
have_data = true
break
case Filesystem::ID:
if have_fs:
kdebug ("duplicate filesystem.\n")
Kernel::panic (0)
Kernel::panic (0, "duplicate filesystem.")
fs_dev = Kernel::get_arg ()
Kernel::recv.reply.invoke ()
have_fs = true
break
default:
kdebug ("unexpected device: ")
kdebug_num (Kernel::recv.data[1].l)
kdebug_char ('\n')
Kernel::panic (0)
Kernel::panic (Kernel::recv.data[1].l, "unexpected device")
// Initialize the root file system.
data = data_dev.create_user (Kernel::my_memory)
data_dev.use (data)
@ -204,8 +201,7 @@ static void run (file *f, bool priv, int id):
Elf32_Ehdr *header = (Elf32_Ehdr *)mapping
for unsigned j = 0; j < SELFMAG; ++j:
if header->e_ident[j] != ELFMAG[j]:
kdebug ("invalid ELF magic\n")
Kernel::panic (0)
Kernel::panic (header->e_ident[j], "invalid ELF magic")
return
if header->e_ident[EI_CLASS] != ELFCLASS32:
kdebug ("invalid ELF class:")
@ -216,21 +212,13 @@ static void run (file *f, bool priv, int id):
Kernel::panic (0)
return
if header->e_ident[EI_DATA] != ELFDATA2LSB:
kdebug ("invalid ELF data\n")
Kernel::panic (0)
return
Kernel::panic (header->e_ident[EI_DATA], "invalid ELF data")
if header->e_ident[EI_VERSION] != EV_CURRENT:
kdebug ("invalid ELF version\n")
Kernel::panic (0)
return
Kernel::panic (header->e_ident[EI_VERSION], "invalid ELF version")
if header->e_type != ET_EXEC:
kdebug ("invalid ELF type\n")
Kernel::panic (0)
return
Kernel::panic (header->e_type, "invalid ELF type")
if header->e_machine != EM_MIPS_RS3_LE && header->e_machine != EM_MIPS:
kdebug ("invalid ELF machine\n")
Kernel::panic (0)
return
Kernel::panic (header->e_machine, "invalid ELF machine")
thread.set_pc (header->e_entry)
thread.set_sp (0x80000000)
for unsigned section = 0; section < header->e_shnum; ++section:
@ -242,8 +230,7 @@ static void run (file *f, bool priv, int id):
if shdr->sh_type != SHT_NOBITS:
unsigned file_offset = shdr->sh_offset >> PAGE_BITS
if (file_offset + ((shdr->sh_size + PAGE_SIZE - 1) >> PAGE_BITS)) >= (PAGE_SIZE >> 2):
kdebug ("thread too large\n")
Kernel::panic (0)
Kernel::panic (shdr->sh_size, "thread too large")
return
for unsigned p = (shdr->sh_addr & PAGE_MASK); p < shdr->sh_addr + shdr->sh_size; p += PAGE_SIZE:
unsigned section_offset = (p - (shdr->sh_addr & PAGE_MASK)) >> PAGE_BITS
@ -268,14 +255,12 @@ static void run (file *f, bool priv, int id):
// kdebug (" (readonly)")
//kdebug ("\n")
if !mem.map (page, p):
kdebug ("unable to map page\n")
Kernel::panic (0)
Kernel::panic (0, "unable to map page")
return
Kernel::free_cap (page)
else:
if readonly:
kdebug ("unwritable bss section\n")
Kernel::panic (0)
Kernel::panic (0, "unwritable bss section")
return
for unsigned p = (shdr->sh_addr & PAGE_MASK); p < shdr->sh_addr + shdr->sh_size; p += PAGE_SIZE:
Kernel::Page page = mem.mapping ((void *)p)
@ -292,26 +277,18 @@ static void run (file *f, bool priv, int id):
Kernel::free_cap (page)
page = mem.create_page ()
if Kernel::recv.data[0].l != Kernel::NO_ERROR:
kdebug ("out of memory\n")
Kernel::panic (0)
return
Kernel::panic (Kernel::recv.data[0].l, "out of memory")
if !page.set_flags (Kernel::Page::PAYING | Kernel::Page::FRAME, Kernel::Page::PAYING | Kernel::Page::FRAME):
kdebug ("out of memory\n")
Kernel::panic (0)
return
Kernel::panic (0, "out of memory")
if !mem.map (page, p):
kdebug ("unable to map bss page\n")
Kernel::panic (0)
return
Kernel::panic (0, "unable to map bss page")
Kernel::free_cap (page)
for unsigned p = 0; p < num_pages; ++p:
Kernel::my_memory.destroy (Kernel::Page (slot, p))
Kernel::Page stackpage = mem.create_page ()
stackpage.set_flags (Kernel::Page::PAYING | Kernel::Page::FRAME, Kernel::Page::PAYING | Kernel::Page::FRAME)
if Kernel::recv.data[0].l != Kernel::NO_ERROR || !mem.map (stackpage, 0x7ffff000):
kdebug ("unable to map initial stack page\n")
Kernel::panic (0)
return
Kernel::panic (Kernel::recv.data[0].l, "unable to map initial stack page")
Kernel::free_cap (stackpage)
Kernel::Caps caps = mem.create_caps (NUM_CAPS)
thread.use (caps, 0)
@ -405,6 +382,8 @@ static void get_device ():
unsigned id = Kernel::recv.protected_data.l
Dev *d = Dev::find (Kernel::recv.data[1].l, Kernel::recv.data[0].h)
if d:
if inuse[id * Dev::num_devs + d->id] > 0:
Kernel::panic (id, "requesting device twice")
kdebug ("giving dev ")
kdebug_num (Kernel::recv.data[1].l)
kdebug (":")
@ -414,7 +393,12 @@ static void get_device ():
kdebug (" to ")
kdebug_num (id)
kdebug ("\n")
Kernel::Cap cap = Kernel::Caps (terminal_slot, id).get (d->id)
Kernel::Cap cap = d->dev.create_user (Kernel::Memory (memory_slot, id), 0, 0x15000)
Kernel::Caps (terminal_slot, id).set (d->id, cap.copy ())
for unsigned i = 0; i < num_files; ++i:
if inuse[i * Dev::num_devs + d->id] == 2:
inuse[i * Dev::num_devs + d->id] = 1
inuse[id * Dev::num_devs + d->id] = 2
d->dev.use (cap)
reply.invoke (0, 0, cap.copy ())
Kernel::free_cap (cap)
@ -453,6 +437,10 @@ Kernel::Num start ():
run (&files[index[i]], files[index[i]].name[0] == '#', i)
kdebug ("running\n")
handle_init (i)
inuse = new unsigned[num_files * Dev::num_devs]
for unsigned f = 0; f < num_files; ++f:
for unsigned d = 0; d < Dev::num_devs; ++d:
inuse[f * Dev::num_devs + d] = 0
// Notify all programs that they may start.
for unsigned i = 0; i < num_files; ++i:
Kernel::Cap (memory_slot, i + num_files).invoke ()
@ -462,12 +450,6 @@ Kernel::Num start ():
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)
@ -476,10 +458,22 @@ Kernel::Num start ():
sysreq.set_cb (cap.copy ())
Kernel::free_cap (sysreq)
Kernel::free_cap (cap)
// set up own capabilities.
Dev *display_dev = Dev::find (Display::ID, 0)
if !display_dev:
Kernel::panic (0, "no display")
Display display = display_dev->dev.create_user (Kernel::my_memory, 0, 0x15000)
Dev *keyboard_dev = Dev::find (Keyboard::ID, 0)
if !keyboard_dev:
Kernel::panic (0, "no keyboard")
Keyboard keyboard = keyboard_dev->dev.create_user (Kernel::my_memory, 0, 0x15000)
kdebug ("init done\n")
root.unlock_ro ()
Kernel::free_slot (slot)
Kernel::my_memory.destroy (caps)
Dev **waiter = new Dev *[num_files]
Kernel::Cap keyboard_cb = Kernel::my_receiver.create_capability (Kernel::Num (0, KEYBOARD))
bool in_system = false
while true:
Kernel::wait ()
switch Kernel::recv.protected_data.h:
@ -487,7 +481,10 @@ Kernel::Num start ():
// System request.
if Kernel::recv.data[0].l & Keyboard::RELEASE:
continue
kdebug ("system request...\n")
keyboard_dev->dev.use (keyboard)
display_dev->dev.use (display)
keyboard.set_cb (keyboard_cb)
in_system = true
continue
case THREAD:
// Request for something from a child thread.
@ -499,10 +496,59 @@ Kernel::Num start ():
case Parent::GET_DEVICE:
get_device ()
break
case Parent::WAIT:
unsigned id = Kernel::recv.protected_data.l
Dev *dev = Dev::find (Kernel::recv.data[1].l, 0)
if id >= num_files:
Kernel::panic (0, "invalid id")
if !dev:
Kernel::panic (0, "invalid dev")
switch inuse[id * Dev::num_devs + dev->id]:
case 0:
Kernel::panic (0, "waiting for non-owned device")
case 2:
if !in_system:
Kernel::recv.reply.invoke ()
break
// fall through.
case 1:
Kernel::Cap reply = Kernel::get_reply ()
memories.set (id + num_files, reply.copy ())
Kernel::free_cap (reply)
waiter[id] = dev
break
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
case KEYBOARD:
if in_system && Kernel::recv.data[0].l == (Key::ENTER | Keyboard::RELEASE):
for Dev *d = Dev::devs; d; d = d->next:
if d->idx != 0:
continue
for unsigned i = 0; i < num_files; ++i:
if inuse[i * Dev::num_devs + d->id] == 2:
Kernel::Cap c = Kernel::Caps (terminal_slot, i).get (d->id)
d->dev.use (c)
Kernel::free_cap (c)
if waiter[i] == d:
Kernel::Cap (memory_slot, i + num_files).invoke ()
waiter[i] = NULL
in_system = false
break
if Kernel::recv.data[0].l & Keyboard::RELEASE:
continue
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:
kdebug ("key pressed.\n")
break
break
default:
Kernel::panic (Kernel::recv.protected_data.h, "unknown source of request")

View File

@ -139,6 +139,7 @@ struct Parent : public Kernel::Cap:
enum request:
GET_DEVICE = Device::ID
PROVIDE_DEVICE
WAIT
GET_MEMORY
PROVIDE_MEMORY
INIT_DONE
@ -151,6 +152,9 @@ struct Parent : public Kernel::Cap:
// Provide a device handle.
template <typename _T> void provide_device (Device dev, unsigned num = 0):
ocall (dev, Kernel::Num (CAP_MASTER_DIRECT | PROVIDE_DEVICE, num), _T::ID)
// Wait until a device is used by the caller again.
template <typename _T> void wait (unsigned num = 0):
call (Kernel::Num (CAP_MASTER_DIRECT | WAIT, num), _T::ID)
// Get memory paid for by another thread, which cannot be inspected or changed by that thread. The memory can be inspected and changed by the user (owning both threads). The call will fail when the threads are not owned by the same user.
Kernel::Memory get_memory (Kernel::Cap target):
iocall (target, CAP_MASTER_DIRECT | GET_MEMORY)

View File

@ -296,9 +296,9 @@ static void memory_invoke (unsigned cmd, unsigned target, Kernel::Num protected_
kThread *ret = mem->alloc_thread (c->data[1].l)
if ret:
reply_cap (CAPTYPE_THREAD | CAP_MASTER, (unsigned)ret, &ret->refs)
//kdebug ("created thread: ")
//kdebug_num ((unsigned)ret)
//kdebug ("\n")
kdebug ("created thread: ")
kdebug_num ((unsigned)ret)
kdebug ("\n")
else:
dpanic (0x23311992, "out of memory creating thread")
reply_num (Kernel::ERR_OUT_OF_MEMORY)
@ -838,7 +838,7 @@ static void caps_invoke (unsigned cmd, unsigned target, Kernel::Num protected_da
kdebug ('\n')
return
default:
dpanic (0, "invalid caps operation")
dpanic (cmd, "invalid caps operation")
reply_num (Kernel::ERR_INVALID_OPERATION)
return

View File

@ -344,7 +344,7 @@ void kCapability::invoke (kCapability::Context *c):
::invoke (target, protected_data, c)
kCapability *kCaps::cap (unsigned idx):
if idx >= size:
dpanic (idx, "invalid capability requested\n")
dpanic (idx, "invalid capability requested")
return NULL
return &caps[idx]

View File

@ -29,7 +29,7 @@ arch_iris_sources = mips/interrupts.cc mips/arch.cc
boot_sources = mips/init.cc mips/nanonote/board.cc
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
boot_threads = init udc
programs = \#nanonote-gpio \#buzzer \#lcd metronome ball
programs = \#nanonote-gpio \#buzzer \#lcd metronome ball display-emu
all: test
@ -78,12 +78,8 @@ server:
servers:
while : ; do $(MAKE) server ; done
monitor:
stty -F /dev/ttyS0 raw 9600
cat /dev/ttyS0
setup:
x-terminal-emulator -e make monitor
x-terminal-emulator -e make debug
x-terminal-emulator -e make servers
ARCH_CLEAN_FILES = $(boot_sources) $(addsuffix .elf,$(boot_threads)) $(arch_headers) devices.hh keys.hh mips/*.o mips/nanonote/*.o source/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw

10
plan
View File

@ -26,3 +26,13 @@ top
- - - - program
- - user session
...
te doen:
- caps in init met een cap per process
- die cap bevat caps in target memory met een cap per service
- die cap bevat een user van de service
- sysreq is geen aangeboden service, usbfs wel
- sysreq schakelt tussen running processes incl. user switching.
- display interface: put pixel commando
- typewriter: print toetsen op scherm; shell?

View File

@ -178,7 +178,7 @@ static void reset ():
// Reset the controller.
write_reg (BACKLIGHT1, 0x1e)
// Enable display.
write_reg (BACKLIGHT1, 0x5f)
write_reg (BACKLIGHT1, 0x5e)
// Set data to rgbrgbrgb input, with a delta color filter.
write_reg (COLOR, 0x01)
#endif
@ -361,16 +361,12 @@ Kernel::Num start ():
Kernel::free_cap (reply)
Kernel::free_cap (arg)
break
Kernel::Caps caps = mem.create_caps (4)
caps.set (1, mem.copy ())
unsigned slot = caps.use ()
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::set_recv_arg (Kernel::Cap (slot, 0))
Kernel::my_receiver.create_capability (Kernel::Num (physical, LCD))
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)
@ -378,13 +374,13 @@ Kernel::Num start ():
//Kernel::panic (0xdeaddead)
mem.map (p, address + (i << PAGE_BITS))
Kernel::free_cap (p)
Kernel::free_slot (slot)
reply.invoke (0, 0, caps.copy ())
Kernel::free_cap (caps)
reply.invoke (0, 0, ret.copy ())
Kernel::free_cap (ret)
break
case Device::DESTROY_USER:
unsigned slot = Kernel::Caps (arg).use ()
unsigned physical = Kernel::my_receiver.get_protected (Kernel::Cap (slot, 0)).l
//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)
@ -394,22 +390,18 @@ Kernel::Num start ():
#ifdef NANONOTE
write_reg (BACKLIGHT1, 0x5e)
#endif
Kernel::Memory mem = Kernel::Cap (slot, 1)
for unsigned i = 0; i < pages; ++i:
mem.destroy (Kernel::Cap (slot, 2 + i))
mem.destroy (arg)
Kernel::free_slot (slot)
//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:
Kernel::Cap first = Kernel::Caps (arg).get (0)
unsigned physical = Kernel::my_receiver.get_protected (first).l
unsigned physical = Kernel::my_receiver.get_protected (arg).l
if physical == ~0:
kdebug ("unable to use framebuffer with wrong cap0\n")
Kernel::panic (0)
break
Kernel::free_cap (first)
bool was_unused = descriptor.frame == ~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")
@ -421,18 +413,15 @@ Kernel::Num start ():
reply.invoke ()
break
case Device::UNUSE:
Kernel::Cap first = Kernel::Caps (arg).get (0)
unsigned physical = Kernel::my_receiver.get_protected (first).l
unsigned physical = Kernel::my_receiver.get_protected (arg).l
if physical == ~0:
kdebug ("unable to unuse framebuffer with wrong cap0\n")
Kernel::panic (0)
break
Kernel::free_cap (first)
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:
@ -480,8 +469,8 @@ Kernel::Num start ():
break
case LCD:
if descriptor.frame != Kernel::recv.protected_data.l:
kdebug ("invalid user requesting lcd\n")
Kernel::panic (0)
//Kernel::panic (0, "invalid user requesting lcd")
Kernel::recv.reply.invoke (~0)
break
switch Kernel::recv.data[0].l:
case Display::SET_EOF_CB:
@ -489,8 +478,7 @@ Kernel::Num start ():
Kernel::Cap arg = Kernel::get_arg ()
if have_eof:
Kernel::free_cap (eof_cb)
kdebug ("replacing eof_cb\n")
Kernel::panic (0)
Kernel::panic (0, "replacing eof_cb")
else:
lcd_clr_eof ()
Kernel::register_interrupt (IRQ_LCD)
@ -500,10 +488,9 @@ Kernel::Num start ():
Kernel::free_cap (reply)
break
case Display::GET_INFO:
kdebug ("get_info isn't defined yet.\n")
Kernel::panic (0)
Kernel::panic (0, "get_info isn't defined yet.")
default:
Kernel::panic (0, "invalid operation for lcd")
Kernel::panic (Kernel::recv.data[0].l, "invalid operation for lcd")
break
default:
Kernel::panic (0, "invalid master operation type for lcd")

View File

@ -4,10 +4,9 @@
static unsigned *framebuffer
static int const r = 10
static int colour
void ball (int x, int y, bool print):
static unsigned bg
static unsigned count
for int ty = y - r; ty < y + r; ++ty:
if ty < 0 || ty >= 240:
continue
@ -16,16 +15,13 @@ void ball (int x, int y, bool print):
continue
if (x - tx) * (x - tx) + (y - ty) * (y - ty) > r * r:
continue
framebuffer[ty * 320 + tx] = (print ? 0xffffff : bg)
if ++count >= 30:
bg += 0x010307
count = 0
framebuffer[ty * 320 + tx] = (print ? colour : 0)
Kernel::Num start ():
Kernel::my_parent.init_done ()
colour = 0xffffff
framebuffer = (unsigned *)0x15000
Kernel::Caps caps = Kernel::my_parent.get_device <Display> ()
Display display = caps.get (0)
Display display = Kernel::my_parent.get_device <Display> (0x10000)
int x = r, y = r, dx = 3, dy = 0
Kernel::Cap eof = Kernel::my_receiver.create_capability (0)
while true:

View File

@ -871,7 +871,6 @@ import sys
charsize = 25 * 4 + 1
for c in range (128 - 32):
line = []
for l in range (8):
offset = 2 + c * charsize + 25 * (l >> 1) + 12 * (l & 1)
ln = ""

61
source/display-emu.ccp Normal file
View File

@ -0,0 +1,61 @@
#pypp 0
#include <devices.hh>
#include <iris.hh>
Kernel::Num start ():
Device d = Kernel::my_receiver.create_capability (0)
Kernel::my_parent.provide_device <Display> (d.copy (), 0x10000)
Kernel::free_cap (d)
Kernel::my_parent.init_done ()
Display real = Kernel::my_parent.get_device <Display> (0)
while true:
Kernel::wait ()
Kernel::Cap arg = Kernel::get_arg ()
Kernel::Cap reply = Kernel::get_reply ()
switch Kernel::recv.protected_data.h:
case 0:
switch Kernel::recv.data[0].l:
case Device::CREATE_USER:
Kernel::Memory mem (arg)
Kernel::Cap target = Kernel::my_receiver.create_capability (Kernel::Num (0, 1))
for unsigned i = 0; i < 320 * 240 * 4; i += PAGE_SIZE:
Kernel::Page p = Kernel::my_memory.mapping ((void *)(0x15000 + i))
Kernel::Page t = mem.create_page ()
t.set_flags (Kernel::Page::PAYING, Kernel::Page::PAYING)
p.share (t, Kernel::Page::FORGET)
mem.map (t, 0x15000 + i)
Kernel::my_memory.destroy (t)
Kernel::free_cap (t)
Kernel::free_cap (p)
reply.invoke (0, 0, target)
Kernel::free_cap (target)
break
case Device::DESTROY_USER:
Kernel::panic (0, "destroying emulation user")
case Device::USE:
case Device::UNUSE:
reply.invoke ()
break
default:
kdebug_num (Kernel::recv.data[0].l)
kdebug ("\n")
Kernel::panic (0, "invalid emulation command")
break
case 1:
switch Kernel::recv.data[0].l:
case Display::SET_EOF_CB:
real.set_eof_cb (arg.copy ())
while Kernel::recv.data[0].l != 0:
Kernel::my_parent.wait <Display> (0)
real.set_eof_cb (arg.copy ())
reply.invoke ()
break
default:
kdebug_num (Kernel::recv.data[0].l)
kdebug_char ('\n')
Kernel::panic (Kernel::recv.data[0].l, "invalid operation on display emulation")
break
default:
Kernel::panic (0, "bug in display emulation")
Kernel::free_cap (arg)
Kernel::free_cap (reply)