mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-12-29 20:31:09 +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.
|
// TODO: Interface is to be designed.
|
||||||
panic (0, "using undefined interface Display::get_info ()")
|
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.
|
// Numerical setting, such as a display backlight.
|
||||||
struct Setting : public Device:
|
struct Setting : public Device:
|
||||||
Setting (Cap c = Cap ()) : Device (c):
|
Setting (Cap c = Cap ()) : Device (c):
|
||||||
enum request:
|
enum request:
|
||||||
SET = Display::ID
|
SET = Font::ID
|
||||||
GET_RANGE
|
GET_RANGE
|
||||||
ID
|
ID
|
||||||
// Set a new value.
|
// Set a new value.
|
||||||
@ -394,6 +488,29 @@ namespace Iris:
|
|||||||
void exit ():
|
void exit ():
|
||||||
call (CAP_MASTER_DIRECT | 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.
|
// TODO.
|
||||||
// Sound interface.
|
// Sound interface.
|
||||||
// Usb interfaces (port, device).
|
// Usb interfaces (port, device).
|
||||||
|
51
init.config
51
init.config
@ -1,6 +1,6 @@
|
|||||||
# driver <name> = '<filename>' load a file into memory to be run priviledged.
|
# driver <name> = '<filename>' load a file into memory to be run priviledged.
|
||||||
# program <name> = '<filename>' load a file into memory to be run normally.
|
# 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.
|
# receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
|
||||||
# sysreq <cap> use a capability as the system request keyboard.
|
# 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.
|
# give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
|
||||||
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#file kernel = "kernel.raw"
|
#file kernel = "kernel.raw"
|
||||||
#program booter = "booter.elf"
|
#program booter = "booter.elf"
|
||||||
#give booter / String = kernel
|
#give booter / Block = kernel
|
||||||
#give booter / Boot = boot
|
#give booter / Boot = boot
|
||||||
|
|
||||||
driver driver_lcd = "lcd.elf"
|
driver driver_lcd = "lcd.elf"
|
||||||
@ -34,32 +34,47 @@
|
|||||||
driver driver_buzzer = "buzzer.elf"
|
driver driver_buzzer = "buzzer.elf"
|
||||||
receive driver_buzzer / Buzzer = buzzer
|
receive driver_buzzer / Buzzer = buzzer
|
||||||
|
|
||||||
program alarm = "alarm.elf"
|
#program alarm = "alarm.elf"
|
||||||
receive alarm / UI = ui
|
#receive alarm / UI = ui
|
||||||
|
|
||||||
program gui = "gui.elf"
|
#program gui = "gui.elf"
|
||||||
give gui / UI = ui
|
#give gui / UI = ui
|
||||||
give gui / Display = display
|
#give gui / Display = display
|
||||||
give gui / Setting = display_bright
|
#give gui / Setting = display_bright
|
||||||
give gui / Buzzer = buzzer
|
#give gui / Buzzer = buzzer
|
||||||
give gui / Keyboard = keyboard
|
#give gui / Keyboard = keyboard
|
||||||
|
|
||||||
#driver sdmmc = "sd+mmc.elf"
|
#driver sdmmc = "sd+mmc.elf"
|
||||||
#receive sdmmc / WString = sdmmc
|
#receive sdmmc / WBlock = sdmmc
|
||||||
#give sdmmc / Event = sdmmc_gpio
|
#give sdmmc / Event = sdmmc_gpio
|
||||||
|
|
||||||
#program partition = "partition.elf"
|
#program partition = "partition.elf"
|
||||||
#receive partition / WString, 0 = p0
|
#receive partition / WBlock, 0 = p0
|
||||||
#receive partition / WString, 1 = p1
|
#receive partition / WBlock, 1 = p1
|
||||||
#receive partition / WString, 2 = p2
|
#receive partition / WBlock, 2 = p2
|
||||||
#receive partition / WString, 3 = p3
|
#receive partition / WBlock, 3 = p3
|
||||||
#give partition / WString = sdmmc
|
#give partition / WBlock = sdmmc
|
||||||
|
|
||||||
#program fat = "fat.elf"
|
#program fat = "fat.elf"
|
||||||
#receive fat / Directory = root
|
#receive fat / Directory = root
|
||||||
#give fat / WString = p0
|
#give fat / WBlock = p0
|
||||||
|
|
||||||
#program test = "test.elf"
|
#program test = "test.elf"
|
||||||
#give test / Directory = root
|
#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 ()
|
arch_reboot ()
|
||||||
case Iris::Thread::PRIV_POWEROFF & REQUEST_MASK:
|
case Iris::Thread::PRIV_POWEROFF & REQUEST_MASK:
|
||||||
arch_poweroff ()
|
arch_poweroff ()
|
||||||
|
case Iris::Thread::PRIV_SUSPEND & REQUEST_MASK:
|
||||||
|
arch_suspend ()
|
||||||
|
reply_num (~0)
|
||||||
|
return
|
||||||
case Iris::Thread::PRIV_BOOT & REQUEST_MASK:
|
case Iris::Thread::PRIV_BOOT & REQUEST_MASK:
|
||||||
arch_boot (c->data[1].l, c->data[1].h)
|
arch_boot (c->data[1].l, c->data[1].h)
|
||||||
case Iris::Thread::PRIV_PANIC & REQUEST_MASK:
|
case Iris::Thread::PRIV_PANIC & REQUEST_MASK:
|
||||||
|
13
iris.hhp
13
iris.hhp
@ -323,6 +323,7 @@ namespace Iris:
|
|||||||
DBG_SEND
|
DBG_SEND
|
||||||
PRIV_REBOOT
|
PRIV_REBOOT
|
||||||
PRIV_POWEROFF
|
PRIV_POWEROFF
|
||||||
|
PRIV_SUSPEND
|
||||||
PRIV_BOOT
|
PRIV_BOOT
|
||||||
PRIV_PANIC
|
PRIV_PANIC
|
||||||
// These get/set_info are not arch-specific.
|
// 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)
|
my_thread.ocall (my_receiver, CAP_MASTER_DIRECT | Thread::PRIV_REGISTER_INTERRUPT, num)
|
||||||
inline void unregister_interrupt (unsigned num):
|
inline void unregister_interrupt (unsigned num):
|
||||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REGISTER_INTERRUPT, num)
|
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REGISTER_INTERRUPT, num)
|
||||||
inline void wait_for_interrupt (unsigned num):
|
inline unsigned wait_for_interrupt ():
|
||||||
my_receiver.set_reply_protected_data (num)
|
my_receiver.set_reply_protected_data (0)
|
||||||
Cap ().call ()
|
Cap ().call ()
|
||||||
|
unsigned ret = recv.data[0].l
|
||||||
my_receiver.set_reply_protected_data (~0)
|
my_receiver.set_reply_protected_data (~0)
|
||||||
|
return ret
|
||||||
inline Cap get_top_memory ():
|
inline Cap get_top_memory ():
|
||||||
my_thread.icall (CAP_MASTER_DIRECT | Thread::PRIV_GET_TOP_MEMORY)
|
my_thread.icall (CAP_MASTER_DIRECT | Thread::PRIV_GET_TOP_MEMORY)
|
||||||
return get_arg ()
|
return get_arg ()
|
||||||
@ -591,6 +594,8 @@ namespace Iris:
|
|||||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT)
|
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT)
|
||||||
inline void poweroff ():
|
inline void poweroff ():
|
||||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_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):
|
inline void boot (unsigned address, unsigned arg):
|
||||||
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_BOOT, Iris::Num (address, arg))
|
my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_BOOT, Iris::Num (address, arg))
|
||||||
|
|
||||||
@ -668,6 +673,10 @@ namespace Iris:
|
|||||||
++last
|
++last
|
||||||
kdebug ((char *)*last)
|
kdebug ((char *)*last)
|
||||||
break
|
break
|
||||||
|
case 'c':
|
||||||
|
++last
|
||||||
|
kdebug_char (*last)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
panic (*f, "invalid character in dbg format string")
|
panic (*f, "invalid character in dbg format string")
|
||||||
else:
|
else:
|
||||||
|
@ -324,6 +324,7 @@ void kPage_arch_update_mapping (kPage *page)
|
|||||||
void arch_register_interrupt (unsigned num, kReceiverP r)
|
void arch_register_interrupt (unsigned num, kReceiverP r)
|
||||||
void arch_reboot ()
|
void arch_reboot ()
|
||||||
void arch_poweroff ()
|
void arch_poweroff ()
|
||||||
|
void arch_suspend ()
|
||||||
void arch_boot (unsigned address, unsigned arg)
|
void arch_boot (unsigned address, unsigned arg)
|
||||||
void arch_uncache_page (unsigned page)
|
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.
|
// These are "extern", not "EXTERN", because they really are defined elsewhere.
|
||||||
#ifdef INIT
|
#ifdef INIT
|
||||||
extern unsigned thread_start[NUM_THREADS + 1]
|
extern unsigned *thread_start
|
||||||
#endif
|
#endif
|
||||||
// Fast pointer to page directory, for tlb miss events
|
// Fast pointer to page directory, for tlb miss events
|
||||||
extern Table **directory
|
extern Table **directory
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#define ARCH
|
#define ARCH
|
||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
|
|
||||||
|
#define MEMORY_SIZE (32 << 20)
|
||||||
|
#define KERNEL_STACK_SIZE 0x1000
|
||||||
// The kernel stack.
|
// The kernel stack.
|
||||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#define KERNEL_STACK_SIZE 0x1000
|
||||||
// The kernel stack.
|
// The kernel stack.
|
||||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||||
|
|
||||||
|
@ -118,7 +118,8 @@ static void init_threads ():
|
|||||||
first_scheduled = NULL
|
first_scheduled = NULL
|
||||||
first_alarm = NULL
|
first_alarm = NULL
|
||||||
kReceiver *init_receiver = 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 ()
|
kMemory *mem = top_memory.alloc_memory ()
|
||||||
assert (mem)
|
assert (mem)
|
||||||
kThread *thread = mem->alloc_thread (NUM_SLOTS)
|
kThread *thread = mem->alloc_thread (NUM_SLOTS)
|
||||||
@ -269,6 +270,7 @@ static void init_threads ():
|
|||||||
thread->schedule_prev = previous
|
thread->schedule_prev = previous
|
||||||
thread->schedule_next = NULL
|
thread->schedule_next = NULL
|
||||||
previous = thread
|
previous = thread
|
||||||
|
++i
|
||||||
|
|
||||||
// Initialize the kernel, finish by falling into the idle task.
|
// Initialize the kernel, finish by falling into the idle task.
|
||||||
void init (unsigned mem):
|
void init (unsigned mem):
|
||||||
|
@ -126,9 +126,9 @@ kThread *interrupt ():
|
|||||||
// Send message to interrupt handler.
|
// Send message to interrupt handler.
|
||||||
if arch_interrupt_receiver[i]:
|
if arch_interrupt_receiver[i]:
|
||||||
kCapability::Context c
|
kCapability::Context c
|
||||||
for unsigned j = 0; j < 2; ++j:
|
c.data[0] = i
|
||||||
c.data[j] = 0
|
c.data[1] = 0
|
||||||
arch_interrupt_receiver[i]->send_message (i, &c)
|
arch_interrupt_receiver[i]->send_message (0, &c)
|
||||||
arch_interrupt_receiver[i] = NULL
|
arch_interrupt_receiver[i] = NULL
|
||||||
if ipr & (1 << TIMER_INTERRUPT):
|
if ipr & (1 << TIMER_INTERRUPT):
|
||||||
#if defined (TRENDTAC)
|
#if defined (TRENDTAC)
|
||||||
|
@ -31,7 +31,7 @@ unbrick_boot_programs = nand sd+mmc usb-mass-storage
|
|||||||
standard_boot_programs = bootinit
|
standard_boot_programs = bootinit
|
||||||
|
|
||||||
# use sort to remove duplicates.
|
# 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
|
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
|
@ -84,22 +84,39 @@ void arch_reboot ():
|
|||||||
while true:
|
while true:
|
||||||
|
|
||||||
void arch_poweroff ():
|
void arch_poweroff ():
|
||||||
sync_serial ()
|
|
||||||
// Power off.
|
// 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.
|
// Make sure the rtc is running.
|
||||||
cpm_start_rtc ()
|
cpm_start_rtc ()
|
||||||
while !rtc_write_ready ():
|
while !rtc_write_ready ():
|
||||||
rtc_enabled ()
|
rtc_enabled ()
|
||||||
while !rtc_write_ready ():
|
while !rtc_write_ready ():
|
||||||
|
kdebug ("Power down.\n")
|
||||||
|
sync_serial ()
|
||||||
rtc_power_down ()
|
rtc_power_down ()
|
||||||
// Wait for power down to work.
|
// Wait for power down to work.
|
||||||
while !rtc_write_ready ():
|
while true:
|
||||||
// Delay a bit more.
|
asm ("wait")
|
||||||
for unsigned i = 0; i < 1000; ++i:
|
|
||||||
gpio_set (0, 0)
|
void arch_suspend ():
|
||||||
// Fall back to reboot.
|
sync_serial ()
|
||||||
kdebug ("Power down failed! Rebooting instead.\n")
|
// Suspend the system: go into SLEEP mode.
|
||||||
arch_reboot ()
|
cpm_sleep_mode ()
|
||||||
|
asm ("wait")
|
||||||
|
cpm_idle_mode ()
|
||||||
|
|
||||||
// Boot into another kernel.
|
// Boot into another kernel.
|
||||||
void arch_boot (unsigned address, unsigned arg):
|
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_disabled() ( RTC_RCR &= ~RTC_RCR_RTCE )
|
||||||
#define rtc_enable_alarm() ( RTC_RCR |= RTC_RCR_AE )
|
#define rtc_enable_alarm() ( RTC_RCR |= RTC_RCR_AE )
|
||||||
#define rtc_disable_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_enable_alarm_irq() ( RTC_RCR |= RTC_RCR_AIE )
|
||||||
#define rtc_disable_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 )
|
#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[1]
|
||||||
extern char stage1_end[1]
|
extern char stage1_end[1]
|
||||||
|
|
||||||
unsigned const stage1_load = 0x80002000
|
unsigned const stage1_load = 0x80003000
|
||||||
unsigned const stage1_start = 0x80002000
|
unsigned const stage1_start = 0x80003000
|
||||||
unsigned const stage1_size = stage1_end - stage1
|
unsigned const stage1_size = stage1_end - stage1
|
||||||
|
|
||||||
class nanonote:
|
class nanonote:
|
||||||
|
@ -30,17 +30,18 @@ asm volatile (".set noreorder\n"
|
|||||||
".globl __start\n"
|
".globl __start\n"
|
||||||
".text\n"
|
".text\n"
|
||||||
"__start:\n"
|
"__start:\n"
|
||||||
"\tnop\n"
|
"\tmove $t0, $ra\n" // 0
|
||||||
"__hack_label:\n"
|
"\tnop\n" // 4
|
||||||
"\tmove $k0, $ra\n"
|
"\tbal 1f\n" // 8
|
||||||
"\tbal 1f\n"
|
"\tnop\n" // 12
|
||||||
"\tnop\n"
|
"\t.word _gp\n" // 16
|
||||||
"\t.word _gp\n"
|
"\t.word 0\n" // 20: This is overwritten in software usbboot mode.
|
||||||
"1:\n"
|
"1:\n"
|
||||||
"\tlw $gp, 0($ra)\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"
|
"\tla $t9, start_cpp\n"
|
||||||
"\tmove $ra, $k0\n"
|
"\tmove $ra, $t0\n"
|
||||||
"\tjr $t9\n"
|
"\tjr $t9\n"
|
||||||
"\tnop\n"
|
"\tnop\n"
|
||||||
".set reorder")
|
".set reorder")
|
||||||
@ -53,12 +54,13 @@ void kdebug (unsigned ch):
|
|||||||
while !(UART0_LSR & UARTLSR_TEMT):
|
while !(UART0_LSR & UARTLSR_TEMT):
|
||||||
|
|
||||||
extern "C":
|
extern "C":
|
||||||
void start_cpp ()
|
void start_cpp (int skip_memsetup)
|
||||||
char stack[0x100]
|
char stack[0x40]
|
||||||
|
|
||||||
void start_cpp ():
|
void start_cpp (int skip_memsetup):
|
||||||
setup_uart ()
|
setup_uart ()
|
||||||
kdebug ('.')
|
kdebug ('.')
|
||||||
|
if !skip_memsetup:
|
||||||
setup_sdram ()
|
setup_sdram ()
|
||||||
kdebug ('!')
|
kdebug ('!')
|
||||||
// everything is ok now: return to boot loader to load stage 2.
|
// everything is ok now: return to boot loader to load stage 2.
|
||||||
|
@ -2,7 +2,7 @@ OUTPUT_ARCH(mips)
|
|||||||
ENTRY(__start)
|
ENTRY(__start)
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
ram : ORIGIN = 0x80002000 , LENGTH = 0x2000
|
ram : ORIGIN = 0x80003000 , LENGTH = 0x800
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
|
@ -48,7 +48,7 @@ struct data:
|
|||||||
server->open (port)
|
server->open (port)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned const STAGE1_LOAD = 0x80002000
|
static unsigned const STAGE1_LOAD = 0x80003000
|
||||||
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
|
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
|
||||||
enum requests:
|
enum requests:
|
||||||
VR_GET_CPU_INFO = 0
|
VR_GET_CPU_INFO = 0
|
||||||
@ -245,6 +245,7 @@ void data::send_file (unsigned address, unsigned size, char const *data):
|
|||||||
handle = NULL
|
handle = NULL
|
||||||
return
|
return
|
||||||
ptr += ret
|
ptr += ret
|
||||||
|
std::cerr << shevek::ostring ("sent %d bytes\n", size)
|
||||||
|
|
||||||
void data::get_device (unsigned vendor, unsigned product, unsigned tries):
|
void data::get_device (unsigned vendor, unsigned product, unsigned tries):
|
||||||
for unsigned i = 0; i < tries; ++i:
|
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 ():
|
static void dump_devices ():
|
||||||
std::cerr << std::hex << "String: " << Iris::String::ID
|
std::cerr << std::hex << "String: " << Iris::String::ID
|
||||||
|
std::cerr << "\nBlock: " << Iris::Block::ID
|
||||||
std::cerr << "\nWString: " << Iris::WString::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 << "\nDevice: " << Iris::Device::ID
|
||||||
|
std::cerr << "\nEvent: " << Iris::Event::ID
|
||||||
|
std::cerr << "\nElfrun: " << Iris::Elfrun::ID
|
||||||
std::cerr << "\nParent: " << Iris::Parent::ID
|
std::cerr << "\nParent: " << Iris::Parent::ID
|
||||||
std::cerr << "\nKeyboard: " << Iris::Keyboard::ID
|
std::cerr << "\nKeyboard: " << Iris::Keyboard::ID
|
||||||
std::cerr << "\nBuzzer: " << Iris::Buzzer::ID
|
std::cerr << "\nBuzzer: " << Iris::Buzzer::ID
|
||||||
std::cerr << "\nDisplay: " << Iris::Display::ID
|
std::cerr << "\nDisplay: " << Iris::Display::ID
|
||||||
|
std::cerr << "\nFont: " << Iris::Display::ID
|
||||||
std::cerr << "\nSetting: " << Iris::Setting::ID
|
std::cerr << "\nSetting: " << Iris::Setting::ID
|
||||||
std::cerr << "\nDirectory: " << Iris::Directory::ID
|
std::cerr << "\nDirectory: " << Iris::Directory::ID
|
||||||
std::cerr << "\nWDirectory: " << Iris::WDirectory::ID
|
std::cerr << "\nWDirectory: " << Iris::WDirectory::ID
|
||||||
std::cerr << "\nStream: " << Iris::Stream::ID
|
std::cerr << "\nStream: " << Iris::Stream::ID
|
||||||
|
std::cerr << "\nUI: " << Iris::UI::ID
|
||||||
std::cerr << "\n"
|
std::cerr << "\n"
|
||||||
|
|
||||||
int main (int argc, char **argv):
|
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 int const run_product = 0x0002
|
||||||
static unsigned const timeout = 10000
|
static unsigned const timeout = 10000
|
||||||
void boot (std::string const &filename, unsigned load, unsigned entry)
|
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
|
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
|
||||||
enum requests:
|
enum requests:
|
||||||
VR_GET_CPU_INFO = 0
|
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
|
103
source/alarm.ccp
103
source/alarm.ccp
@ -1,73 +1,50 @@
|
|||||||
#pypp 0
|
#pypp 0
|
||||||
#include <iris.hh>
|
#include <iris.hh>
|
||||||
#include <ui.hh>
|
#include <devices.hh>
|
||||||
|
|
||||||
enum Ins:
|
enum captypes:
|
||||||
TOTAL_TIME
|
CONTROL = 1
|
||||||
START
|
KBD
|
||||||
NUM_INS
|
INTERRUPT
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
Iris::Num start ():
|
Iris::Num start ():
|
||||||
ticking = false;
|
unsigned *screen = (unsigned *)0x40000000
|
||||||
Iris::Cap ui_cap = Iris::my_receiver.create_capability (0)
|
Iris::RTC rtc = Iris::my_parent.get_capability <Iris::RTC> ()
|
||||||
ui.init (ui_cap.copy ());
|
Iris::Display display = Iris::my_parent.get_capability <Iris::Display> ()
|
||||||
Iris::free_cap (ui_cap)
|
display.map_fb ((unsigned)screen)
|
||||||
total_time.init ()
|
Iris::Font font = Iris::my_parent.get_capability <Iris::Font> ()
|
||||||
do_start.init ()
|
font.set_display (display)
|
||||||
current_time.init ()
|
Iris::Keyboard keyboard = Iris::my_parent.get_capability <Iris::Keyboard> ()
|
||||||
do_alarm.init ()
|
Iris::Cap cap = Iris::my_receiver.create_capability (KBD)
|
||||||
ui.add_in (&total_time, TOTAL_TIME);
|
keyboard.set_cb (cap.copy ())
|
||||||
ui.add_in (&do_start, START);
|
Iris::free_cap (cap)
|
||||||
ui.add_out (¤t_time, CURRENT_TIME);
|
Iris::Buzzer buzzer = Iris::my_parent.get_capability <Iris::Buzzer> ()
|
||||||
ui.add_out (&do_alarm, ALARM);
|
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 ()
|
Iris::my_parent.init_done ()
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
Iris::wait ()
|
Iris::wait ()
|
||||||
switch Iris::recv.protected_data.l:
|
switch Iris::recv.protected_data.l:
|
||||||
case ~0:
|
case INTERRUPT:
|
||||||
// alarm.
|
// Interrupt
|
||||||
if current_time:
|
if Iris::recv.data[0].l == ~0:
|
||||||
current_time = current_time - 1
|
// Not a real interrupt, just an abort notification.
|
||||||
if !current_time:
|
|
||||||
do_alarm ()
|
|
||||||
ticking = false
|
|
||||||
else:
|
|
||||||
// TODO: use rtc for scheduling an event.
|
|
||||||
Iris::my_receiver.set_alarm (HZ)
|
|
||||||
continue
|
continue
|
||||||
case 0:
|
font.printf ("alarm: interrupt\n")
|
||||||
// ui event.
|
break
|
||||||
if !ui.event (&event):
|
case CONTROL:
|
||||||
// Exit request.
|
// Store callback
|
||||||
return 0
|
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::Memory top_memory = Iris::get_top_memory ()
|
||||||
Iris::Directory root = receive_devices ()
|
Iris::Directory root = receive_devices ()
|
||||||
root.lock_ro ()
|
root.lock_ro ()
|
||||||
|
kdebug_line ()
|
||||||
Iris::Block run_block = find (root, ELFRUN_NAME)
|
Iris::Block run_block = find (root, ELFRUN_NAME)
|
||||||
|
kdebug_line ()
|
||||||
Iris::Cap parent_cap = Iris::my_receiver.create_capability (0)
|
Iris::Cap parent_cap = Iris::my_receiver.create_capability (0)
|
||||||
|
kdebug_line ()
|
||||||
run (run_block, top_memory, parent_cap)
|
run (run_block, top_memory, parent_cap)
|
||||||
|
kdebug_line ()
|
||||||
Iris::wait ()
|
Iris::wait ()
|
||||||
|
kdebug_line ()
|
||||||
if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY || Iris::recv.data[1].l != Iris::Elfrun::ID:
|
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::panic (0, "elfrun doesn't provide correct capability")
|
||||||
Iris::Cap reply = Iris::get_reply ()
|
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 },
|
{ "Keyboard", 8, Iris::Keyboard::ID },
|
||||||
{ "Buzzer", 6, Iris::Buzzer::ID },
|
{ "Buzzer", 6, Iris::Buzzer::ID },
|
||||||
{ "Display", 7, Iris::Display::ID },
|
{ "Display", 7, Iris::Display::ID },
|
||||||
|
{ "Font", 4, Iris::Font::ID },
|
||||||
{ "Setting", 7, Iris::Setting::ID },
|
{ "Setting", 7, Iris::Setting::ID },
|
||||||
{ "Directory", 9, Iris::Directory::ID },
|
{ "Directory", 9, Iris::Directory::ID },
|
||||||
{ "WDirectory", 10, Iris::WDirectory::ID },
|
{ "WDirectory", 10, Iris::WDirectory::ID },
|
||||||
{ "Stream", 6, Iris::Stream::ID },
|
{ "Stream", 6, Iris::Stream::ID },
|
||||||
{ "UI", 2, Iris::UI::ID },
|
{ "UI", 2, Iris::UI::ID },
|
||||||
|
{ "RTC", 3, Iris::RTC::ID },
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,9 +516,9 @@ Iris::Num start ():
|
|||||||
switch Iris::recv.protected_data.l:
|
switch Iris::recv.protected_data.l:
|
||||||
case SYSREQ:
|
case SYSREQ:
|
||||||
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
||||||
Iris::poweroff ()
|
Iris::reboot ()
|
||||||
continue
|
continue
|
||||||
kdebug ("sysreq event: powering device off at release\n")
|
kdebug ("sysreq event: rebooting device at release\n")
|
||||||
continue
|
continue
|
||||||
case FILE:
|
case FILE:
|
||||||
File *file = (File *)Iris::recv.protected_data.h
|
File *file = (File *)Iris::recv.protected_data.h
|
||||||
@ -563,6 +565,7 @@ Iris::Num start ():
|
|||||||
if (*d)->type == type && (*d)->index == index:
|
if (*d)->type == type && (*d)->index == index:
|
||||||
break
|
break
|
||||||
if !d:
|
if !d:
|
||||||
|
Iris::debug ("requested %x by %s\n", type, caller->name)
|
||||||
Iris::panic (type, "unregistered device requested")
|
Iris::panic (type, "unregistered device requested")
|
||||||
Iris::recv.reply.invoke (0, 0, (*d)->dev->cap)
|
Iris::recv.reply.invoke (0, 0, (*d)->dev->cap)
|
||||||
//kdebug ("given device ")
|
//kdebug ("given device ")
|
||||||
|
@ -244,7 +244,7 @@ static void log_msg ():
|
|||||||
log_char ('\n')
|
log_char ('\n')
|
||||||
|
|
||||||
enum captype:
|
enum captype:
|
||||||
LOG = 32
|
LOG = 1
|
||||||
BACKLIGHT
|
BACKLIGHT
|
||||||
LCD
|
LCD
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ Iris::Num start ():
|
|||||||
Iris::wait ()
|
Iris::wait ()
|
||||||
//log_msg ()
|
//log_msg ()
|
||||||
switch Iris::recv.protected_data.l:
|
switch Iris::recv.protected_data.l:
|
||||||
case IRQ_LCD:
|
case 0:
|
||||||
have_eof = false
|
have_eof = false
|
||||||
eof_cb.invoke ()
|
eof_cb.invoke ()
|
||||||
Iris::free_cap (eof_cb)
|
Iris::free_cap (eof_cb)
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
#include "keys.hh"
|
#include "keys.hh"
|
||||||
|
|
||||||
//#define QI
|
#define QI
|
||||||
#define SCAN_INTERVAL HZ / 50
|
#define SCAN_INTERVAL HZ / 50
|
||||||
|
|
||||||
class DevKbd:
|
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::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::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::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::TAB, Key::CAPS_LOCK, 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::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::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
|
#else
|
||||||
{ Key::ESCAPE, Key::TAB, Key::F1, Key::F2, Key::F3, Key::F4, Key::SPECIAL + 0, ~0 },
|
{ 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 },
|
{ 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::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::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::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::TAB, Key::CAPS_LOCK, 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::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::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
|
#else
|
||||||
Key::ESCAPE, Key::TAB, Key::F1, Key::F2, Key::F3, Key::F4, Key::SPECIAL + 0,
|
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,
|
Key::N1, Key::N2, Key::N3, Key::N4, Key::N5, Key::N6, Key::N7, Key::N8,
|
||||||
@ -195,7 +195,7 @@ class Event:
|
|||||||
scan ()
|
scan ()
|
||||||
|
|
||||||
enum codes:
|
enum codes:
|
||||||
KBD_DEV = 32
|
KBD_DEV = 1
|
||||||
PWR
|
PWR
|
||||||
SDMMC
|
SDMMC
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ Iris::Num start ():
|
|||||||
Iris::my_receiver.set_alarm (SCAN_INTERVAL)
|
Iris::my_receiver.set_alarm (SCAN_INTERVAL)
|
||||||
continue
|
continue
|
||||||
switch Iris::recv.protected_data.l:
|
switch Iris::recv.protected_data.l:
|
||||||
case IRQ_GPIO3:
|
case 0:
|
||||||
// Interrupt.
|
// Interrupt.
|
||||||
pwr.scan ()
|
pwr.scan ()
|
||||||
kbd.scan ()
|
kbd.scan ()
|
||||||
|
101
source/rtc.ccp
101
source/rtc.ccp
@ -20,6 +20,8 @@
|
|||||||
#define ARCH
|
#define ARCH
|
||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
|
|
||||||
|
static Iris::Font font
|
||||||
|
|
||||||
static void ready ():
|
static void ready ():
|
||||||
while !rtc_write_ready ():
|
while !rtc_write_ready ():
|
||||||
Iris::schedule ()
|
Iris::schedule ()
|
||||||
@ -42,17 +44,104 @@ Iris::Num start ():
|
|||||||
cpm_start_rtc ()
|
cpm_start_rtc ()
|
||||||
ready ()
|
ready ()
|
||||||
rtc_enabled ()
|
rtc_enabled ()
|
||||||
|
if rtc_get_scratch_pattern () != 0xbeefface:
|
||||||
ready ()
|
ready ()
|
||||||
rtc_set_nc1Hz_val (RTC_CLOCK)
|
rtc_set_nc1Hz_val (RTC_CLOCK)
|
||||||
ready ()
|
ready ()
|
||||||
rtc_enable_1Hz_irq ()
|
rtc_set_adjc_val (0)
|
||||||
|
ready ()
|
||||||
|
rtc_set_second (0)
|
||||||
|
ready ()
|
||||||
|
rtc_disable_1Hz_irq ()
|
||||||
|
ready ()
|
||||||
|
rtc_disable_alarm ()
|
||||||
|
ready ()
|
||||||
rtc_clear_alarm_flag ()
|
rtc_clear_alarm_flag ()
|
||||||
|
ready ()
|
||||||
|
rtc_enable_alarm_irq ()
|
||||||
|
ready ()
|
||||||
rtc_set_hwfcr_val (0)
|
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:
|
while true:
|
||||||
ready ()
|
|
||||||
rtc_clear_1Hz_flag ()
|
|
||||||
ready ()
|
|
||||||
Iris::register_interrupt (IRQ_RTC)
|
|
||||||
Iris::wait ()
|
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
|
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
|
MSC_IMASK = ~MSC_IMASK_END_CMD_RES
|
||||||
Iris::register_interrupt (IRQ_MSC)
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
msc_start_op ()
|
msc_start_op ()
|
||||||
Iris::wait_for_interrupt (IRQ_MSC)
|
Iris::wait_for_interrupt ()
|
||||||
MSC_IMASK = ~0
|
MSC_IMASK = ~0
|
||||||
//kdebug ("cmd: ")
|
//kdebug ("cmd: ")
|
||||||
//kdebug_num (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:
|
for unsigned a = 0; a < 1 << csd.write_bl_len; a += 4:
|
||||||
while MSC_STAT & MSC_STAT_DATA_FIFO_FULL:
|
while MSC_STAT & MSC_STAT_DATA_FIFO_FULL:
|
||||||
Iris::register_interrupt (IRQ_MSC)
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
Iris::wait_for_interrupt (IRQ_MSC)
|
Iris::wait_for_interrupt ()
|
||||||
MSC_TXFIFO = current_block[a >> 2]
|
MSC_TXFIFO = current_block[a >> 2]
|
||||||
MSC_IMASK = ~0
|
MSC_IMASK = ~0
|
||||||
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
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:
|
for unsigned aa = 0; aa < 1 << 9; aa += 4:
|
||||||
while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
|
while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
|
||||||
Iris::register_interrupt (IRQ_MSC)
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
Iris::wait_for_interrupt (IRQ_MSC)
|
Iris::wait_for_interrupt ()
|
||||||
current_block[(a + aa) >> 2] = MSC_RXFIFO
|
current_block[(a + aa) >> 2] = MSC_RXFIFO
|
||||||
MSC_IMASK = ~0
|
MSC_IMASK = ~0
|
||||||
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
||||||
@ -485,13 +485,13 @@ void Mmc::wait_write ():
|
|||||||
MSC_IMASK = ~MSC_IMASK_PRG_DONE
|
MSC_IMASK = ~MSC_IMASK_PRG_DONE
|
||||||
while !MSC_STAT & MSC_STAT_PRG_DONE:
|
while !MSC_STAT & MSC_STAT_PRG_DONE:
|
||||||
Iris::register_interrupt (IRQ_MSC)
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
Iris::wait_for_interrupt (IRQ_MSC)
|
Iris::wait_for_interrupt ()
|
||||||
MSC_IREG = MSC_IREG_PRG_DONE
|
MSC_IREG = MSC_IREG_PRG_DONE
|
||||||
|
|
||||||
static Mmc mmc
|
static Mmc mmc
|
||||||
|
|
||||||
enum types:
|
enum types:
|
||||||
DETECT
|
DETECT = 1
|
||||||
REQUEST
|
REQUEST
|
||||||
|
|
||||||
Iris::Num start ():
|
Iris::Num start ():
|
||||||
@ -525,15 +525,15 @@ Iris::Num start ():
|
|||||||
while true:
|
while true:
|
||||||
Iris::wait ()
|
Iris::wait ()
|
||||||
switch Iris::recv.protected_data.l:
|
switch Iris::recv.protected_data.l:
|
||||||
|
case 0:
|
||||||
|
mmc.interrupt ()
|
||||||
|
break
|
||||||
case DETECT:
|
case DETECT:
|
||||||
if Iris::recv.data[0].l:
|
if Iris::recv.data[0].l:
|
||||||
mmc.detect ()
|
mmc.detect ()
|
||||||
else:
|
else:
|
||||||
mmc.release ()
|
mmc.release ()
|
||||||
break
|
break
|
||||||
case IRQ_MSC:
|
|
||||||
mmc.interrupt ()
|
|
||||||
break
|
|
||||||
case REQUEST:
|
case REQUEST:
|
||||||
//kdebug ("sd+mmc request ")
|
//kdebug ("sd+mmc request ")
|
||||||
//kdebug_num (Iris::recv.data[0].l)
|
//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.
|
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
||||||
|
|
||||||
enum codes:
|
enum codes:
|
||||||
KEYBOARD = 32
|
KEYBOARD = 1
|
||||||
TOUCHPAD
|
TOUCHPAD
|
||||||
LOCKLEDS
|
LOCKLEDS
|
||||||
PWM
|
PWM
|
||||||
@ -289,7 +289,7 @@ Iris::Num start ():
|
|||||||
if kbd.is_scanning ():
|
if kbd.is_scanning ():
|
||||||
Iris::my_receiver.set_alarm (ALARM_INTERVAL)
|
Iris::my_receiver.set_alarm (ALARM_INTERVAL)
|
||||||
break
|
break
|
||||||
case IRQ_GPIO0:
|
case 0:
|
||||||
// Always scan keyboard and touchpad on any interrupt.
|
// Always scan keyboard and touchpad on any interrupt.
|
||||||
kbd.scan ()
|
kbd.scan ()
|
||||||
tp.check_events ()
|
tp.check_events ()
|
||||||
|
@ -390,6 +390,7 @@ bool Udc::handle_setup (Setup *s, unsigned cmd):
|
|||||||
|
|
||||||
void Udc::irq_usb (unsigned cmd):
|
void Udc::irq_usb (unsigned cmd):
|
||||||
// Reset.
|
// Reset.
|
||||||
|
//Iris::debug ("usb reset\n")
|
||||||
state = IDLE
|
state = IDLE
|
||||||
|
|
||||||
void Udc::irq_in (unsigned cmd):
|
void Udc::irq_in (unsigned cmd):
|
||||||
@ -507,11 +508,7 @@ void Udc::irq_out (unsigned cmd):
|
|||||||
Iris::panic (0)
|
Iris::panic (0)
|
||||||
unsigned size = UDC_OUTCOUNT
|
unsigned size = UDC_OUTCOUNT
|
||||||
unsigned csr = UDC_OUTCSR
|
unsigned csr = UDC_OUTCSR
|
||||||
//kdebug ("handling bulk interrupt for ")
|
//Iris::debug ("handling bulk interrupt for %x with %d bytes.\n", csr, size)
|
||||||
//kdebug_num (csr)
|
|
||||||
//kdebug (" with ")
|
|
||||||
//kdebug_num (size)
|
|
||||||
//kdebug (" bytes.\n")
|
|
||||||
csr &= ~UDC_OUTCSR_OUTPKTRDY
|
csr &= ~UDC_OUTCSR_OUTPKTRDY
|
||||||
for unsigned i = 0; i < size; i += 4:
|
for unsigned i = 0; i < size; i += 4:
|
||||||
*p++ = UDC_FIFO (1)
|
*p++ = UDC_FIFO (1)
|
||||||
@ -534,13 +531,7 @@ void Udc::interrupt (unsigned cmd):
|
|||||||
unsigned out = UDC_INTROUT
|
unsigned out = UDC_INTROUT
|
||||||
if !(usb & 4) && !(in & 1) && !(out & 2):
|
if !(usb & 4) && !(in & 1) && !(out & 2):
|
||||||
break
|
break
|
||||||
//kdebug ("interrupt: ")
|
//Iris::debug ("interrupt: %d/%d/%d\n", usb, in, out)
|
||||||
//kdebug_num (usb, 1)
|
|
||||||
//kdebug ("/")
|
|
||||||
//kdebug_num (in, 1)
|
|
||||||
//kdebug ("/")
|
|
||||||
//kdebug_num (out, 1)
|
|
||||||
//kdebug ("\n")
|
|
||||||
if usb & 4:
|
if usb & 4:
|
||||||
irq_usb (cmd)
|
irq_usb (cmd)
|
||||||
if in & 1:
|
if in & 1:
|
||||||
@ -554,7 +545,7 @@ void Udc::log (unsigned c):
|
|||||||
log_buffer[log_buffer_size++] = c
|
log_buffer[log_buffer_size++] = c
|
||||||
|
|
||||||
enum pdata:
|
enum pdata:
|
||||||
LOG = 32
|
LOG = 1
|
||||||
DIRECTORY
|
DIRECTORY
|
||||||
FILE
|
FILE
|
||||||
NAME
|
NAME
|
||||||
@ -565,20 +556,23 @@ Iris::Num start ():
|
|||||||
map_cpm ()
|
map_cpm ()
|
||||||
Udc udc
|
Udc udc
|
||||||
|
|
||||||
Iris::Cap logcap = Iris::my_receiver.create_capability (LOG)
|
//Iris::Cap logcap = Iris::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 ()
|
|
||||||
Iris::register_interrupt (IRQ_UDC)
|
|
||||||
Iris::Directory dir = Iris::my_receiver.create_capability (DIRECTORY)
|
Iris::Directory dir = Iris::my_receiver.create_capability (DIRECTORY)
|
||||||
Iris::my_parent.provide_capability <Iris::Directory> (dir.copy ())
|
Iris::my_parent.provide_capability <Iris::Directory> (dir.copy ())
|
||||||
Iris::free_cap (dir)
|
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
|
unsigned state = 0
|
||||||
while true:
|
while true:
|
||||||
Iris::wait ()
|
Iris::wait ()
|
||||||
Iris::Cap reply = Iris::get_reply ()
|
Iris::Cap reply = Iris::get_reply ()
|
||||||
Iris::Cap arg = Iris::get_arg ()
|
Iris::Cap arg = Iris::get_arg ()
|
||||||
|
//Iris::debug ("udc event, protected: %x\n", Iris::recv.protected_data.l)
|
||||||
switch Iris::recv.protected_data.l:
|
switch Iris::recv.protected_data.l:
|
||||||
case IRQ_UDC:
|
case 0:
|
||||||
udc.interrupt (state)
|
udc.interrupt (state)
|
||||||
Iris::register_interrupt (IRQ_UDC)
|
Iris::register_interrupt (IRQ_UDC)
|
||||||
break
|
break
|
||||||
@ -586,7 +580,7 @@ Iris::Num start ():
|
|||||||
udc.log (Iris::recv.data[0].l)
|
udc.log (Iris::recv.data[0].l)
|
||||||
break
|
break
|
||||||
case DIRECTORY:
|
case DIRECTORY:
|
||||||
//kdebug ("dir request\n")
|
//Iris::debug ("dir request %d\n", Iris::recv.data[0].l)
|
||||||
switch Iris::recv.data[0].l:
|
switch Iris::recv.data[0].l:
|
||||||
case Iris::Directory::GET_NAME:
|
case Iris::Directory::GET_NAME:
|
||||||
Iris::Cap name = Iris::my_receiver.create_capability (Iris::Num (NAME, Iris::recv.data[1].l))
|
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:
|
case Iris::Directory::UNLOCK_RO:
|
||||||
state = Iris::recv.data[0].l
|
state = Iris::recv.data[0].l
|
||||||
if Iris::recv.data[1].h != 0:
|
if Iris::recv.data[1].h != 0:
|
||||||
kdebug ("index out of supported range\n")
|
Iris::panic (0, "index out of supported range")
|
||||||
Iris::panic (0)
|
|
||||||
udc.send (Iris::recv.data[0].l, Iris::recv.data[1].l, reply, arg)
|
udc.send (Iris::recv.data[0].l, Iris::recv.data[1].l, reply, arg)
|
||||||
continue
|
continue
|
||||||
case Iris::Directory::GET_FILE_RO:
|
case Iris::Directory::GET_FILE_RO:
|
||||||
@ -623,7 +616,7 @@ Iris::Num start ():
|
|||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
case FILE:
|
case FILE:
|
||||||
//kdebug ("file request\n")
|
//Iris::debug ("file request %d\n", Iris::recv.data[0].l)
|
||||||
switch Iris::recv.data[0].l:
|
switch Iris::recv.data[0].l:
|
||||||
case Iris::Block::GET_BLOCK:
|
case Iris::Block::GET_BLOCK:
|
||||||
if Iris::recv.data[0].h != PAGE_SIZE << 16:
|
if Iris::recv.data[0].h != PAGE_SIZE << 16:
|
||||||
@ -639,7 +632,7 @@ Iris::Num start ():
|
|||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
case NAME:
|
case NAME:
|
||||||
//kdebug ("name request\n")
|
//Iris::debug ("name request %d\n", Iris::recv.data[0].l)
|
||||||
switch Iris::recv.data[0].l:
|
switch Iris::recv.data[0].l:
|
||||||
case Iris::String::GET_SIZE:
|
case Iris::String::GET_SIZE:
|
||||||
reply.invoke (16)
|
reply.invoke (16)
|
||||||
|
Loading…
Reference in New Issue
Block a user