1
0
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:
Bas Wijnen 2012-09-26 19:03:36 +02:00
parent 538b9b9361
commit d9a12225eb
38 changed files with 815 additions and 336 deletions

View File

@ -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
View 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

View File

@ -1 +0,0 @@
mips/Makefile.arch

10
configure.ac Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
courier.xcf Normal file

Binary file not shown.

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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
View 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])]))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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-

View File

@ -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):

View File

@ -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 )

View File

@ -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:

View File

@ -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.

View File

@ -2,7 +2,7 @@ OUTPUT_ARCH(mips)
ENTRY(__start)
MEMORY
{
ram : ORIGIN = 0x80002000 , LENGTH = 0x2000
ram : ORIGIN = 0x80003000 , LENGTH = 0x800
}
SECTIONS

View File

@ -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):

View File

@ -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

View File

@ -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
View 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

View File

@ -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 (&current_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")

View File

@ -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
View 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

View File

@ -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 ")

View File

@ -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)

View File

@ -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 ()

View File

@ -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

View File

@ -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)

View File

@ -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 ()

View File

@ -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)