mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-12-28 12:39:52 +02:00
use automake
This commit is contained in:
parent
538b9b9361
commit
d9a12225eb
69
Makefile
69
Makefile
@ -1,69 +0,0 @@
|
||||
# Iris: micro-kernel for a capability-based operating system.
|
||||
# Makefile: build rules
|
||||
# Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# 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
|
||||
LD = $(CROSS)ld
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
headers = kernel.hh iris.hh devices.hh ui.hh keys.hh $(arch_headers)
|
||||
iris_sources = panic.cc data.cc alloc.cc memory.cc invoke.cc schedule.cc $(arch_iris_sources)
|
||||
BUILT_SOURCES = $(iris_sources) $(boot_sources)
|
||||
|
||||
STRIPFLAG = -S
|
||||
|
||||
# Include arch-specific rules.
|
||||
include Makefile.arch
|
||||
|
||||
# Disable implicit rules.
|
||||
%.o: %.S
|
||||
%.o: %.cc
|
||||
|
||||
PYPP = /usr/bin/pypp
|
||||
%.cc: %.ccp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
%.hh: %.hhp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
|
||||
%.o:%.cc Makefile Makefile.arch $(headers)
|
||||
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
%.elf: boot-programs/crt0.o boot-programs/%.o
|
||||
$(LD) $(LDFLAGS) $(filter %.o,$^) -o $@
|
||||
$(OBJCOPY) $(STRIPFLAG) $(OBJCOPYFLAGS) $@
|
||||
|
||||
fs/%.elf: source/crt0.o source/%.o fs/init.config
|
||||
$(LD) $(LDFLAGS) $(filter %.o,$^) -o $@
|
||||
$(OBJCOPY) $(STRIPFLAG) $(OBJCOPYFLAGS) $@
|
||||
|
||||
fs/%: %
|
||||
test -d fs || mkdir fs
|
||||
ln -s ../$< $@
|
||||
|
||||
clean:
|
||||
rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES)
|
||||
rm -rf fs/
|
||||
|
||||
debug:
|
||||
stty -F $(SERIAL) raw 57600
|
||||
while : ; do cat $(SERIAL) ; done
|
||||
|
||||
.PHONY: clean
|
||||
.PRECIOUS: $(headers) boot-programs/crt0.o source/crt0.o
|
150
Makefile.am
Normal file
150
Makefile.am
Normal file
@ -0,0 +1,150 @@
|
||||
# Iris: micro-kernel for a capability-based operating system.
|
||||
# Makefile.am: build rules
|
||||
# Copyright 2009-2012 Bas Wijnen <wijnen@debian.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AUTOMAKE_OPTIONS = subdir-objects foreign
|
||||
|
||||
# Define some variables.
|
||||
OBJCOPY = $(host_alias)-objcopy
|
||||
SERIAL = /dev/ttyUSB0
|
||||
junk = mdebug.abi32 reginfo comment pdr note.gnu.build-id
|
||||
objcopyflags = -S $(addprefix --remove-section=.,$(junk))
|
||||
|
||||
start_load = 0x80400000
|
||||
load = 0x80000000
|
||||
|
||||
noinst_DATA = iris.raw
|
||||
noinst_PROGRAMS = iris.elf
|
||||
|
||||
%.raw: %.elf
|
||||
$(OBJCOPY) $(objcopyflags) -Obinary $< $@
|
||||
|
||||
# Define boot_threads depending on selected mode.
|
||||
if UDC
|
||||
boot_threads = bootinit udc
|
||||
else
|
||||
if UNBRICK
|
||||
boot_threads = nand sdmmc usbmassstorage
|
||||
else
|
||||
boot_threads = sdmmc partition fat
|
||||
endif
|
||||
endif
|
||||
|
||||
# Threadlist must be the last file on the line below.
|
||||
iris_sources = panic.cc data.cc alloc.cc memory.cc invoke.cc schedule.cc mips/interrupts.cc mips/arch.cc threadlist.S
|
||||
boot_sources = mips/init.cc mips/nanonote/board.cc
|
||||
headers = kernel.hh iris.hh devices.hh ui.hh keys.hh mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh mips/nand.hh
|
||||
iris_elf_CPPFLAGS = -O5 -fno-inline -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
||||
iris_elf_CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -ggdb3
|
||||
iris_elf_LDFLAGS = -Wl,--omagic -Wl,-Ttext -Wl,$(load) -nostdlib
|
||||
iris_elf_SOURCES = mips/entry.S ${iris_sources} mips/boot.S ${boot_sources} ${headers}
|
||||
|
||||
program_sources = \
|
||||
source/alarm.cc \
|
||||
source/ball.cc \
|
||||
source/boot.cc \
|
||||
source/booter.cc \
|
||||
source/bootinit.cc \
|
||||
source/bsquare.cc \
|
||||
source/buzzer.cc \
|
||||
source/elfrun.cc \
|
||||
source/fat.cc \
|
||||
source/font.cc \
|
||||
source/gpio.cc \
|
||||
source/gui.cc \
|
||||
source/init.cc \
|
||||
source/lcd.cc \
|
||||
source/metronome.cc \
|
||||
source/nand.cc \
|
||||
source/partition.cc \
|
||||
source/rtc.cc \
|
||||
source/sdmmc.cc \
|
||||
source/test.cc \
|
||||
source/udc.cc \
|
||||
source/usbmassstorage.cc
|
||||
|
||||
program_targets = \
|
||||
fs/alarm.elf \
|
||||
fs/ball.elf \
|
||||
fs/boot.elf \
|
||||
fs/booter.elf \
|
||||
fs/bootinit.elf \
|
||||
fs/bsquare.elf \
|
||||
fs/buzzer.elf \
|
||||
fs/elfrun.elf \
|
||||
fs/fat.elf \
|
||||
fs/font.elf \
|
||||
fs/gpio.elf \
|
||||
fs/gui.elf \
|
||||
fs/init.elf \
|
||||
fs/lcd.elf \
|
||||
fs/metronome.elf \
|
||||
fs/nand.elf \
|
||||
fs/partition.elf \
|
||||
fs/rtc.elf \
|
||||
fs/sdmmc.elf \
|
||||
fs/test.elf \
|
||||
fs/udc.elf \
|
||||
fs/usbmassstorage.elf
|
||||
|
||||
noinst_PROGRAMS += $(program_targets)
|
||||
AM_CPPFLAGS = -O5 -fno-inline -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE
|
||||
AM_CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -ggdb3
|
||||
AM_LDFLAGS = -nostdlib
|
||||
|
||||
BUILT_SOURCES = $(iris_sources) $(boot_sources) $(program_sources) $(headers) mips/nanonote/threadlist.S source/charset.data fs/font.dat fs/init.config
|
||||
|
||||
threadlist.S: mkthreadlist Makefile $(addprefix fs/,$(addsuffix .elf,$(boot_threads)))
|
||||
$(top_srcdir)/$< $(boot_threads) > $@
|
||||
|
||||
PYPP = /usr/bin/pypp
|
||||
%.cc: %.ccp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
%.hh: %.hhp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
|
||||
source/charset.data: source/charset
|
||||
$< > $@
|
||||
fs/font.dat: courier-10+8+32.png makefont
|
||||
./makefont $< > $@
|
||||
fs/%: %
|
||||
ln -s ../$< $@
|
||||
|
||||
fs_alarm_elf_SOURCES = source/crt0.cc source/alarm.cc
|
||||
fs_ball_elf_SOURCES = source/crt0.cc source/ball.cc
|
||||
fs_boot_elf_SOURCES = source/crt0.cc source/boot.cc
|
||||
fs_booter_elf_SOURCES = source/crt0.cc source/booter.cc
|
||||
fs_bootinit_elf_SOURCES = source/crt0.cc source/bootinit.cc
|
||||
fs_bsquare_elf_SOURCES = source/crt0.cc source/bsquare.cc
|
||||
fs_buzzer_elf_SOURCES = source/crt0.cc source/buzzer.cc
|
||||
fs_elfrun_elf_SOURCES = source/crt0.cc source/elfrun.cc
|
||||
fs_fat_elf_SOURCES = source/crt0.cc source/fat.cc
|
||||
fs_font_elf_SOURCES = source/crt0.cc source/font.cc
|
||||
fs_gpio_elf_SOURCES = source/crt0.cc source/gpio.cc
|
||||
fs_gui_elf_SOURCES = source/crt0.cc source/gui.cc
|
||||
fs_init_elf_SOURCES = source/crt0.cc source/init.cc
|
||||
fs_lcd_elf_SOURCES = source/crt0.cc source/lcd.cc
|
||||
fs_metronome_elf_SOURCES = source/crt0.cc source/metronome.cc
|
||||
fs_nand_elf_SOURCES = source/crt0.cc source/nand.cc
|
||||
fs_partition_elf_SOURCES = source/crt0.cc source/partition.cc
|
||||
fs_rtc_elf_SOURCES = source/crt0.cc source/rtc.cc
|
||||
fs_sdmmc_elf_SOURCES = source/crt0.cc source/sdmmc.cc
|
||||
fs_test_elf_SOURCES = source/crt0.cc source/test.cc
|
||||
fs_udc_elf_SOURCES = source/crt0.cc source/udc.cc
|
||||
fs_usbmassstorage_elf_SOURCES = source/crt0.cc source/usbmassstorage.cc
|
||||
|
||||
autoclean: maintainer-clean
|
||||
rm -rf aclocal.m4 configure depcomp fs install-sh iris.raw iris-sd.tar Makefile.in missing
|
@ -1 +0,0 @@
|
||||
mips/Makefile.arch
|
10
configure.ac
Normal file
10
configure.ac
Normal file
@ -0,0 +1,10 @@
|
||||
AC_INIT([iris], [0.2], [wijnen@debian.org])
|
||||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
||||
AC_PROG_CXX
|
||||
AM_PROG_AS
|
||||
|
||||
AC_ARG_ENABLE([udc-boot], AC_HELP_STRING([--enable-udc-boot], [Compile for booting over custom usb protocol]), AM_CONDITIONAL(UDC, true), AM_CONDITIONAL(UDC, false))
|
||||
AC_ARG_ENABLE([unbrick], AC_HELP_STRING([--enable-unbrick], [Compile for unbricking]), AM_CONDITIONAL(UNBRICK, true), AM_CONDITIONAL(UNBRICK, false))
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
BIN
courier-10+8+32.png
Normal file
BIN
courier-10+8+32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
courier.xcf
Normal file
BIN
courier.xcf
Normal file
Binary file not shown.
119
devices.hhp
119
devices.hhp
@ -300,11 +300,105 @@ namespace Iris:
|
||||
// TODO: Interface is to be designed.
|
||||
panic (0, "using undefined interface Display::get_info ()")
|
||||
|
||||
// Font interface.
|
||||
// This can be used to turn a Display into a tty
|
||||
struct Font : public Cap:
|
||||
Font (Cap c = Cap ()) : Cap (c):
|
||||
enum request:
|
||||
SET_DISPLAY = Display::ID
|
||||
LOAD_FONT
|
||||
SETUP
|
||||
AT
|
||||
WRITE
|
||||
GET_POS
|
||||
GET_SIZE
|
||||
ID
|
||||
// Connect this font to new Display.
|
||||
void set_display (Display d):
|
||||
ocall (d, CAP_MASTER_DIRECT | SET_DISPLAY)
|
||||
// Load new glyphs.
|
||||
void load_font (String font):
|
||||
ocall (font, CAP_MASTER_DIRECT | LOAD_FONT)
|
||||
// Set some things up, like colours.
|
||||
void setup ():
|
||||
// TODO: Interface is to be designed.
|
||||
panic (0, "using undefined interface Font::setup ()")
|
||||
// Set new cursor position.
|
||||
void at (int x, int y, bool delta_x = false, bool delta_y = false):
|
||||
call (Num (CAP_MASTER_DIRECT | AT, delta_x + 2 * delta_y), Num (x, y))
|
||||
// Write one glyph to the display.
|
||||
void write (char c):
|
||||
call (CAP_MASTER_DIRECT | WRITE, c)
|
||||
// Write some glyphs to the display.
|
||||
void write (char const *text):
|
||||
for char const *t = text; *t; ++t:
|
||||
invoke (CAP_MASTER_DIRECT | WRITE, *t)
|
||||
// Write some glyphs to the display.
|
||||
void write (char const *text, unsigned size):
|
||||
for unsigned t = 0; t < size; ++t:
|
||||
invoke (CAP_MASTER_DIRECT | WRITE, text[t])
|
||||
void get_pos (unsigned &x, unsigned &y):
|
||||
call (CAP_MASTER_DIRECT | GET_POS)
|
||||
x = recv.data[0].l
|
||||
y = recv.data[1].l
|
||||
// Determine the size of a character.
|
||||
void get_size (unsigned c, unsigned &width, unsigned &height, unsigned &baseline):
|
||||
Num ret = call (CAP_MASTER_DIRECT | GET_SIZE, c)
|
||||
width = recv.data[1].l
|
||||
height = ret.h
|
||||
baseline = ret.l
|
||||
void write (unsigned num, unsigned base = 10):
|
||||
char const *encode = "0123456789abcdef"
|
||||
unsigned digits = 1
|
||||
unsigned power = 1
|
||||
while power <= num / base:
|
||||
power *= base
|
||||
++digits
|
||||
for unsigned i = 0; i < digits; ++i:
|
||||
unsigned d = num / power
|
||||
write (encode[d])
|
||||
num -= d * power
|
||||
power /= base
|
||||
void printf (char const *f, ...):
|
||||
unsigned *last = (unsigned *)&f
|
||||
while *f:
|
||||
if *f == '\r':
|
||||
at (0, 0, false, true)
|
||||
else if *f == '\n':
|
||||
at (0, 16, false, true)
|
||||
else if *f == '%':
|
||||
++f
|
||||
switch *f:
|
||||
case '%':
|
||||
write ('%')
|
||||
break
|
||||
case 'd':
|
||||
++last
|
||||
write (*last)
|
||||
break
|
||||
case 'x':
|
||||
++last
|
||||
write (*last, 0x10)
|
||||
break
|
||||
case 's':
|
||||
++last
|
||||
write ((char *)*last)
|
||||
break
|
||||
case 'c':
|
||||
++last
|
||||
write ((char)*last)
|
||||
break
|
||||
default:
|
||||
panic (*f, "invalid code character in dbg format string")
|
||||
else:
|
||||
write (*f)
|
||||
++f
|
||||
|
||||
// Numerical setting, such as a display backlight.
|
||||
struct Setting : public Device:
|
||||
Setting (Cap c = Cap ()) : Device (c):
|
||||
enum request:
|
||||
SET = Display::ID
|
||||
SET = Font::ID
|
||||
GET_RANGE
|
||||
ID
|
||||
// Set a new value.
|
||||
@ -393,6 +487,29 @@ namespace Iris:
|
||||
call (Num (CAP_MASTER_DIRECT | EVENT, code), value)
|
||||
void exit ():
|
||||
call (CAP_MASTER_DIRECT | EXIT)
|
||||
|
||||
struct RTC : public Cap:
|
||||
RTC (Cap c = Cap ()) : Cap (c):
|
||||
enum request:
|
||||
SETUP = UI::ID
|
||||
GET_TIME
|
||||
SET_TIME
|
||||
GET_ALARM
|
||||
UNSET_ALARM
|
||||
SET_ALARM
|
||||
ID
|
||||
void setup (unsigned hz, unsigned adjc):
|
||||
call (CAP_MASTER_DIRECT | SETUP, Num (hz, adjc))
|
||||
unsigned get_time ():
|
||||
return call (CAP_MASTER_DIRECT | GET_TIME).l
|
||||
unsigned set_time (unsigned time):
|
||||
return call (CAP_MASTER_DIRECT | SET_TIME, time).l
|
||||
unsigned get_alarm ():
|
||||
return call (CAP_MASTER_DIRECT | GET_ALARM).l
|
||||
unsigned unset_alarm ():
|
||||
return call (CAP_MASTER_DIRECT | UNSET_ALARM).l
|
||||
unsigned set_alarm (unsigned time, Cap cb):
|
||||
return ocall (cb, CAP_MASTER_DIRECT | SET_ALARM, time).l
|
||||
|
||||
// TODO.
|
||||
// Sound interface.
|
||||
|
51
init.config
51
init.config
@ -1,6 +1,6 @@
|
||||
# driver <name> = '<filename>' load a file into memory to be run priviledged.
|
||||
# program <name> = '<filename>' load a file into memory to be run normally.
|
||||
# file <name> = '<filename>' load a file into memory as a String.
|
||||
# file <name> = '<filename>' load a file into memory as a Block.
|
||||
# receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
|
||||
# sysreq <cap> use a capability as the system request keyboard.
|
||||
# give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
#file kernel = "kernel.raw"
|
||||
#program booter = "booter.elf"
|
||||
#give booter / String = kernel
|
||||
#give booter / Block = kernel
|
||||
#give booter / Boot = boot
|
||||
|
||||
driver driver_lcd = "lcd.elf"
|
||||
@ -34,32 +34,47 @@
|
||||
driver driver_buzzer = "buzzer.elf"
|
||||
receive driver_buzzer / Buzzer = buzzer
|
||||
|
||||
program alarm = "alarm.elf"
|
||||
receive alarm / UI = ui
|
||||
#program alarm = "alarm.elf"
|
||||
#receive alarm / UI = ui
|
||||
|
||||
program gui = "gui.elf"
|
||||
give gui / UI = ui
|
||||
give gui / Display = display
|
||||
give gui / Setting = display_bright
|
||||
give gui / Buzzer = buzzer
|
||||
give gui / Keyboard = keyboard
|
||||
#program gui = "gui.elf"
|
||||
#give gui / UI = ui
|
||||
#give gui / Display = display
|
||||
#give gui / Setting = display_bright
|
||||
#give gui / Buzzer = buzzer
|
||||
#give gui / Keyboard = keyboard
|
||||
|
||||
#driver sdmmc = "sd+mmc.elf"
|
||||
#receive sdmmc / WString = sdmmc
|
||||
#receive sdmmc / WBlock = sdmmc
|
||||
#give sdmmc / Event = sdmmc_gpio
|
||||
|
||||
#program partition = "partition.elf"
|
||||
#receive partition / WString, 0 = p0
|
||||
#receive partition / WString, 1 = p1
|
||||
#receive partition / WString, 2 = p2
|
||||
#receive partition / WString, 3 = p3
|
||||
#give partition / WString = sdmmc
|
||||
#receive partition / WBlock, 0 = p0
|
||||
#receive partition / WBlock, 1 = p1
|
||||
#receive partition / WBlock, 2 = p2
|
||||
#receive partition / WBlock, 3 = p3
|
||||
#give partition / WBlock = sdmmc
|
||||
|
||||
#program fat = "fat.elf"
|
||||
#receive fat / Directory = root
|
||||
#give fat / WString = p0
|
||||
#give fat / WBlock = p0
|
||||
|
||||
#program test = "test.elf"
|
||||
#give test / Directory = root
|
||||
|
||||
#driver rtc = "rtc.elf"
|
||||
file fontfile = "font.dat"
|
||||
program font = "font.elf"
|
||||
receive font / Font = font
|
||||
give font / Block = fontfile
|
||||
#give font / Display = display
|
||||
|
||||
driver driver_rtc = "rtc.elf"
|
||||
receive driver_rtc / RTC = rtc
|
||||
|
||||
driver alarm = "alarm.elf"
|
||||
give alarm / Keyboard = keyboard
|
||||
give alarm / Display = display
|
||||
give alarm / Buzzer = buzzer
|
||||
give alarm / Font = font
|
||||
give alarm / RTC = rtc
|
||||
receive alarm / Event = alarm
|
||||
|
@ -574,6 +574,10 @@ static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_da
|
||||
arch_reboot ()
|
||||
case Iris::Thread::PRIV_POWEROFF & REQUEST_MASK:
|
||||
arch_poweroff ()
|
||||
case Iris::Thread::PRIV_SUSPEND & REQUEST_MASK:
|
||||
arch_suspend ()
|
||||
reply_num (~0)
|
||||
return
|
||||
case Iris::Thread::PRIV_BOOT & REQUEST_MASK:
|
||||
arch_boot (c->data[1].l, c->data[1].h)
|
||||
case Iris::Thread::PRIV_PANIC & REQUEST_MASK:
|
||||
|
13
iris.hhp
13
iris.hhp
@ -323,6 +323,7 @@ namespace Iris:
|
||||
DBG_SEND
|
||||
PRIV_REBOOT
|
||||
PRIV_POWEROFF
|
||||
PRIV_SUSPEND
|
||||
PRIV_BOOT
|
||||
PRIV_PANIC
|
||||
// These get/set_info are not arch-specific.
|
||||
@ -578,10 +579,12 @@ namespace Iris:
|
||||
my_thread.ocall (my_receiver, CAP_MASTER_DIRECT | Thread::PRIV_REGISTER_INTERRUPT, num)
|
||||
inline void unregister_interrupt (unsigned num):
|
||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REGISTER_INTERRUPT, num)
|
||||
inline void wait_for_interrupt (unsigned num):
|
||||
my_receiver.set_reply_protected_data (num)
|
||||
inline unsigned wait_for_interrupt ():
|
||||
my_receiver.set_reply_protected_data (0)
|
||||
Cap ().call ()
|
||||
unsigned ret = recv.data[0].l
|
||||
my_receiver.set_reply_protected_data (~0)
|
||||
return ret
|
||||
inline Cap get_top_memory ():
|
||||
my_thread.icall (CAP_MASTER_DIRECT | Thread::PRIV_GET_TOP_MEMORY)
|
||||
return get_arg ()
|
||||
@ -591,6 +594,8 @@ namespace Iris:
|
||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT)
|
||||
inline void poweroff ():
|
||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_POWEROFF)
|
||||
inline void suspend ():
|
||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_SUSPEND)
|
||||
inline void boot (unsigned address, unsigned arg):
|
||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_BOOT, Iris::Num (address, arg))
|
||||
|
||||
@ -668,6 +673,10 @@ namespace Iris:
|
||||
++last
|
||||
kdebug ((char *)*last)
|
||||
break
|
||||
case 'c':
|
||||
++last
|
||||
kdebug_char (*last)
|
||||
break
|
||||
default:
|
||||
panic (*f, "invalid character in dbg format string")
|
||||
else:
|
||||
|
@ -324,6 +324,7 @@ void kPage_arch_update_mapping (kPage *page)
|
||||
void arch_register_interrupt (unsigned num, kReceiverP r)
|
||||
void arch_reboot ()
|
||||
void arch_poweroff ()
|
||||
void arch_suspend ()
|
||||
void arch_boot (unsigned address, unsigned arg)
|
||||
void arch_uncache_page (unsigned page)
|
||||
|
||||
|
30
makefont
Executable file
30
makefont
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
def mknum (num):
|
||||
return ''.join ([chr ((num >> (8 * i)) & 0xff) for i in range (4)])
|
||||
|
||||
im = Image.open (sys.argv[1])
|
||||
height = im.size[1]
|
||||
width, baseline, skip = [int (x) for x in os.path.splitext (sys.argv[1])[0].split ('-')[-1].split ('+')]
|
||||
num_glyphs = im.size[0] / width
|
||||
sys.stdout.write (mknum (skip + num_glyphs))
|
||||
size1 = (3 + width * height) * 4
|
||||
base = (num_glyphs + skip) * 4
|
||||
for i in range (skip):
|
||||
sys.stdout.write (mknum (base + (num_glyphs - 1) * size1))
|
||||
for i in range (skip, skip + num_glyphs):
|
||||
sys.stdout.write (mknum (base + (i - skip) * size1))
|
||||
|
||||
im = im.convert ('RGBA')
|
||||
pix = im.load ()
|
||||
#sys.stderr.write ('%d\n' % len (pix[0,0]))
|
||||
for g in range (skip, skip + num_glyphs):
|
||||
sys.stdout.write (mknum (width))
|
||||
sys.stdout.write (mknum (height))
|
||||
sys.stdout.write (mknum (baseline))
|
||||
for y in range (height):
|
||||
for x in range (width):
|
||||
sys.stdout.write (''.join ([chr (x) for x in (pix[x + (g - skip) * width, y])]))
|
@ -138,7 +138,7 @@ extern "C":
|
||||
|
||||
// These are "extern", not "EXTERN", because they really are defined elsewhere.
|
||||
#ifdef INIT
|
||||
extern unsigned thread_start[NUM_THREADS + 1]
|
||||
extern unsigned *thread_start
|
||||
#endif
|
||||
// Fast pointer to page directory, for tlb miss events
|
||||
extern Table **directory
|
||||
|
@ -19,6 +19,8 @@
|
||||
#define ARCH
|
||||
#include "arch.hh"
|
||||
|
||||
#define MEMORY_SIZE (32 << 20)
|
||||
#define KERNEL_STACK_SIZE 0x1000
|
||||
// The kernel stack.
|
||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define KERNEL_STACK_SIZE 0x1000
|
||||
// The kernel stack.
|
||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||
|
||||
|
@ -118,7 +118,8 @@ static void init_threads ():
|
||||
first_scheduled = NULL
|
||||
first_alarm = NULL
|
||||
kReceiver *init_receiver = NULL
|
||||
for unsigned i = 0; i < NUM_THREADS; ++i:
|
||||
unsigned i = 0
|
||||
while thread_start[i] != 0:
|
||||
kMemory *mem = top_memory.alloc_memory ()
|
||||
assert (mem)
|
||||
kThread *thread = mem->alloc_thread (NUM_SLOTS)
|
||||
@ -269,6 +270,7 @@ static void init_threads ():
|
||||
thread->schedule_prev = previous
|
||||
thread->schedule_next = NULL
|
||||
previous = thread
|
||||
++i
|
||||
|
||||
// Initialize the kernel, finish by falling into the idle task.
|
||||
void init (unsigned mem):
|
||||
|
@ -126,9 +126,9 @@ kThread *interrupt ():
|
||||
// Send message to interrupt handler.
|
||||
if arch_interrupt_receiver[i]:
|
||||
kCapability::Context c
|
||||
for unsigned j = 0; j < 2; ++j:
|
||||
c.data[j] = 0
|
||||
arch_interrupt_receiver[i]->send_message (i, &c)
|
||||
c.data[0] = i
|
||||
c.data[1] = 0
|
||||
arch_interrupt_receiver[i]->send_message (0, &c)
|
||||
arch_interrupt_receiver[i] = NULL
|
||||
if ipr & (1 << TIMER_INTERRUPT):
|
||||
#if defined (TRENDTAC)
|
||||
|
@ -31,7 +31,7 @@ unbrick_boot_programs = nand sd+mmc usb-mass-storage
|
||||
standard_boot_programs = bootinit
|
||||
|
||||
# use sort to remove duplicates.
|
||||
programs = $(sort init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui test boot booter $(udc_boot_programs) $(sd_boot_programs) $(unbrick_boot_programs) $(standard_boot_programs))
|
||||
programs = $(sort init gpio font lcd bsquare ball buzzer metronome elfrun alarm rtc gui test boot booter $(udc_boot_programs) $(sd_boot_programs) $(unbrick_boot_programs) $(standard_boot_programs))
|
||||
|
||||
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
||||
CROSS = mipsel-linux-gnu-
|
||||
|
@ -84,22 +84,39 @@ void arch_reboot ():
|
||||
while true:
|
||||
|
||||
void arch_poweroff ():
|
||||
sync_serial ()
|
||||
// Power off.
|
||||
// First enable interrupts, so it can be awoken.
|
||||
// Disable all interrupts which shouldn't wake it (only an issue while powering down, really).
|
||||
INTC_IMSR = ~0
|
||||
intc_unmask_irq (IRQ_RTC)
|
||||
intc_unmask_irq (IRQ_GPIO3)
|
||||
GPIO_PXIMS (3) = ~0
|
||||
gpio_unmask_irq (3, 29)
|
||||
// Clear interrupt flags.
|
||||
gpio_ack_irq (3, 29)
|
||||
intc_ack_irq (IRQ_GPIO3)
|
||||
intc_ack_irq (IRQ_RTC)
|
||||
// Clear pending interrupts and enable interrupts.
|
||||
cp0_set (CP0_STATUS, 0x1000ff01)
|
||||
|
||||
// Make sure the rtc is running.
|
||||
cpm_start_rtc ()
|
||||
while !rtc_write_ready ():
|
||||
rtc_enabled ()
|
||||
while !rtc_write_ready ():
|
||||
kdebug ("Power down.\n")
|
||||
sync_serial ()
|
||||
rtc_power_down ()
|
||||
// Wait for power down to work.
|
||||
while !rtc_write_ready ():
|
||||
// Delay a bit more.
|
||||
for unsigned i = 0; i < 1000; ++i:
|
||||
gpio_set (0, 0)
|
||||
// Fall back to reboot.
|
||||
kdebug ("Power down failed! Rebooting instead.\n")
|
||||
arch_reboot ()
|
||||
while true:
|
||||
asm ("wait")
|
||||
|
||||
void arch_suspend ():
|
||||
sync_serial ()
|
||||
// Suspend the system: go into SLEEP mode.
|
||||
cpm_sleep_mode ()
|
||||
asm ("wait")
|
||||
cpm_idle_mode ()
|
||||
|
||||
// Boot into another kernel.
|
||||
void arch_boot (unsigned address, unsigned arg):
|
||||
|
@ -3532,6 +3532,7 @@ static void cim_enable_nongated_clock_mode ():
|
||||
#define rtc_disabled() ( RTC_RCR &= ~RTC_RCR_RTCE )
|
||||
#define rtc_enable_alarm() ( RTC_RCR |= RTC_RCR_AE )
|
||||
#define rtc_disable_alarm() ( RTC_RCR &= ~RTC_RCR_AE )
|
||||
#define rtc_alarm_is_enabled() ( RTC_RCR & RTC_RCR_AE )
|
||||
#define rtc_enable_alarm_irq() ( RTC_RCR |= RTC_RCR_AIE )
|
||||
#define rtc_disable_alarm_irq() ( RTC_RCR &= ~RTC_RCR_AIE )
|
||||
#define rtc_enable_1Hz_irq() ( RTC_RCR |= RTC_RCR_1HZIE )
|
||||
|
@ -33,8 +33,8 @@ asm volatile (".section .rodata\n"
|
||||
extern char stage1[1]
|
||||
extern char stage1_end[1]
|
||||
|
||||
unsigned const stage1_load = 0x80002000
|
||||
unsigned const stage1_start = 0x80002000
|
||||
unsigned const stage1_load = 0x80003000
|
||||
unsigned const stage1_start = 0x80003000
|
||||
unsigned const stage1_size = stage1_end - stage1
|
||||
|
||||
class nanonote:
|
||||
|
@ -30,17 +30,18 @@ asm volatile (".set noreorder\n"
|
||||
".globl __start\n"
|
||||
".text\n"
|
||||
"__start:\n"
|
||||
"\tnop\n"
|
||||
"__hack_label:\n"
|
||||
"\tmove $k0, $ra\n"
|
||||
"\tbal 1f\n"
|
||||
"\tnop\n"
|
||||
"\t.word _gp\n"
|
||||
"\tmove $t0, $ra\n" // 0
|
||||
"\tnop\n" // 4
|
||||
"\tbal 1f\n" // 8
|
||||
"\tnop\n" // 12
|
||||
"\t.word _gp\n" // 16
|
||||
"\t.word 0\n" // 20: This is overwritten in software usbboot mode.
|
||||
"1:\n"
|
||||
"\tlw $gp, 0($ra)\n"
|
||||
"\tla $sp, stack + 0x100\n"
|
||||
"\tlb $a0, 4($ra)\n"
|
||||
"\tla $sp, stack + 0x40\n"
|
||||
"\tla $t9, start_cpp\n"
|
||||
"\tmove $ra, $k0\n"
|
||||
"\tmove $ra, $t0\n"
|
||||
"\tjr $t9\n"
|
||||
"\tnop\n"
|
||||
".set reorder")
|
||||
@ -53,12 +54,13 @@ void kdebug (unsigned ch):
|
||||
while !(UART0_LSR & UARTLSR_TEMT):
|
||||
|
||||
extern "C":
|
||||
void start_cpp ()
|
||||
char stack[0x100]
|
||||
void start_cpp (int skip_memsetup)
|
||||
char stack[0x40]
|
||||
|
||||
void start_cpp ():
|
||||
void start_cpp (int skip_memsetup):
|
||||
setup_uart ()
|
||||
kdebug ('.')
|
||||
setup_sdram ()
|
||||
if !skip_memsetup:
|
||||
setup_sdram ()
|
||||
kdebug ('!')
|
||||
// everything is ok now: return to boot loader to load stage 2.
|
||||
|
@ -2,7 +2,7 @@ OUTPUT_ARCH(mips)
|
||||
ENTRY(__start)
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x80002000 , LENGTH = 0x2000
|
||||
ram : ORIGIN = 0x80003000 , LENGTH = 0x800
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
|
@ -48,7 +48,7 @@ struct data:
|
||||
server->open (port)
|
||||
|
||||
private:
|
||||
static unsigned const STAGE1_LOAD = 0x80002000
|
||||
static unsigned const STAGE1_LOAD = 0x80003000
|
||||
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
|
||||
enum requests:
|
||||
VR_GET_CPU_INFO = 0
|
||||
@ -245,6 +245,7 @@ void data::send_file (unsigned address, unsigned size, char const *data):
|
||||
handle = NULL
|
||||
return
|
||||
ptr += ret
|
||||
std::cerr << shevek::ostring ("sent %d bytes\n", size)
|
||||
|
||||
void data::get_device (unsigned vendor, unsigned product, unsigned tries):
|
||||
for unsigned i = 0; i < tries; ++i:
|
||||
@ -314,16 +315,23 @@ void data::boot (std::string const &filename, unsigned load, unsigned entry):
|
||||
|
||||
static void dump_devices ():
|
||||
std::cerr << std::hex << "String: " << Iris::String::ID
|
||||
std::cerr << "\nBlock: " << Iris::Block::ID
|
||||
std::cerr << "\nWString: " << Iris::WString::ID
|
||||
std::cerr << "\nWBlock: " << Iris::WBlock::ID
|
||||
std::cerr << "\nBoot: " << Iris::Boot::ID
|
||||
std::cerr << "\nDevice: " << Iris::Device::ID
|
||||
std::cerr << "\nEvent: " << Iris::Event::ID
|
||||
std::cerr << "\nElfrun: " << Iris::Elfrun::ID
|
||||
std::cerr << "\nParent: " << Iris::Parent::ID
|
||||
std::cerr << "\nKeyboard: " << Iris::Keyboard::ID
|
||||
std::cerr << "\nBuzzer: " << Iris::Buzzer::ID
|
||||
std::cerr << "\nDisplay: " << Iris::Display::ID
|
||||
std::cerr << "\nFont: " << Iris::Display::ID
|
||||
std::cerr << "\nSetting: " << Iris::Setting::ID
|
||||
std::cerr << "\nDirectory: " << Iris::Directory::ID
|
||||
std::cerr << "\nWDirectory: " << Iris::WDirectory::ID
|
||||
std::cerr << "\nStream: " << Iris::Stream::ID
|
||||
std::cerr << "\nUI: " << Iris::UI::ID
|
||||
std::cerr << "\n"
|
||||
|
||||
int main (int argc, char **argv):
|
||||
|
@ -1,97 +0,0 @@
|
||||
// Iris: micro-kernel for a capability-based operating system.
|
||||
// mips/nanonote/threadlist.S: List of initial threads.
|
||||
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
.globl init_start
|
||||
.globl thread_start
|
||||
.set noreorder
|
||||
|
||||
#if defined (UDCBOOT)
|
||||
.balign 0x1000
|
||||
thread0:
|
||||
.incbin "fs/bootinit.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread1:
|
||||
.incbin "fs/udc.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread2:
|
||||
|
||||
// Everything from here may be freed after kernel initialization.
|
||||
init_start:
|
||||
|
||||
thread_start:
|
||||
.word thread0
|
||||
.word thread1
|
||||
.word thread2
|
||||
|
||||
#elif defined (SDBOOT)
|
||||
.balign 0x1000
|
||||
thread0:
|
||||
.incbin "fs/bootinit.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread1:
|
||||
.incbin "fs/sd+mmc.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread2:
|
||||
.incbin "fs/partition.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread3:
|
||||
.incbin "fs/fat.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread4:
|
||||
|
||||
// Everything from here may be freed after kernel initialization.
|
||||
init_start:
|
||||
|
||||
thread_start:
|
||||
.word thread0
|
||||
.word thread1
|
||||
.word thread2
|
||||
.word thread3
|
||||
#elif defined (UNBRICK)
|
||||
.balign 0x1000
|
||||
thread0:
|
||||
.incbin "fs/bootinit.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread1:
|
||||
.incbin "fs/sd+mmc.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread2:
|
||||
.incbin "fs/usb-mass-storage.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread3:
|
||||
|
||||
// Everything from here may be freed after kernel initialization.
|
||||
init_start:
|
||||
|
||||
thread_start:
|
||||
.word thread0
|
||||
.word thread1
|
||||
.word thread2
|
||||
.word thread3
|
||||
|
||||
#else
|
||||
#error "boot method not defined"
|
||||
#endif
|
@ -35,7 +35,7 @@ static int const run_vendor = 0xfffe
|
||||
static int const run_product = 0x0002
|
||||
static unsigned const timeout = 10000
|
||||
void boot (std::string const &filename, unsigned load, unsigned entry)
|
||||
static unsigned const STAGE1_LOAD = 0x80002000
|
||||
static unsigned const STAGE1_LOAD = 0x80003000
|
||||
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
|
||||
enum requests:
|
||||
VR_GET_CPU_INFO = 0
|
||||
|
31
mkthreadlist
Executable file
31
mkthreadlist
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
cat << EOF
|
||||
.globl init_start
|
||||
.globl thread_start
|
||||
.set noreorder
|
||||
.balign 0x1000
|
||||
EOF
|
||||
|
||||
for i in "$@" ; do
|
||||
cat << EOF
|
||||
$i:
|
||||
.incbin "fs/$i.elf"
|
||||
.balign 0x1000
|
||||
EOF
|
||||
done
|
||||
|
||||
cat << EOF
|
||||
end_threads:
|
||||
init_start:
|
||||
thread_start:
|
||||
EOF
|
||||
|
||||
for i in "$@" ; do
|
||||
cat << EOF
|
||||
.word $i
|
||||
EOF
|
||||
done
|
||||
|
||||
cat << EOF
|
||||
.word 0
|
||||
EOF
|
105
source/alarm.ccp
105
source/alarm.ccp
@ -1,73 +1,50 @@
|
||||
#pypp 0
|
||||
#include <iris.hh>
|
||||
#include <ui.hh>
|
||||
#include <devices.hh>
|
||||
|
||||
enum Ins:
|
||||
TOTAL_TIME
|
||||
START
|
||||
NUM_INS
|
||||
|
||||
enum Outs:
|
||||
CURRENT_TIME
|
||||
ALARM
|
||||
NUM_OUTS
|
||||
|
||||
typedef UI <NUM_INS, NUM_OUTS> ui_t
|
||||
static ui_t ui
|
||||
static ui_t::in <unsigned> total_time
|
||||
static ui_t::in_event do_start
|
||||
static ui_t::out <unsigned> current_time
|
||||
static ui_t::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")
|
||||
enum captypes:
|
||||
CONTROL = 1
|
||||
KBD
|
||||
INTERRUPT
|
||||
|
||||
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);
|
||||
unsigned *screen = (unsigned *)0x40000000
|
||||
Iris::RTC rtc = Iris::my_parent.get_capability <Iris::RTC> ()
|
||||
Iris::Display display = Iris::my_parent.get_capability <Iris::Display> ()
|
||||
display.map_fb ((unsigned)screen)
|
||||
Iris::Font font = Iris::my_parent.get_capability <Iris::Font> ()
|
||||
font.set_display (display)
|
||||
Iris::Keyboard keyboard = Iris::my_parent.get_capability <Iris::Keyboard> ()
|
||||
Iris::Cap cap = Iris::my_receiver.create_capability (KBD)
|
||||
keyboard.set_cb (cap.copy ())
|
||||
Iris::free_cap (cap)
|
||||
Iris::Buzzer buzzer = Iris::my_parent.get_capability <Iris::Buzzer> ()
|
||||
Iris::Event self = Iris::my_receiver.create_capability (CONTROL)
|
||||
Iris::my_parent.provide_capability <Iris::Event> (self)
|
||||
cap = Iris::my_receiver.create_capability (INTERRUPT)
|
||||
Iris::my_parent.init_done ()
|
||||
|
||||
while true:
|
||||
Iris::wait ()
|
||||
switch Iris::recv.protected_data.l:
|
||||
case ~0:
|
||||
// alarm.
|
||||
if current_time:
|
||||
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
|
||||
case INTERRUPT:
|
||||
// Interrupt
|
||||
if Iris::recv.data[0].l == ~0:
|
||||
// Not a real interrupt, just an abort notification.
|
||||
continue
|
||||
font.printf ("alarm: interrupt\n")
|
||||
break
|
||||
case CONTROL:
|
||||
// Store callback
|
||||
font.printf ("alarm: control event\n")
|
||||
break
|
||||
case KBD:
|
||||
// Key press
|
||||
unsigned time = rtc.get_time ()
|
||||
unsigned alarm = rtc.get_alarm ()
|
||||
unsigned enabled = Iris::recv.data[1].l
|
||||
font.printf ("%d %d %d", time, alarm, enabled)
|
||||
rtc.set_alarm (time + 10, cap)
|
||||
Iris::poweroff ()
|
||||
break
|
||||
default:
|
||||
Iris::panic (Iris::recv.protected_data.l, "invalid request for alarm")
|
||||
|
@ -320,10 +320,15 @@ Iris::Num start ():
|
||||
Iris::Memory top_memory = Iris::get_top_memory ()
|
||||
Iris::Directory root = receive_devices ()
|
||||
root.lock_ro ()
|
||||
kdebug_line ()
|
||||
Iris::Block run_block = find (root, ELFRUN_NAME)
|
||||
kdebug_line ()
|
||||
Iris::Cap parent_cap = Iris::my_receiver.create_capability (0)
|
||||
kdebug_line ()
|
||||
run (run_block, top_memory, parent_cap)
|
||||
kdebug_line ()
|
||||
Iris::wait ()
|
||||
kdebug_line ()
|
||||
if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY || Iris::recv.data[1].l != Iris::Elfrun::ID:
|
||||
Iris::panic (0, "elfrun doesn't provide correct capability")
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
|
179
source/font.ccp
Normal file
179
source/font.ccp
Normal file
@ -0,0 +1,179 @@
|
||||
#pypp 0
|
||||
// Iris: micro-kernel for a capability-based operating system.
|
||||
// source/font.ccp: Font manager.
|
||||
// Copyright 2012 Bas Wijnen <wijnen@debian.org>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "devices.hh"
|
||||
|
||||
#define screenw 320
|
||||
#define screenh 240
|
||||
|
||||
struct Glyph:
|
||||
unsigned width, height, baseline
|
||||
unsigned data[1]
|
||||
|
||||
static Iris::Display display
|
||||
static Iris::Caps caps, display_caps
|
||||
static unsigned slot, num_glyphs
|
||||
static unsigned long pages, base
|
||||
static Glyph **glyphs
|
||||
static char *fb
|
||||
static unsigned x, y
|
||||
|
||||
static unsigned read_int (unsigned addr):
|
||||
return *reinterpret_cast <unsigned *> (addr)
|
||||
|
||||
static void load_font (Iris::Block font):
|
||||
unsigned long long size = font.get_size ().value ()
|
||||
pages = (size + PAGE_SIZE - 1) >> PAGE_BITS
|
||||
caps = Iris::my_memory.create_caps (pages)
|
||||
slot = caps.use ()
|
||||
for unsigned i = 0; i < size; i += PAGE_SIZE:
|
||||
Iris::Page page = Iris::Cap (slot, i >> PAGE_BITS)
|
||||
Iris::set_recv_arg (page)
|
||||
font.get_block (i)
|
||||
Iris::my_memory.map (page, base + i)
|
||||
num_glyphs = read_int (base)
|
||||
glyphs = reinterpret_cast <Glyph **> (base + sizeof (int))
|
||||
for unsigned i = 0; i < num_glyphs; ++i:
|
||||
glyphs[i] = reinterpret_cast <Glyph *> (base + sizeof (int) + read_int (base + sizeof (int) + i * sizeof (int)))
|
||||
|
||||
static void free_font ():
|
||||
for unsigned i = 0; i < pages; ++i:
|
||||
Iris::my_memory.destroy (Iris::Cap (slot, i))
|
||||
Iris::my_memory.destroy (caps)
|
||||
Iris::free_slot (slot)
|
||||
|
||||
static unsigned draw_char (char c, unsigned &w, unsigned &h):
|
||||
if c >= num_glyphs:
|
||||
c = num_glyphs - 1
|
||||
Glyph *g = glyphs[c]
|
||||
w = g->width
|
||||
h = g->height
|
||||
for unsigned ty = 0; ty < h; ++ty:
|
||||
unsigned py = ty + y - g->baseline
|
||||
if py < 0 || py >= screenh:
|
||||
continue
|
||||
for unsigned tx = 0; tx < g->width; ++tx:
|
||||
unsigned px = tx + x
|
||||
if px < 0 || px >= screenw:
|
||||
continue
|
||||
unsigned p = g->data[ty * g->width + tx]
|
||||
unsigned red = unsigned (p) & 0xff
|
||||
unsigned green = unsigned (p >> 8) & 0xff
|
||||
unsigned blue = unsigned (p >> 16) & 0xff
|
||||
unsigned alpha = (unsigned (p >> 24) & 0xff) + 1
|
||||
if alpha == 0x100:
|
||||
fb[(py * 320 + px) * 4 + 2] = red
|
||||
fb[(py * 320 + px) * 4 + 1] = green
|
||||
fb[(py * 320 + px) * 4 + 0] = blue
|
||||
else:
|
||||
unsigned unalpha = 256 - alpha
|
||||
fb[(py * 320 + px) * 4 + 2] = (fb[(py * 320 + px) * 4 + 2] * unalpha + red * alpha) >> 8
|
||||
fb[(py * 320 + px) * 4 + 1] = (fb[(py * 320 + px) * 4 + 1] * unalpha + green * alpha) >> 8
|
||||
fb[(py * 320 + px) * 4 + 0] = (fb[(py * 320 + px) * 4 + 0] * unalpha + blue * alpha) >> 8
|
||||
return g->baseline
|
||||
|
||||
static void get_size (char c, unsigned &w, unsigned &h, unsigned &b):
|
||||
if c >= num_glyphs:
|
||||
c = num_glyphs - 1
|
||||
Glyph *g = glyphs[c]
|
||||
w = g->width
|
||||
h = g->height
|
||||
b = g->baseline
|
||||
|
||||
Iris::Num start ():
|
||||
x = 0
|
||||
y = 8
|
||||
// Random address which is large enough to store a huge file.
|
||||
base = 0x40000000
|
||||
fb = reinterpret_cast <char *> (0x20000000)
|
||||
Iris::Font self = Iris::my_receiver.create_capability (0)
|
||||
Iris::my_parent.provide_capability <Iris::Font> (self.copy ())
|
||||
Iris::free_cap (self)
|
||||
//display = Iris::my_parent.get_capability <Iris::Display> ()
|
||||
Iris::Block font = Iris::my_parent.get_capability <Iris::Block> ()
|
||||
load_font (font)
|
||||
Iris::free_cap (font)
|
||||
Iris::my_parent.init_done ()
|
||||
//display_caps = display.map_fb (reinterpret_cast <unsigned> (fb))
|
||||
bool have_display = false
|
||||
while true:
|
||||
Iris::wait ()
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::Font::SET_DISPLAY:
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
if have_display:
|
||||
Iris::free_cap (display)
|
||||
have_display = true
|
||||
display = Iris::get_arg ()
|
||||
display_caps = display.map_fb (reinterpret_cast <unsigned> (fb))
|
||||
reply.invoke ()
|
||||
Iris::free_cap (reply)
|
||||
break
|
||||
case Iris::Font::LOAD_FONT:
|
||||
free_font ()
|
||||
font = Iris::get_arg ()
|
||||
load_font (font)
|
||||
Iris::free_cap (font)
|
||||
Iris::recv.reply.invoke ()
|
||||
break
|
||||
case Iris::Font::SETUP:
|
||||
// TODO: interface needs to be defined.
|
||||
Iris::recv.reply.invoke ()
|
||||
break
|
||||
case Iris::Font::AT:
|
||||
if Iris::recv.data[0].h & 1:
|
||||
x += Iris::recv.data[1].l
|
||||
if x > screenw:
|
||||
x = 0
|
||||
y += 16
|
||||
if y + 16 > screenh + 8:
|
||||
y = 8
|
||||
else:
|
||||
x = Iris::recv.data[1].l
|
||||
if Iris::recv.data[0].h & 2:
|
||||
y += Iris::recv.data[1].h
|
||||
if y + 16 > screenh + 8:
|
||||
y = 8
|
||||
else:
|
||||
y = Iris::recv.data[1].h
|
||||
Iris::recv.reply.invoke ()
|
||||
break
|
||||
case Iris::Font::WRITE:
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
unsigned w, h
|
||||
unsigned b = draw_char (Iris::recv.data[1].l, w, h)
|
||||
x += w
|
||||
if x + w > screenw:
|
||||
x = 0
|
||||
y += h
|
||||
if y + h > screenh + b:
|
||||
y = b
|
||||
reply.invoke ()
|
||||
Iris::free_cap (reply)
|
||||
break
|
||||
case Iris::Font::GET_POS:
|
||||
Iris::recv.reply.invoke (x, y)
|
||||
break
|
||||
case Iris::Font::GET_SIZE:
|
||||
unsigned w, h, b
|
||||
get_size (Iris::recv.data[1].l, w, h, b)
|
||||
Iris::recv.reply.invoke (Iris::Num (b, h), w)
|
||||
break
|
||||
default:
|
||||
Iris::panic (0, "invalid operation type for lcd")
|
||||
break
|
@ -295,11 +295,13 @@ static Type types[] = {
|
||||
{ "Keyboard", 8, Iris::Keyboard::ID },
|
||||
{ "Buzzer", 6, Iris::Buzzer::ID },
|
||||
{ "Display", 7, Iris::Display::ID },
|
||||
{ "Font", 4, Iris::Font::ID },
|
||||
{ "Setting", 7, Iris::Setting::ID },
|
||||
{ "Directory", 9, Iris::Directory::ID },
|
||||
{ "WDirectory", 10, Iris::WDirectory::ID },
|
||||
{ "Stream", 6, Iris::Stream::ID },
|
||||
{ "UI", 2, Iris::UI::ID },
|
||||
{ "RTC", 3, Iris::RTC::ID },
|
||||
{ NULL, 0, 0 }
|
||||
}
|
||||
|
||||
@ -514,9 +516,9 @@ Iris::Num start ():
|
||||
switch Iris::recv.protected_data.l:
|
||||
case SYSREQ:
|
||||
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
||||
Iris::poweroff ()
|
||||
Iris::reboot ()
|
||||
continue
|
||||
kdebug ("sysreq event: powering device off at release\n")
|
||||
kdebug ("sysreq event: rebooting device at release\n")
|
||||
continue
|
||||
case FILE:
|
||||
File *file = (File *)Iris::recv.protected_data.h
|
||||
@ -563,6 +565,7 @@ Iris::Num start ():
|
||||
if (*d)->type == type && (*d)->index == index:
|
||||
break
|
||||
if !d:
|
||||
Iris::debug ("requested %x by %s\n", type, caller->name)
|
||||
Iris::panic (type, "unregistered device requested")
|
||||
Iris::recv.reply.invoke (0, 0, (*d)->dev->cap)
|
||||
//kdebug ("given device ")
|
||||
|
@ -244,7 +244,7 @@ static void log_msg ():
|
||||
log_char ('\n')
|
||||
|
||||
enum captype:
|
||||
LOG = 32
|
||||
LOG = 1
|
||||
BACKLIGHT
|
||||
LCD
|
||||
|
||||
@ -359,7 +359,7 @@ Iris::Num start ():
|
||||
Iris::wait ()
|
||||
//log_msg ()
|
||||
switch Iris::recv.protected_data.l:
|
||||
case IRQ_LCD:
|
||||
case 0:
|
||||
have_eof = false
|
||||
eof_cb.invoke ()
|
||||
Iris::free_cap (eof_cb)
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "arch.hh"
|
||||
#include "keys.hh"
|
||||
|
||||
//#define QI
|
||||
#define QI
|
||||
#define SCAN_INTERVAL HZ / 50
|
||||
|
||||
class DevKbd:
|
||||
@ -128,10 +128,10 @@ unsigned const DevKbd::encode[NUM_ROWS][NUM_COLS] = {
|
||||
{ Key::Q, Key::W, Key::E, Key::R, Key::T, Key::Y, Key::U, Key::I },
|
||||
{ Key::A, Key::S, Key::D, Key::F, Key::G, Key::H, Key::J, Key::K },
|
||||
{ Key::ESCAPE, Key::Z, Key::X, Key::C, Key::V, Key::B, Key::N, Key::M },
|
||||
{ Key::TAB, Key::CAPS, Key::BACKSLASH, Key::QUOTE, Key::COMMA, Key::PERIOD, Key::SLASH, Key::UP },
|
||||
{ Key::O, Key::L, Key::EQUAL, Key::ARROW, Key::SPACE, Key::QI, Key::CTRL, Key::LEFT },
|
||||
{ Key::TAB, Key::CAPS_LOCK, Key::BACKSLASH, Key::QUOTE, Key::COMMA, Key::PERIOD, Key::SLASH, Key::UP },
|
||||
{ Key::O, Key::L, Key::EQUALS, Key::SPECIAL + 0, Key::SPACE, Key::RIGHT_LOGO, Key::RIGHT_CONTROL, Key::LEFT },
|
||||
{ Key::F8, Key::P, Key::BACKSPACE, Key::ENTER, Key::VOLUME_UP, Key::VOLUME_DOWN, Key::DOWN, Key::RIGHT },
|
||||
{ Key::SHIFT, Key::ALT, Key::FN, ~0, ~0, ~0, ~0, ~0 }
|
||||
{ Key::LEFT_SHIFT, Key::LEFT_ALT, Key::FN, ~0, ~0, ~0, ~0, ~0 }
|
||||
#else
|
||||
{ Key::ESCAPE, Key::TAB, Key::F1, Key::F2, Key::F3, Key::F4, Key::SPECIAL + 0, ~0 },
|
||||
{ Key::N1, Key::N2, Key::N3, Key::N4, Key::N5, Key::N6, Key::N7, Key::N8 },
|
||||
@ -149,10 +149,10 @@ unsigned const DevKbd::keys[NUM_KEYS] = {
|
||||
Key::Q, Key::W, Key::E, Key::R, Key::T, Key::Y, Key::U, Key::I,
|
||||
Key::A, Key::S, Key::D, Key::F, Key::G, Key::H, Key::J, Key::K,
|
||||
Key::ESCAPE, Key::Z, Key::X, Key::C, Key::V, Key::B, Key::N, Key::M,
|
||||
Key::TAB, Key::CAPS, Key::BACKSLASH, Key::QUOTE, Key::COMMA, Key::PERIOD, Key::SLASH, Key::UP,
|
||||
Key::O, Key::L, Key::EQUAL, Key::ARROW, Key::SPACE, Key::QI, Key::CTRL, Key::LEFT,
|
||||
Key::TAB, Key::CAPS_LOCK, Key::BACKSLASH, Key::QUOTE, Key::COMMA, Key::PERIOD, Key::SLASH, Key::UP,
|
||||
Key::O, Key::L, Key::EQUALS, Key::SPECIAL + 0, Key::SPACE, Key::RIGHT_LOGO, Key::RIGHT_CONTROL, Key::LEFT,
|
||||
Key::F8, Key::P, Key::BACKSPACE, Key::ENTER, Key::VOLUME_UP, Key::VOLUME_DOWN, Key::DOWN, Key::RIGHT,
|
||||
Key::SHIFT, Key::ALT, Key::FN
|
||||
Key::LEFT_SHIFT, Key::LEFT_ALT, Key::FN
|
||||
#else
|
||||
Key::ESCAPE, Key::TAB, Key::F1, Key::F2, Key::F3, Key::F4, Key::SPECIAL + 0,
|
||||
Key::N1, Key::N2, Key::N3, Key::N4, Key::N5, Key::N6, Key::N7, Key::N8,
|
||||
@ -195,7 +195,7 @@ class Event:
|
||||
scan ()
|
||||
|
||||
enum codes:
|
||||
KBD_DEV = 32
|
||||
KBD_DEV = 1
|
||||
PWR
|
||||
SDMMC
|
||||
|
||||
@ -228,7 +228,7 @@ Iris::Num start ():
|
||||
Iris::my_receiver.set_alarm (SCAN_INTERVAL)
|
||||
continue
|
||||
switch Iris::recv.protected_data.l:
|
||||
case IRQ_GPIO3:
|
||||
case 0:
|
||||
// Interrupt.
|
||||
pwr.scan ()
|
||||
kbd.scan ()
|
||||
|
103
source/rtc.ccp
103
source/rtc.ccp
@ -20,6 +20,8 @@
|
||||
#define ARCH
|
||||
#include "arch.hh"
|
||||
|
||||
static Iris::Font font
|
||||
|
||||
static void ready ():
|
||||
while !rtc_write_ready ():
|
||||
Iris::schedule ()
|
||||
@ -42,17 +44,104 @@ Iris::Num start ():
|
||||
cpm_start_rtc ()
|
||||
ready ()
|
||||
rtc_enabled ()
|
||||
if rtc_get_scratch_pattern () != 0xbeefface:
|
||||
ready ()
|
||||
rtc_set_nc1Hz_val (RTC_CLOCK)
|
||||
ready ()
|
||||
rtc_set_adjc_val (0)
|
||||
ready ()
|
||||
rtc_set_second (0)
|
||||
ready ()
|
||||
rtc_set_nc1Hz_val (RTC_CLOCK)
|
||||
rtc_disable_1Hz_irq ()
|
||||
ready ()
|
||||
rtc_disable_alarm ()
|
||||
ready ()
|
||||
rtc_enable_1Hz_irq ()
|
||||
rtc_clear_alarm_flag ()
|
||||
ready ()
|
||||
rtc_enable_alarm_irq ()
|
||||
ready ()
|
||||
rtc_set_hwfcr_val (0)
|
||||
ready ()
|
||||
rtc_set_hrcr_val (0)
|
||||
ready ()
|
||||
rtc_enable_alarm_wakeup ()
|
||||
ready ()
|
||||
rtc_set_scratch_pattern (0xbeefface)
|
||||
Iris::RTC self = Iris::my_receiver.create_capability (1)
|
||||
Iris::my_parent.provide_capability <Iris::RTC> (self.copy ())
|
||||
Iris::free_cap (self)
|
||||
Iris::my_parent.init_done ()
|
||||
bool have_interrupt = false
|
||||
Iris::Cap interrupt
|
||||
while true:
|
||||
ready ()
|
||||
rtc_clear_1Hz_flag ()
|
||||
ready ()
|
||||
Iris::register_interrupt (IRQ_RTC)
|
||||
Iris::wait ()
|
||||
kdebug ("tick\n")
|
||||
if Iris::recv.protected_data.l == 0:
|
||||
// Interrupt.
|
||||
ready ()
|
||||
rtc_disable_alarm ()
|
||||
if have_interrupt:
|
||||
interrupt.invoke (0)
|
||||
Iris::free_cap (interrupt)
|
||||
have_interrupt = false
|
||||
continue
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::RTC::SETUP:
|
||||
ready ()
|
||||
rtc_set_nc1Hz_val (Iris::recv.data[1].l)
|
||||
ready ()
|
||||
rtc_set_adjc_val (Iris::recv.data[1].h)
|
||||
Iris::recv.reply.invoke ()
|
||||
break
|
||||
case Iris::RTC::GET_TIME:
|
||||
ready ()
|
||||
Iris::recv.reply.invoke (rtc_get_second ())
|
||||
Iris::recv.reply.invoke (0)
|
||||
break
|
||||
case Iris::RTC::SET_TIME:
|
||||
ready ()
|
||||
rtc_set_second (Iris::recv.data[1].l)
|
||||
Iris::recv.reply.invoke ()
|
||||
break
|
||||
case Iris::RTC::GET_ALARM:
|
||||
ready ()
|
||||
Iris::recv.reply.invoke (rtc_get_alarm_second (), rtc_alarm_is_enabled ())
|
||||
Iris::recv.reply.invoke (0)
|
||||
break
|
||||
case Iris::RTC::UNSET_ALARM:
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
if have_interrupt:
|
||||
have_interrupt = false
|
||||
interrupt.invoke (~0)
|
||||
Iris::free_cap (interrupt)
|
||||
Iris::unregister_interrupt (IRQ_RTC)
|
||||
ready ()
|
||||
rtc_disable_alarm ()
|
||||
reply.invoke ()
|
||||
Iris::free_cap (reply)
|
||||
case Iris::RTC::SET_ALARM:
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
Iris::Cap arg = Iris::get_arg ()
|
||||
unsigned alarm = Iris::recv.data[1].l
|
||||
ready ()
|
||||
rtc_clear_alarm_flag ()
|
||||
if have_interrupt:
|
||||
Iris::debug ("not registering irq\n")
|
||||
interrupt.invoke (~0)
|
||||
Iris::free_cap (interrupt)
|
||||
else:
|
||||
Iris::debug ("registering irq\n")
|
||||
Iris::register_interrupt (IRQ_RTC)
|
||||
interrupt = arg
|
||||
have_interrupt = true
|
||||
ready ()
|
||||
rtc_set_alarm_second (alarm)
|
||||
ready ()
|
||||
rtc_clear_alarm_flag ()
|
||||
ready ()
|
||||
rtc_enable_alarm ()
|
||||
reply.invoke ()
|
||||
Iris::free_cap (reply)
|
||||
break
|
||||
default:
|
||||
Iris::panic (Iris::recv.data[0].l, "invalid rtc request")
|
||||
return 0
|
||||
|
@ -95,7 +95,7 @@ bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigne
|
||||
MSC_IMASK = ~MSC_IMASK_END_CMD_RES
|
||||
Iris::register_interrupt (IRQ_MSC)
|
||||
msc_start_op ()
|
||||
Iris::wait_for_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt ()
|
||||
MSC_IMASK = ~0
|
||||
//kdebug ("cmd: ")
|
||||
//kdebug_num (cmd)
|
||||
@ -426,7 +426,7 @@ void Mmc::set_block (unsigned block):
|
||||
for unsigned a = 0; a < 1 << csd.write_bl_len; a += 4:
|
||||
while MSC_STAT & MSC_STAT_DATA_FIFO_FULL:
|
||||
Iris::register_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt ()
|
||||
MSC_TXFIFO = current_block[a >> 2]
|
||||
MSC_IMASK = ~0
|
||||
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
||||
@ -442,7 +442,7 @@ void Mmc::set_block (unsigned block):
|
||||
for unsigned aa = 0; aa < 1 << 9; aa += 4:
|
||||
while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
|
||||
Iris::register_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt ()
|
||||
current_block[(a + aa) >> 2] = MSC_RXFIFO
|
||||
MSC_IMASK = ~0
|
||||
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
||||
@ -485,13 +485,13 @@ void Mmc::wait_write ():
|
||||
MSC_IMASK = ~MSC_IMASK_PRG_DONE
|
||||
while !MSC_STAT & MSC_STAT_PRG_DONE:
|
||||
Iris::register_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt (IRQ_MSC)
|
||||
Iris::wait_for_interrupt ()
|
||||
MSC_IREG = MSC_IREG_PRG_DONE
|
||||
|
||||
static Mmc mmc
|
||||
|
||||
enum types:
|
||||
DETECT
|
||||
DETECT = 1
|
||||
REQUEST
|
||||
|
||||
Iris::Num start ():
|
||||
@ -525,15 +525,15 @@ Iris::Num start ():
|
||||
while true:
|
||||
Iris::wait ()
|
||||
switch Iris::recv.protected_data.l:
|
||||
case 0:
|
||||
mmc.interrupt ()
|
||||
break
|
||||
case DETECT:
|
||||
if Iris::recv.data[0].l:
|
||||
mmc.detect ()
|
||||
else:
|
||||
mmc.release ()
|
||||
break
|
||||
case IRQ_MSC:
|
||||
mmc.interrupt ()
|
||||
break
|
||||
case REQUEST:
|
||||
//kdebug ("sd+mmc request ")
|
||||
//kdebug_num (Iris::recv.data[0].l)
|
@ -247,7 +247,7 @@ class Pwm:
|
||||
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
||||
|
||||
enum codes:
|
||||
KEYBOARD = 32
|
||||
KEYBOARD = 1
|
||||
TOUCHPAD
|
||||
LOCKLEDS
|
||||
PWM
|
||||
@ -289,7 +289,7 @@ Iris::Num start ():
|
||||
if kbd.is_scanning ():
|
||||
Iris::my_receiver.set_alarm (ALARM_INTERVAL)
|
||||
break
|
||||
case IRQ_GPIO0:
|
||||
case 0:
|
||||
// Always scan keyboard and touchpad on any interrupt.
|
||||
kbd.scan ()
|
||||
tp.check_events ()
|
||||
|
@ -390,6 +390,7 @@ bool Udc::handle_setup (Setup *s, unsigned cmd):
|
||||
|
||||
void Udc::irq_usb (unsigned cmd):
|
||||
// Reset.
|
||||
//Iris::debug ("usb reset\n")
|
||||
state = IDLE
|
||||
|
||||
void Udc::irq_in (unsigned cmd):
|
||||
@ -507,11 +508,7 @@ void Udc::irq_out (unsigned cmd):
|
||||
Iris::panic (0)
|
||||
unsigned size = UDC_OUTCOUNT
|
||||
unsigned csr = UDC_OUTCSR
|
||||
//kdebug ("handling bulk interrupt for ")
|
||||
//kdebug_num (csr)
|
||||
//kdebug (" with ")
|
||||
//kdebug_num (size)
|
||||
//kdebug (" bytes.\n")
|
||||
//Iris::debug ("handling bulk interrupt for %x with %d bytes.\n", csr, size)
|
||||
csr &= ~UDC_OUTCSR_OUTPKTRDY
|
||||
for unsigned i = 0; i < size; i += 4:
|
||||
*p++ = UDC_FIFO (1)
|
||||
@ -534,13 +531,7 @@ void Udc::interrupt (unsigned cmd):
|
||||
unsigned out = UDC_INTROUT
|
||||
if !(usb & 4) && !(in & 1) && !(out & 2):
|
||||
break
|
||||
//kdebug ("interrupt: ")
|
||||
//kdebug_num (usb, 1)
|
||||
//kdebug ("/")
|
||||
//kdebug_num (in, 1)
|
||||
//kdebug ("/")
|
||||
//kdebug_num (out, 1)
|
||||
//kdebug ("\n")
|
||||
//Iris::debug ("interrupt: %d/%d/%d\n", usb, in, out)
|
||||
if usb & 4:
|
||||
irq_usb (cmd)
|
||||
if in & 1:
|
||||
@ -554,7 +545,7 @@ void Udc::log (unsigned c):
|
||||
log_buffer[log_buffer_size++] = c
|
||||
|
||||
enum pdata:
|
||||
LOG = 32
|
||||
LOG = 1
|
||||
DIRECTORY
|
||||
FILE
|
||||
NAME
|
||||
@ -565,20 +556,23 @@ Iris::Num start ():
|
||||
map_cpm ()
|
||||
Udc udc
|
||||
|
||||
Iris::Cap logcap = Iris::my_receiver.create_capability (LOG)
|
||||
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
||||
udc.init ()
|
||||
Iris::register_interrupt (IRQ_UDC)
|
||||
//Iris::Cap logcap = Iris::my_receiver.create_capability (LOG)
|
||||
//__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
||||
Iris::Directory dir = Iris::my_receiver.create_capability (DIRECTORY)
|
||||
Iris::my_parent.provide_capability <Iris::Directory> (dir.copy ())
|
||||
Iris::free_cap (dir)
|
||||
udc.init ()
|
||||
Iris::register_interrupt (IRQ_UDC)
|
||||
// Don't call init_done, because this can be used as bootthread and without a parent this call will not be answered.
|
||||
//Iris::my_parent.init_done ()
|
||||
unsigned state = 0
|
||||
while true:
|
||||
Iris::wait ()
|
||||
Iris::Cap reply = Iris::get_reply ()
|
||||
Iris::Cap arg = Iris::get_arg ()
|
||||
//Iris::debug ("udc event, protected: %x\n", Iris::recv.protected_data.l)
|
||||
switch Iris::recv.protected_data.l:
|
||||
case IRQ_UDC:
|
||||
case 0:
|
||||
udc.interrupt (state)
|
||||
Iris::register_interrupt (IRQ_UDC)
|
||||
break
|
||||
@ -586,7 +580,7 @@ Iris::Num start ():
|
||||
udc.log (Iris::recv.data[0].l)
|
||||
break
|
||||
case DIRECTORY:
|
||||
//kdebug ("dir request\n")
|
||||
//Iris::debug ("dir request %d\n", Iris::recv.data[0].l)
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::Directory::GET_NAME:
|
||||
Iris::Cap name = Iris::my_receiver.create_capability (Iris::Num (NAME, Iris::recv.data[1].l))
|
||||
@ -600,8 +594,7 @@ Iris::Num start ():
|
||||
case Iris::Directory::UNLOCK_RO:
|
||||
state = Iris::recv.data[0].l
|
||||
if Iris::recv.data[1].h != 0:
|
||||
kdebug ("index out of supported range\n")
|
||||
Iris::panic (0)
|
||||
Iris::panic (0, "index out of supported range")
|
||||
udc.send (Iris::recv.data[0].l, Iris::recv.data[1].l, reply, arg)
|
||||
continue
|
||||
case Iris::Directory::GET_FILE_RO:
|
||||
@ -623,7 +616,7 @@ Iris::Num start ():
|
||||
continue
|
||||
break
|
||||
case FILE:
|
||||
//kdebug ("file request\n")
|
||||
//Iris::debug ("file request %d\n", Iris::recv.data[0].l)
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::Block::GET_BLOCK:
|
||||
if Iris::recv.data[0].h != PAGE_SIZE << 16:
|
||||
@ -639,7 +632,7 @@ Iris::Num start ():
|
||||
continue
|
||||
break
|
||||
case NAME:
|
||||
//kdebug ("name request\n")
|
||||
//Iris::debug ("name request %d\n", Iris::recv.data[0].l)
|
||||
switch Iris::recv.data[0].l:
|
||||
case Iris::String::GET_SIZE:
|
||||
reply.invoke (16)
|
||||
|
Loading…
Reference in New Issue
Block a user