mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-16 20:44:05 +02:00
console
This commit is contained in:
parent
dbeaddc0ca
commit
c4830dd4f5
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ uimage
|
||||
*.hh
|
||||
gpio
|
||||
lcd
|
||||
init
|
||||
boot-programs/charset.data
|
||||
|
2
Makefile
2
Makefile
@ -42,7 +42,7 @@ PYPP = /usr/bin/pypp
|
||||
%.o:%.cc Makefile Makefile.arch $(headers)
|
||||
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
%: boot-programs/init.o boot-programs/%.o
|
||||
%: boot-programs/crt0.o boot-programs/%.o
|
||||
$(LD) $(filter %.o,$^) -o $@
|
||||
#$(OBJCOPY) -S $(OBJCOPYFLAGS) $@
|
||||
|
||||
|
883
boot-programs/charset
Executable file
883
boot-programs/charset
Executable file
@ -0,0 +1,883 @@
|
||||
#!/usr/bin/env python
|
||||
data = """
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
.#.#..
|
||||
.#.#..
|
||||
.#.#..
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.#.#..
|
||||
#####.
|
||||
.#.#..
|
||||
#####.
|
||||
.#.#..
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
.####.
|
||||
#.#...
|
||||
.###..
|
||||
..#.#.
|
||||
####..
|
||||
..#...
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
.#....
|
||||
..#...
|
||||
...#..
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
.#....
|
||||
#.#...
|
||||
.#....
|
||||
#.#.#.
|
||||
#..#..
|
||||
.##.#.
|
||||
......
|
||||
......
|
||||
|
||||
...#..
|
||||
...#..
|
||||
..#...
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
....#.
|
||||
...#..
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
...#..
|
||||
....#.
|
||||
......
|
||||
|
||||
#.....
|
||||
.#....
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
.#....
|
||||
#.....
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
.#.#..
|
||||
#####.
|
||||
.#.#..
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
..#...
|
||||
..#...
|
||||
#####.
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
..#...
|
||||
..#...
|
||||
.#....
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
#####.
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
....#.
|
||||
...#..
|
||||
..#...
|
||||
.#....
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
#.#.#.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
..#...
|
||||
.##...
|
||||
..#...
|
||||
..#...
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
..##..
|
||||
.#....
|
||||
#####.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
..##..
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.#.#..
|
||||
#..#..
|
||||
#####.
|
||||
...#..
|
||||
...#..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#####.
|
||||
#.....
|
||||
####..
|
||||
....#.
|
||||
####..
|
||||
......
|
||||
......
|
||||
|
||||
...#..
|
||||
..#...
|
||||
.###..
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#####.
|
||||
....#.
|
||||
...#..
|
||||
...#..
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
.###..
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
..#...
|
||||
.#....
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
..#...
|
||||
......
|
||||
......
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
..#...
|
||||
......
|
||||
......
|
||||
..#...
|
||||
.#....
|
||||
......
|
||||
|
||||
......
|
||||
....#.
|
||||
..##..
|
||||
##....
|
||||
..##..
|
||||
....#.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
#####.
|
||||
......
|
||||
#####.
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#.....
|
||||
.##...
|
||||
...##.
|
||||
.##...
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
.###..
|
||||
#...#.
|
||||
#...#.
|
||||
...#..
|
||||
..#...
|
||||
......
|
||||
..#...
|
||||
......
|
||||
|
||||
......
|
||||
####..
|
||||
....#.
|
||||
.##.#.
|
||||
#.#.#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
.#.#..
|
||||
#...#.
|
||||
#####.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
###...
|
||||
#..#..
|
||||
####..
|
||||
#...#.
|
||||
#...#.
|
||||
####..
|
||||
......
|
||||
......
|
||||
|
||||
.###..
|
||||
#...#.
|
||||
#.....
|
||||
#.....
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
###...
|
||||
#..#..
|
||||
#...#.
|
||||
#...#.
|
||||
#..#..
|
||||
###...
|
||||
......
|
||||
......
|
||||
|
||||
#####.
|
||||
#.....
|
||||
###...
|
||||
#.....
|
||||
#.....
|
||||
#####.
|
||||
......
|
||||
......
|
||||
|
||||
#####.
|
||||
#.....
|
||||
#.....
|
||||
###...
|
||||
#.....
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
.###..
|
||||
#.....
|
||||
#.....
|
||||
#..##.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#...#.
|
||||
#####.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
.###..
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
..###.
|
||||
...#..
|
||||
...#..
|
||||
...#..
|
||||
#..#..
|
||||
.##...
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#..#..
|
||||
#.#...
|
||||
###...
|
||||
#..#..
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
#.....
|
||||
#.....
|
||||
#.....
|
||||
#.....
|
||||
#.....
|
||||
#####.
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
##.##.
|
||||
#.#.#.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
##..#.
|
||||
#.#.#.
|
||||
#..##.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
.###..
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
####..
|
||||
#...#.
|
||||
#...#.
|
||||
####..
|
||||
#.....
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
.###..
|
||||
#...#.
|
||||
#...#.
|
||||
#.#.#.
|
||||
#..#..
|
||||
.##.#.
|
||||
......
|
||||
......
|
||||
|
||||
####..
|
||||
#...#.
|
||||
#...#.
|
||||
####..
|
||||
#..#..
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
.####.
|
||||
#.....
|
||||
.###..
|
||||
....#.
|
||||
....#.
|
||||
####..
|
||||
......
|
||||
......
|
||||
|
||||
#####.
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#...#.
|
||||
.#.#..
|
||||
.#.#..
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#...#.
|
||||
#.#.#.
|
||||
#.#.#.
|
||||
.#.#..
|
||||
.#.#..
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
.#.#..
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
#...#.
|
||||
#...#.
|
||||
.#.#..
|
||||
..#...
|
||||
.#....
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
#####.
|
||||
...#..
|
||||
..#...
|
||||
.#....
|
||||
#.....
|
||||
#####.
|
||||
......
|
||||
......
|
||||
|
||||
..###.
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..###.
|
||||
......
|
||||
|
||||
......
|
||||
#.....
|
||||
.#....
|
||||
..#...
|
||||
...#..
|
||||
....#.
|
||||
......
|
||||
......
|
||||
|
||||
###...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
###...
|
||||
......
|
||||
|
||||
..#...
|
||||
.#.#..
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
#####.
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
..#...
|
||||
...#..
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.##.#.
|
||||
#..##.
|
||||
#...#.
|
||||
#..##.
|
||||
.##.#.
|
||||
......
|
||||
......
|
||||
|
||||
#.....
|
||||
#.....
|
||||
####..
|
||||
#...#.
|
||||
#...#.
|
||||
####..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
#.....
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
....#.
|
||||
....#.
|
||||
.####.
|
||||
#...#.
|
||||
#...#.
|
||||
.####.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
####..
|
||||
#.....
|
||||
.####.
|
||||
......
|
||||
......
|
||||
|
||||
...#..
|
||||
..#.#.
|
||||
..#...
|
||||
.###..
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.####.
|
||||
#...#.
|
||||
#...#.
|
||||
.####.
|
||||
....#.
|
||||
.###..
|
||||
......
|
||||
|
||||
#.....
|
||||
#.....
|
||||
####..
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
......
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
......
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
#.#...
|
||||
.#....
|
||||
......
|
||||
|
||||
#.....
|
||||
#..#..
|
||||
#.#...
|
||||
##....
|
||||
#.#...
|
||||
#..#..
|
||||
......
|
||||
......
|
||||
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.#.#..
|
||||
#.#.#.
|
||||
#.#.#.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#.##..
|
||||
##..#.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.###..
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
####..
|
||||
#...#.
|
||||
#...#.
|
||||
####..
|
||||
#.....
|
||||
#.....
|
||||
......
|
||||
|
||||
......
|
||||
.####.
|
||||
#...#.
|
||||
#...#.
|
||||
.####.
|
||||
....#.
|
||||
....#.
|
||||
......
|
||||
|
||||
......
|
||||
#.##..
|
||||
##..#.
|
||||
#.....
|
||||
#.....
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
.####.
|
||||
#.....
|
||||
.###..
|
||||
....#.
|
||||
####..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
..#...
|
||||
.###..
|
||||
..#...
|
||||
..#.#.
|
||||
...#..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
#...#.
|
||||
.###..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
#...#.
|
||||
.#.#..
|
||||
.#.#..
|
||||
..#...
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
#...#.
|
||||
#.#.#.
|
||||
#.#.#.
|
||||
.#.#..
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
.#.#..
|
||||
..#...
|
||||
.#.#..
|
||||
#...#.
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#...#.
|
||||
.#.#..
|
||||
..#...
|
||||
.#....
|
||||
#.....
|
||||
......
|
||||
......
|
||||
|
||||
......
|
||||
#####.
|
||||
...#..
|
||||
..#...
|
||||
.#....
|
||||
#####.
|
||||
......
|
||||
......
|
||||
|
||||
...##.
|
||||
..#...
|
||||
..#...
|
||||
##....
|
||||
..#...
|
||||
..#...
|
||||
...##.
|
||||
......
|
||||
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
..#...
|
||||
......
|
||||
|
||||
##....
|
||||
..#...
|
||||
..#...
|
||||
...##.
|
||||
..#...
|
||||
..#...
|
||||
##....
|
||||
......
|
||||
|
||||
......
|
||||
......
|
||||
.#....
|
||||
#.#.#.
|
||||
...#..
|
||||
......
|
||||
......
|
||||
......
|
||||
|
||||
#####.
|
||||
#...#.
|
||||
#.#.#.
|
||||
#.#.#.
|
||||
#.#.#.
|
||||
#...#.
|
||||
#####.
|
||||
......
|
||||
"""
|
||||
# """ # add quotes, because vim thinkt the qotes on the previous line start a string.
|
||||
|
||||
import sys
|
||||
|
||||
charsize = 7 * 8 + 1
|
||||
for c in range (128 - 32):
|
||||
line = []
|
||||
for l in range (8):
|
||||
offset = 1 + c * charsize + 7 * l
|
||||
line += [int (data[offset:offset + 6].replace ('.', '0').replace ('#', '1'), 2)]
|
||||
kols = []
|
||||
for k in range (5, -1, -1):
|
||||
d = 0
|
||||
for l in range (8):
|
||||
if line[l] & (1 << k):
|
||||
d += 1 << l
|
||||
sys.stdout.write (chr (d))
|
@ -20,6 +20,7 @@
|
||||
.globl __my_thread
|
||||
.globl __my_memory
|
||||
.globl __my_call
|
||||
.globl __my_parent
|
||||
.set noreorder
|
||||
|
||||
__start:
|
||||
@ -37,6 +38,8 @@ __hack_label:
|
||||
sw $a2, ($v0)
|
||||
la $v0, __my_call
|
||||
sw $a3, ($v0)
|
||||
la $v0, __my_parent
|
||||
sw $t0, ($v0)
|
||||
la $t9, main
|
||||
la $ra, 1f
|
||||
jr $t9
|
||||
@ -51,3 +54,4 @@ __hack_label:
|
||||
.comm __my_thread, 4
|
||||
.comm __my_memory, 4
|
||||
.comm __my_call, 4
|
||||
.comm __my_parent, 4
|
@ -19,8 +19,9 @@
|
||||
#ifndef __IRIS_DEVICES_HH
|
||||
#define __IRIS_DEVICES_HH
|
||||
|
||||
// lcd driver.
|
||||
#define LCD_BACKLIGHT 1
|
||||
#define LCD_RESET 2
|
||||
enum init_requests:
|
||||
INIT_SET_GPIO_0
|
||||
INIT_SET_GPIO_1
|
||||
INIT_SET_LCD
|
||||
|
||||
#endif
|
||||
|
@ -46,15 +46,56 @@
|
||||
// Battery presence and charge detection: 3.29 (note that this is also a keyboard column.)
|
||||
// interrupts: no; it would be possible, but setting these to input makes it impossible to detect certain key presses as interrupts.
|
||||
|
||||
// interrupt summary
|
||||
// Port 0: pin 0, 1, 2, 3, 4, 5, 6, 7: keyboard; 13, 16: touchpad
|
||||
// Port 1: None.
|
||||
// Port 2: None.
|
||||
// Port 3: None.
|
||||
|
||||
enum event_type:
|
||||
KEYBOARD_EVENT
|
||||
TOUCHPAD_EVENT
|
||||
POWERBUTTON_EVENT
|
||||
BATTERY_EVENT
|
||||
NUM_EVENTS
|
||||
|
||||
enum cap_type:
|
||||
CAP_KEYBOARD = 32
|
||||
CAP_TOUCHPAD
|
||||
CAP_POWEROFF
|
||||
CAP_POWERBUTTON
|
||||
CAP_BATTERY
|
||||
CAP_LOCKLEDS
|
||||
CAP_PWM
|
||||
|
||||
static Capability cbs[NUM_EVENTS]
|
||||
|
||||
static void event (event_type type, unsigned data):
|
||||
if !cbs[type]:
|
||||
return
|
||||
invoke_01 (cbs[type], data)
|
||||
|
||||
static void set_cb (event_type type, Capability cb):
|
||||
if cbs[type]:
|
||||
drop (cbs[type])
|
||||
cbs[type] = cb
|
||||
|
||||
enum battery_type:
|
||||
BATTERY_ABSENT
|
||||
BATTERY_CHARGING
|
||||
BATTERY_CHARGED
|
||||
|
||||
class Keyboard:
|
||||
enum { NUM_COLS = 17 }
|
||||
enum { COL_MASK = 0x2000ffff }
|
||||
enum { ROW_MASK = 0x000000ff }
|
||||
|
||||
unsigned keys[NUM_COLS]
|
||||
void event (bool release, unsigned row, unsigned col):
|
||||
bool scanning
|
||||
|
||||
public:
|
||||
bool is_scanning ():
|
||||
return scanning
|
||||
Keyboard ():
|
||||
// Set all columns to input and disable the pull-ups.
|
||||
GPIO_GPDIR (3) &= ~COL_MASK
|
||||
@ -66,6 +107,7 @@ class Keyboard:
|
||||
// Enable interrupts on falling edge.
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & 0xffff) | (GPIO_IRQ_FALLEDG * 0xaaaa)
|
||||
GPIO_GPIER (0) |= 0xff
|
||||
scanning = false
|
||||
|
||||
for unsigned i = 0; i < NUM_COLS; ++i:
|
||||
keys[i] = 0xff
|
||||
@ -81,31 +123,39 @@ class Keyboard:
|
||||
// Generate events.
|
||||
for unsigned row = 0; row < 8; ++row:
|
||||
if (data ^ keys[col]) & (1 << row):
|
||||
event (data & (1 << row), row, col)
|
||||
unsigned code = (row << 8) | col
|
||||
if data & (1 << row):
|
||||
code |= 0x10000
|
||||
event (KEYBOARD_EVENT, code)
|
||||
keys[col] = data
|
||||
if data != ROW_MASK:
|
||||
key_pressed = true
|
||||
if key_pressed:
|
||||
// TODO: schedule keyboard scan.
|
||||
scanning = true
|
||||
|
||||
class Touchpad:
|
||||
enum { LEFT = 1 << 16 }
|
||||
enum { RIGHT = 1 << 13 }
|
||||
unsigned old_state
|
||||
void event ():
|
||||
public:
|
||||
enum buttons:
|
||||
LEFT = 1 << 16
|
||||
RIGHT = 1 << 13
|
||||
void check_events ():
|
||||
unsigned state = GPIO_GPDR (0)
|
||||
if (state ^ old_state) & LEFT:
|
||||
if state & LEFT:
|
||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_FALLEDG << (2 * 0))
|
||||
event (TOUCHPAD_EVENT, 0)
|
||||
else:
|
||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_RAISEDG << (2 * 0))
|
||||
event (TOUCHPAD_EVENT, 0x10000)
|
||||
if (state ^ old_state) & RIGHT:
|
||||
if state & RIGHT:
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
||||
event (TOUCHPAD_EVENT, 1)
|
||||
else:
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_RAISEDG << (2 * 13))
|
||||
event (TOUCHPAD_EVENT, 0x10001)
|
||||
old_state = state
|
||||
public:
|
||||
Touchpad ():
|
||||
// Set pins to input with pull-ups.
|
||||
GPIO_GPDIR (0) &= ~(LEFT | RIGHT)
|
||||
@ -115,7 +165,7 @@ class Touchpad:
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
||||
old_state = 0
|
||||
// See if they are already pressed. If so, the interrupt detection is changed.
|
||||
event ()
|
||||
check_events ()
|
||||
// Now enable the interrupts.
|
||||
GPIO_GPIER (0) |= LEFT | RIGHT
|
||||
|
||||
@ -130,16 +180,16 @@ class Lockleds:
|
||||
GPIO_GPDR (0) &= ~(SCROLL | CAPS)
|
||||
GPIO_GPDIR (2) |= NUM
|
||||
GPIO_GPDIR (0) |= CAPS | SCROLL
|
||||
void set (bool num, bool caps, bool scroll):
|
||||
if num:
|
||||
void set (unsigned state):
|
||||
if state & 4:
|
||||
GPIO_GPDR (2) &= ~NUM
|
||||
else:
|
||||
GPIO_GPDR (2) |= NUM
|
||||
if caps:
|
||||
if state & 2:
|
||||
GPIO_GPDR (0) &= ~CAPS
|
||||
else:
|
||||
GPIO_GPDR (0) |= CAPS
|
||||
if scroll:
|
||||
if state & 1:
|
||||
GPIO_GPDR (0) &= ~SCROLL
|
||||
else:
|
||||
GPIO_GPDR (0) |= SCROLL
|
||||
@ -151,6 +201,7 @@ class Power:
|
||||
enum { BATTERY = 1 << 29 }
|
||||
unsigned old_state
|
||||
bool was_present
|
||||
public:
|
||||
void poll ():
|
||||
// Switch off keyboard interrupts, because this may interfere with them.
|
||||
GPIO_GPIER (0) &= ~0xff
|
||||
@ -159,25 +210,26 @@ class Power:
|
||||
udelay (100)
|
||||
unsigned state = GPIO_GPDR (3)
|
||||
if (state ^ old_state) & PWR_IN:
|
||||
// TODO: event
|
||||
event (POWERBUTTON_EVENT, state & PWR_IN ? 0 : 0x10000)
|
||||
if (state ^ old_state) & BATTERY:
|
||||
if !(state & BATTERY):
|
||||
GPIO_GPPUR (3) |= BATTERY
|
||||
udelay (100)
|
||||
if GPIO_GPDR (3) & BATTERY:
|
||||
if !was_present:
|
||||
// TODO: event
|
||||
event (BATTERY_EVENT, BATTERY_CHARGED)
|
||||
was_present = true
|
||||
else:
|
||||
if was_present:
|
||||
// TODO: event
|
||||
event (BATTERY_EVENT, BATTERY_ABSENT)
|
||||
was_present = false
|
||||
else:
|
||||
event (BATTERY_EVENT, BATTERY_CHARGING)
|
||||
old_state = state
|
||||
GPIO_GPPUR (3) &= ~BATTERY
|
||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||
udelay (100)
|
||||
GPIO_GPIER (3) |= 0xff
|
||||
public:
|
||||
Power ():
|
||||
GPIO_GPDR (2) |= PWR_OUT
|
||||
GPIO_GPDIR (2) |= PWR_OUT
|
||||
@ -186,23 +238,90 @@ class Power:
|
||||
poll ()
|
||||
void poweroff ():
|
||||
GPIO_GPDR (2) &= ~PWR_OUT
|
||||
GPIO_GPDIR (2) |= PWR_OUT
|
||||
while true:
|
||||
// Do nothing; wait until the device stops running.
|
||||
|
||||
// Not really a gpio device, but it's so small, and uses gpio, so I include it here to avoid ipc.
|
||||
class Pwm:
|
||||
// Pin definitions, all in port 2.
|
||||
enum { PWM_ENABLE = 1 << 30 }
|
||||
public:
|
||||
Pwm ():
|
||||
GPIO_GPDIR (2) |= PWM_ENABLE
|
||||
PWM_PER (0) = 300
|
||||
void set_backlight (bool state):
|
||||
if state:
|
||||
PWM_DUT (0) = 300
|
||||
PWM_CTR (0) = 0xbf
|
||||
GPIO_GPDR (2) |= PWM_ENABLE
|
||||
else:
|
||||
PWM_DUT (0) = 0
|
||||
PWM_CTR (0) = 0x3f
|
||||
GPIO_GPDR (2) &= ~PWM_ENABLE
|
||||
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
||||
|
||||
int main ():
|
||||
map_gpio ()
|
||||
map_pwm0 ()
|
||||
|
||||
Keyboard kbd
|
||||
Touchpad tp
|
||||
Lockleds leds
|
||||
//Lockleds leds
|
||||
Power power
|
||||
Pwm pwm
|
||||
|
||||
register_interrupt (IRQ_GPIO0)
|
||||
|
||||
Capability cap_kbd = receiver_create_capability (__my_receiver, CAP_KEYBOARD)
|
||||
Capability cap_tp = receiver_create_capability (__my_receiver, CAP_TOUCHPAD)
|
||||
Capability cap_poweroff = receiver_create_capability (__my_receiver, CAP_POWEROFF)
|
||||
Capability cap_powerbutton = receiver_create_capability (__my_receiver, CAP_POWERBUTTON)
|
||||
Capability cap_battery = receiver_create_capability (__my_receiver, CAP_BATTERY)
|
||||
Capability cap_lockleds = receiver_create_capability (__my_receiver, CAP_LOCKLEDS)
|
||||
Capability cap_pwm = receiver_create_capability (__my_receiver, CAP_PWM)
|
||||
|
||||
invoke_41 (__my_parent, cap_copy (cap_kbd), cap_copy (cap_tp), cap_copy (cap_poweroff), cap_copy (cap_powerbutton), INIT_SET_GPIO_0)
|
||||
invoke_31 (__my_parent, cap_copy (cap_battery), cap_copy (cap_lockleds), cap_copy (cap_pwm), INIT_SET_GPIO_1)
|
||||
|
||||
receiver_set_alarm (__my_receiver, HZ / 5)
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
switch msg.protected_data:
|
||||
case ~0:
|
||||
// Alarm.
|
||||
if kbd.is_scanning ():
|
||||
kbd.scan ()
|
||||
power.poll ()
|
||||
receiver_set_alarm (__my_receiver, HZ / 5)
|
||||
break
|
||||
case IRQ_GPIO0:
|
||||
case IRQ_GPIO1:
|
||||
case IRQ_GPIO2:
|
||||
case IRQ_GPIO3:
|
||||
// TODO
|
||||
unsigned irq = GPIO_GPFR (0)
|
||||
// Ack all. This works because they are all edge triggered.
|
||||
GPIO_GPFR (0) = irq
|
||||
if irq & 0xff:
|
||||
kbd.scan ()
|
||||
if irq & (Touchpad::LEFT | Touchpad::RIGHT):
|
||||
tp.check_events ()
|
||||
case CAP_KEYBOARD:
|
||||
set_cb (KEYBOARD_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_TOUCHPAD:
|
||||
set_cb (TOUCHPAD_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_POWEROFF:
|
||||
power.poweroff ()
|
||||
break
|
||||
case CAP_POWERBUTTON:
|
||||
set_cb (POWERBUTTON_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_BATTERY:
|
||||
set_cb (BATTERY_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_LOCKLEDS:
|
||||
//leds.set (msg.data[0])
|
||||
break
|
||||
case CAP_PWM:
|
||||
pwm.set_backlight (msg.data[0])
|
||||
break
|
||||
|
84
boot-programs/init.ccp
Normal file
84
boot-programs/init.ccp
Normal file
@ -0,0 +1,84 @@
|
||||
#pypp 0
|
||||
// Iris: micro-kernel for a capability-based operating system.
|
||||
// boot-programs/init.ccp: System boot manager.
|
||||
// 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/>.
|
||||
|
||||
#include "devices.hh"
|
||||
#include "iris.h"
|
||||
|
||||
static Capability kbd, tp, poweroff, powerbutton, battery, lockleds, pwm, lcd
|
||||
|
||||
enum type:
|
||||
KBD = 0x10000
|
||||
TP
|
||||
POWERBUTTON
|
||||
BATTERY
|
||||
|
||||
static void send (Capability c, unsigned d):
|
||||
Capability n = receiver_create_capability (__my_receiver, d)
|
||||
invoke_10 (c, cap_copy (n))
|
||||
drop (n)
|
||||
|
||||
static void setup ():
|
||||
unsigned state = 0
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
switch msg.data[0]:
|
||||
case INIT_SET_GPIO_0:
|
||||
kdebug (0, 2)
|
||||
kbd = msg.cap[0]
|
||||
tp = msg.cap[1]
|
||||
poweroff = msg.cap[2]
|
||||
powerbutton = msg.cap[3]
|
||||
++state
|
||||
break
|
||||
case INIT_SET_GPIO_1:
|
||||
kdebug (1, 2)
|
||||
battery = msg.cap[0]
|
||||
lockleds = msg.cap[1]
|
||||
pwm = msg.cap[2]
|
||||
++state
|
||||
break
|
||||
case INIT_SET_LCD:
|
||||
kdebug (2, 2)
|
||||
lcd = msg.cap[0]
|
||||
++state
|
||||
break
|
||||
if state == 3:
|
||||
break
|
||||
send (kbd, KBD)
|
||||
send (tp, TP)
|
||||
send (powerbutton, POWERBUTTON)
|
||||
send (battery, BATTERY)
|
||||
invoke_01 (pwm, 1)
|
||||
|
||||
int main ():
|
||||
setup ()
|
||||
kdebug (3, 2)
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
switch msg.protected_data:
|
||||
case KBD:
|
||||
invoke_01 (lockleds, 0x4 | (msg.data[0] >> 16))
|
||||
break
|
||||
case TP:
|
||||
invoke_01 (lockleds, 0x2 | (msg.data[0] >> 16))
|
||||
break
|
||||
case POWERBUTTON:
|
||||
case BATTERY:
|
||||
break
|
@ -20,30 +20,20 @@
|
||||
#define ARCH
|
||||
#include "arch.hh"
|
||||
|
||||
__asm__ volatile (".globl charset\ncharset:\n.incbin \"boot-programs/charset.data\"")
|
||||
// I'm too lazy to do this right. The address of charset is really the address of the array.
|
||||
extern unsigned charset
|
||||
|
||||
#define assert(x) do { while (!(x)) kdebug (0, 0); } while (0)
|
||||
|
||||
enum types:
|
||||
LCD_EOF_CB = 32
|
||||
|
||||
// For now, support only 16 bpp.
|
||||
// Screen is 800x480 tft.
|
||||
unsigned h = 800, v = 480, hs = 80, vs = 20, fps = 60, Bpp = 2
|
||||
#define frame_size (v * h * Bpp)
|
||||
|
||||
// Pin definitions, all in port 2.
|
||||
#define PWM_ENABLE (1 << 30)
|
||||
#define SPEN (1 << 0) //LCD_SPL
|
||||
#define SPCK (1 << 1) //LCD_CLS
|
||||
#define SPDA (1 << 2) //LCD_PS
|
||||
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
|
||||
|
||||
static void set_backlight (bool state):
|
||||
if state:
|
||||
PWM_DUT (0) = 300
|
||||
PWM_CTR (0) = 0xbf
|
||||
GPIO_GPDR (2) |= PWM_ENABLE
|
||||
else:
|
||||
PWM_DUT (0) = 0
|
||||
PWM_CTR (0) = 0x3f
|
||||
GPIO_GPDR (2) &= ~PWM_ENABLE
|
||||
|
||||
struct Descriptor:
|
||||
unsigned next
|
||||
unsigned frame
|
||||
@ -51,18 +41,6 @@ struct Descriptor:
|
||||
unsigned cmd
|
||||
|
||||
static void reset (unsigned physical_descriptor):
|
||||
PWM_PER (0) = 300
|
||||
set_backlight (true)
|
||||
|
||||
// initialize things.
|
||||
GPIO_GPIER (2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
|
||||
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET
|
||||
udelay (50)
|
||||
GPIO_GPDR (2) &= ~LCD_RET
|
||||
ddelay (2)
|
||||
GPIO_GPDR (2) |= LCD_RET
|
||||
ddelay (1)
|
||||
|
||||
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
|
||||
LCD_VSYNC = vs
|
||||
LCD_HSYNC = hs
|
||||
@ -92,6 +70,88 @@ static void reset (unsigned physical_descriptor):
|
||||
lcd_set_ena ()
|
||||
lcd_enable_eof_intr ()
|
||||
|
||||
static void putchar (unsigned x, unsigned y, unsigned utf8, unsigned fg = 0xffff, unsigned bg = 0x0000):
|
||||
if utf8 < 32 || utf8 > 126:
|
||||
utf8 = 127
|
||||
unsigned idx = utf8 - 32
|
||||
unsigned char *c = &((unsigned char *)&charset)[idx * 6]
|
||||
unsigned lookup[2] = { bg, fg }
|
||||
for unsigned k = 0; k < 6; ++k:
|
||||
for unsigned r = 0; r < 8; ++r:
|
||||
LCD_FRAMEBUFFER_BASE[(y * 8 + r) * 800 + x * 6 + k] = lookup[c[k] & (1 << r) ? 1 : 0]
|
||||
|
||||
static unsigned read_rest (unsigned num, char const *&utf8):
|
||||
unsigned ret = 0
|
||||
while num--:
|
||||
if (*utf8 & 0xc0) != 0x80:
|
||||
return ~0
|
||||
ret <<= 6
|
||||
ret |= (*utf8++) & 0x3f
|
||||
return ret
|
||||
|
||||
static unsigned read_utf8 (char const *&utf8):
|
||||
unsigned c = *utf8++
|
||||
if !(c & 0x80):
|
||||
return c
|
||||
if !(c & 0x40):
|
||||
// Invalid character.
|
||||
return 0
|
||||
if !(c & 0x20):
|
||||
// 2-byte character.
|
||||
c &= 0x1f
|
||||
c <<= 6
|
||||
c |= read_rest (1, utf8)
|
||||
else if !(c & 0x10):
|
||||
// 3-byte character.
|
||||
c &= 0xf
|
||||
c <<= 12
|
||||
c |= read_rest (2, utf8)
|
||||
else if !(c & 0x8):
|
||||
// 4-byte character.
|
||||
c &= 0x7
|
||||
c <<= 18
|
||||
c |= read_rest (3, utf8)
|
||||
else if !(c & 0x4):
|
||||
// 5-byte character.
|
||||
c &= 0x3
|
||||
c <<= 24
|
||||
c |= read_rest (4, utf8)
|
||||
else if !(c & 0x2):
|
||||
// 6-byte character.
|
||||
c &= 0x1
|
||||
c <<= 30
|
||||
c |= read_rest (5, utf8)
|
||||
else
|
||||
// Invalid character.
|
||||
return 0
|
||||
if c == ~0:
|
||||
return 0
|
||||
return c
|
||||
|
||||
static void putstr (unsigned x, unsigned y, char const *utf8):
|
||||
while *utf8:
|
||||
putchar (x++, y, read_utf8 (utf8))
|
||||
|
||||
static unsigned log_x = 1, log_y = 1
|
||||
static void inc_logx ():
|
||||
if ++log_x >= 800 / 6:
|
||||
log_x = 1
|
||||
if ++log_y >= 480 / 8:
|
||||
log_y = 1
|
||||
|
||||
static void log (char const *utf8):
|
||||
while *utf8:
|
||||
unsigned c = read_utf8 (utf8)
|
||||
switch c:
|
||||
case '\n':
|
||||
while log_x < 800 / 6:
|
||||
putchar (log_x++, log_y, ' ')
|
||||
inc_logx ()
|
||||
break
|
||||
default:
|
||||
putchar (log_x, log_y, c)
|
||||
inc_logx ()
|
||||
|
||||
int main ():
|
||||
// TODO: The descriptor takes an entire uncached page, because I don't know how to force a cache write-back. It's much better to do that instead.
|
||||
map_gpio ()
|
||||
@ -119,12 +179,8 @@ int main ():
|
||||
alloc_physical (page, physical + (i + CAPPAGE_SIZE) * PAGE_SIZE, 0, 1)
|
||||
memory_map (__my_memory, page, (unsigned)LCD_FRAMEBUFFER_BASE + (i + CAPPAGE_SIZE) * PAGE_SIZE, 1)
|
||||
drop (page)
|
||||
unsigned og = 0
|
||||
for unsigned y = 0; y < 480; ++y:
|
||||
unsigned g = (y << 6) / 480
|
||||
if g != og:
|
||||
og = g
|
||||
g = 0x3f
|
||||
unsigned olr = 0, ob = ((25 * y * y) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
|
||||
for unsigned x = 0; x < 800; ++x:
|
||||
unsigned r = (x << 5) / 800
|
||||
@ -139,6 +195,7 @@ int main ():
|
||||
ob = b
|
||||
b = 0x1f
|
||||
LCD_FRAMEBUFFER_BASE[y * 800 + x] = (r << 11) | (g << 5) | (b)
|
||||
log ("testing!\nIs dit een werkende console?\nLinks, rechts?\n")
|
||||
Descriptor *descriptor = (Descriptor *)((unsigned)LCD_FRAMEBUFFER_BASE + frame_size)
|
||||
unsigned physical_descriptor = physical + frame_size
|
||||
descriptor->next = physical_descriptor
|
||||
@ -147,7 +204,12 @@ int main ():
|
||||
descriptor->cmd = LCD_CMD_EOFINT | ((frame_size / 4) << LCD_CMD_LEN_BIT)
|
||||
reset (physical_descriptor)
|
||||
register_interrupt (IRQ_LCD)
|
||||
set_backlight (true)
|
||||
|
||||
Capability eof_cb = 0
|
||||
|
||||
Capability cap = receiver_create_capability (__my_receiver, LCD_EOF_CB)
|
||||
invoke_11 (__my_parent, cap, INIT_SET_LCD)
|
||||
drop (cap)
|
||||
|
||||
while true:
|
||||
Message msg
|
||||
@ -156,13 +218,11 @@ int main ():
|
||||
case IRQ_LCD:
|
||||
lcd_clr_eof ()
|
||||
register_interrupt (IRQ_LCD)
|
||||
// TODO: allow callback
|
||||
if eof_cb:
|
||||
invoke_00 (eof_cb)
|
||||
break
|
||||
#if 0
|
||||
case LCD_BACKLIGHT:
|
||||
set_backlight (msg.data[0])
|
||||
case LCD_EOF_CB:
|
||||
if eof_cb:
|
||||
drop (eof_cb)
|
||||
eof_cb = msg.cap[0]
|
||||
break
|
||||
case LCD_RESET:
|
||||
//reset (physical_descriptor)
|
||||
break
|
||||
#endif
|
||||
|
@ -127,9 +127,6 @@ bool Receiver::send_message (unsigned protected_data, Capability::Context *c):
|
||||
address_space->free_capability (msg->capabilities[j])
|
||||
address_space->free_message (this, msg)
|
||||
return false
|
||||
if tried_direct:
|
||||
Thread_arch_receive_fail (owner)
|
||||
owner->unwait ()
|
||||
return true
|
||||
|
||||
static Capability *reply
|
||||
@ -141,8 +138,6 @@ static void fill_cap (Capability *r, unsigned target, unsigned protected_data):
|
||||
ref = &((Receiver *)target)->capabilities
|
||||
else:
|
||||
ref = &((Object_base *)protected_data)->refs
|
||||
// alloc_capability needs a Memory, but it isn't used if return storage is given.
|
||||
ref = &((Object_base *)protected_data)->refs
|
||||
// alloc_capability needs a Memory, but it isn't used if return storage is given.
|
||||
top_memory.alloc_capability ((Receiver *)target, NULL, ref, protected_data, r)
|
||||
|
||||
|
130
iris.h
130
iris.h
@ -29,6 +29,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Number of clock interrupts per second.
|
||||
#define HZ 10
|
||||
|
||||
#define PAGE_BITS (12)
|
||||
#define PAGE_SIZE (1 << PAGE_BITS)
|
||||
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
||||
@ -135,6 +138,7 @@ extern Capability __my_receiver;
|
||||
extern Capability __my_thread;
|
||||
extern Capability __my_memory;
|
||||
extern Capability __my_call;
|
||||
extern Capability __my_parent;
|
||||
|
||||
Capability cap_copy (Capability src)
|
||||
{
|
||||
@ -169,23 +173,23 @@ static void invoke (Capability target, Message *msg)
|
||||
"\tsyscall"
|
||||
:
|
||||
: "m"(target), "m"(msg)
|
||||
: "v0", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
|
||||
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
|
||||
}
|
||||
|
||||
static void wait (Message *msg)
|
||||
{
|
||||
__asm__ volatile ("li $v0, 2\n"
|
||||
"\tsyscall\n"
|
||||
"\tlw $v0, %0\n"
|
||||
"\tsw $t0, 0($v0)\n"
|
||||
"\tsw $t1, 4($v0)\n"
|
||||
"\tsw $t2, 8($v0)\n"
|
||||
"\tsw $t3, 12($v0)\n"
|
||||
"\tsw $a0, 16($v0)\n"
|
||||
"\tsw $a1, 20($v0)\n"
|
||||
"\tsw $a2, 24($v0)\n"
|
||||
"\tsw $a3, 28($v0)\n"
|
||||
"\tsw $v1, 32($v0)"
|
||||
"\tlw $v1, %0\n"
|
||||
"\tsw $t0, 0($v1)\n"
|
||||
"\tsw $t1, 4($v1)\n"
|
||||
"\tsw $t2, 8($v1)\n"
|
||||
"\tsw $t3, 12($v1)\n"
|
||||
"\tsw $a0, 16($v1)\n"
|
||||
"\tsw $a1, 20($v1)\n"
|
||||
"\tsw $a2, 24($v1)\n"
|
||||
"\tsw $a3, 28($v1)\n"
|
||||
"\tsw $v0, 32($v1)"
|
||||
:
|
||||
: "m"(msg)
|
||||
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
|
||||
@ -205,21 +209,35 @@ static void call (Capability target, Message *msg)
|
||||
"\tlw $a2, 24($v1)\n"
|
||||
"\tlw $a3, 28($v1)\n"
|
||||
"\tsyscall\n"
|
||||
"\tlw $v0, %1\n"
|
||||
"\tsw $t0, 0($v0)\n"
|
||||
"\tsw $t1, 4($v0)\n"
|
||||
"\tsw $t2, 8($v0)\n"
|
||||
"\tsw $t3, 12($v0)\n"
|
||||
"\tsw $a0, 16($v0)\n"
|
||||
"\tsw $a1, 20($v0)\n"
|
||||
"\tsw $a2, 24($v0)\n"
|
||||
"\tsw $a3, 28($v0)\n"
|
||||
"\tsw $v1, 32($v0)"
|
||||
"\tlw $v1, %1\n"
|
||||
"\tsw $t0, 0($v1)\n"
|
||||
"\tsw $t1, 4($v1)\n"
|
||||
"\tsw $t2, 8($v1)\n"
|
||||
"\tsw $t3, 12($v1)\n"
|
||||
"\tsw $a0, 16($v1)\n"
|
||||
"\tsw $a1, 20($v1)\n"
|
||||
"\tsw $a2, 24($v1)\n"
|
||||
"\tsw $a3, 28($v1)\n"
|
||||
"\tsw $v0, 32($v1)"
|
||||
:
|
||||
: "m"(t), "m"(msg)
|
||||
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
|
||||
}
|
||||
|
||||
static void invoke_00 (Capability t)
|
||||
{
|
||||
Message msg;
|
||||
msg.data[0] = 0;
|
||||
msg.data[1] = 0;
|
||||
msg.data[2] = 0;
|
||||
msg.data[3] = 0;
|
||||
msg.cap[0] = 0;
|
||||
msg.cap[1] = 0;
|
||||
msg.cap[2] = 0;
|
||||
msg.cap[3] = 0;
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_01 (Capability t, unsigned d)
|
||||
{
|
||||
Message msg;
|
||||
@ -276,6 +294,20 @@ static void invoke_04 (Capability t, unsigned d0, unsigned d1, unsigned d2, unsi
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_10 (Capability t, Capability c)
|
||||
{
|
||||
Message msg;
|
||||
msg.cap[0] = c;
|
||||
msg.data[0] = 0;
|
||||
msg.data[1] = 0;
|
||||
msg.data[2] = 0;
|
||||
msg.data[3] = 0;
|
||||
msg.cap[1] = 0;
|
||||
msg.cap[2] = 0;
|
||||
msg.cap[3] = 0;
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_11 (Capability t, Capability c, unsigned d)
|
||||
{
|
||||
Message msg;
|
||||
@ -318,6 +350,62 @@ static void invoke_13 (Capability t, Capability c, unsigned d0, unsigned d1, uns
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_20 (Capability t, Capability c0, Capability c1)
|
||||
{
|
||||
Message msg;
|
||||
msg.cap[0] = c0;
|
||||
msg.cap[1] = c1;
|
||||
msg.data[0] = 0;
|
||||
msg.data[1] = 0;
|
||||
msg.data[2] = 0;
|
||||
msg.data[3] = 0;
|
||||
msg.cap[2] = 0;
|
||||
msg.cap[3] = 0;
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_21 (Capability t, Capability c0, Capability c1, unsigned d)
|
||||
{
|
||||
Message msg;
|
||||
msg.cap[0] = c0;
|
||||
msg.cap[1] = c1;
|
||||
msg.data[0] = d;
|
||||
msg.data[1] = 0;
|
||||
msg.data[2] = 0;
|
||||
msg.data[3] = 0;
|
||||
msg.cap[2] = 0;
|
||||
msg.cap[3] = 0;
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_31 (Capability t, Capability c0, Capability c1, Capability c2, unsigned d)
|
||||
{
|
||||
Message msg;
|
||||
msg.cap[0] = c0;
|
||||
msg.cap[1] = c1;
|
||||
msg.cap[2] = c2;
|
||||
msg.data[0] = d;
|
||||
msg.data[1] = 0;
|
||||
msg.data[2] = 0;
|
||||
msg.data[3] = 0;
|
||||
msg.cap[3] = 0;
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static void invoke_41 (Capability t, Capability c0, Capability c1, Capability c2, Capability c3, unsigned d)
|
||||
{
|
||||
Message msg;
|
||||
msg.cap[0] = c0;
|
||||
msg.cap[1] = c1;
|
||||
msg.cap[2] = c2;
|
||||
msg.cap[3] = c3;
|
||||
msg.data[0] = d;
|
||||
msg.data[1] = 0;
|
||||
msg.data[2] = 0;
|
||||
msg.data[3] = 0;
|
||||
invoke (t, &msg);
|
||||
}
|
||||
|
||||
static Capability call_c01 (Capability c, unsigned d)
|
||||
{
|
||||
Message msg;
|
||||
|
@ -19,9 +19,6 @@
|
||||
#ifndef _KERNEL_HH
|
||||
#define _KERNEL_HH
|
||||
|
||||
// Number of clock interrupts per second.
|
||||
#define HZ 10
|
||||
|
||||
// Include definitions which are shared with user space.
|
||||
#define __KERNEL
|
||||
#include "iris.h"
|
||||
@ -205,7 +202,6 @@ void phys_free (unsigned page, unsigned num)
|
||||
// Defined by architecture-specific files.
|
||||
void Thread_arch_init (Thread *thread)
|
||||
void Thread_arch_receive (Thread *thread, unsigned protected_data, Capability::Context *c)
|
||||
void Thread_arch_receive_fail (Thread *thread)
|
||||
unsigned *Thread_arch_info (Thread *thread, unsigned num)
|
||||
void Memory_arch_init (Memory *mem)
|
||||
void Memory_arch_free (Memory *mem)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
load = 0x80000000
|
||||
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=1
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
||||
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
||||
CROSS = mipsel-linux-gnu-
|
||||
OBJDUMP = $(CROSS)objdump
|
||||
@ -26,9 +26,8 @@ OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
||||
|
||||
arch_kernel_sources = mips/interrupts.cc mips/test.cc mips/arch.cc
|
||||
boot_sources = mips/init.cc
|
||||
BUILT_SOURCES = $(kernel_sources) $(boot_sources)
|
||||
arch_headers = mips/arch.hh mips/jz4730.hh
|
||||
boot_threads = gpio lcd
|
||||
boot_threads = init gpio lcd
|
||||
|
||||
uimage:
|
||||
|
||||
@ -36,6 +35,10 @@ mips/entry.o: $(boot_threads)
|
||||
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||
$(boot_threads): TARGET_FLAGS = -I.
|
||||
$(boot_threads): boot-programs/devices.hh
|
||||
lcd: boot-programs/charset.data
|
||||
|
||||
boot-programs/charset.data: boot-programs/charset
|
||||
$< > $@
|
||||
|
||||
# Transform ':' into ';' so vim doesn't think there are errors.
|
||||
uimage: kernel.raw.gz Makefile mips/Makefile.arch
|
||||
@ -54,4 +57,4 @@ kernel: mips/entry.o $(subst .cc,.o,$(kernel_sources)) mips/boot.o $(subst .cc,.
|
||||
%.gz: %
|
||||
gzip < $< > $@
|
||||
|
||||
ARCH_CLEAN_FILES = uimage kernel kernel.raw kernel.raw.gz $(boot_threads) mips/*.o
|
||||
ARCH_CLEAN_FILES = uimage kernel kernel.raw kernel.raw.gz $(boot_threads) mips/*.o boot-programs/charset.data
|
||||
|
@ -54,11 +54,7 @@ void Thread_arch_receive (Thread *thread, unsigned protected_data, Capability::C
|
||||
thread->arch.t1 = c->data[1]
|
||||
thread->arch.t2 = c->data[2]
|
||||
thread->arch.t3 = c->data[3]
|
||||
thread->arch.v1 = protected_data
|
||||
thread->arch.v0 = 1
|
||||
|
||||
void Thread_arch_receive_fail (Thread *thread):
|
||||
thread->arch.v0 = 0
|
||||
thread->arch.v0 = protected_data
|
||||
|
||||
unsigned *Thread_arch_info (Thread *thread, unsigned num):
|
||||
switch num:
|
||||
|
10
mips/boot.S
10
mips/boot.S
@ -38,7 +38,14 @@ start_hack_for_disassembler:
|
||||
|
||||
la $sp, kernel_stack + KERNEL_STACK_SIZE
|
||||
|
||||
// TODO: flush cache and optionally refill it.
|
||||
// Flush cache.
|
||||
lui $v1, 0x8000
|
||||
ori $v0, $v1, 0x8000
|
||||
1:
|
||||
cache 0, 0($v1)
|
||||
cache 1, 0($v1)
|
||||
bne $v1, $v0, 1b
|
||||
addiu $v1, $v1, 32
|
||||
|
||||
// Set kseg0 cachable.
|
||||
li $k0, 0x3
|
||||
@ -67,3 +74,4 @@ thread_start:
|
||||
.word thread0
|
||||
.word thread1
|
||||
.word thread2
|
||||
.word thread3
|
||||
|
@ -231,10 +231,14 @@ save_regs:
|
||||
.globl thread0
|
||||
.globl thread1
|
||||
.globl thread2
|
||||
.globl thread3
|
||||
.balign 0x1000
|
||||
thread0:
|
||||
.incbin "lcd"
|
||||
.incbin "init"
|
||||
.balign 0x1000
|
||||
thread1:
|
||||
.incbin "gpio"
|
||||
.incbin "lcd"
|
||||
.balign 0x1000
|
||||
thread2:
|
||||
.incbin "gpio"
|
||||
thread3:
|
||||
|
@ -141,6 +141,8 @@ static void init_threads ():
|
||||
//bool executable = shdr->sh_flags & SHF_EXEC_INSTR
|
||||
if shdr->sh_type != SHT_NOBITS:
|
||||
unsigned file_offset = shdr->sh_offset >> PAGE_BITS
|
||||
if ((file_offset + shdr->sh_size) >> PAGE_BITS) >= (PAGE_SIZE >> 2):
|
||||
panic (0x87446809, "initial thread too large")
|
||||
for unsigned p = (shdr->sh_addr & PAGE_MASK); p < shdr->sh_addr + shdr->sh_size; p += PAGE_SIZE:
|
||||
unsigned section_offset = (p - (shdr->sh_addr & PAGE_MASK)) >> PAGE_BITS
|
||||
unsigned idx = file_offset + section_offset
|
||||
@ -238,11 +240,9 @@ void init (unsigned mem):
|
||||
// Set up initial threads.
|
||||
init_threads ()
|
||||
|
||||
// Disable all gpio pins initially.
|
||||
// Disable all gpio interrupts and alternate functions initially.
|
||||
for unsigned i = 0; i < 4; ++i:
|
||||
GPIO_GPIER (i) = 0
|
||||
GPIO_GPDIR (i) = 0
|
||||
GPIO_GPPUR (i) = 0
|
||||
GPIO_GPALR (i) = 0
|
||||
GPIO_GPAUR (i) = 0
|
||||
// Set up the rest of the hardware (copied from Linux).
|
||||
|
@ -19,6 +19,11 @@
|
||||
#define ARCH
|
||||
#include "../kernel.hh"
|
||||
|
||||
typedef unsigned cacheline[8]
|
||||
void arch_flush_cache ():
|
||||
for cacheline *line = (cacheline *)0x80000000; line < (cacheline *)0x80008000; ++line:
|
||||
__asm__ volatile ("lw $k0, %0; cache 0, 0($k0); cache 1, 0($k0)" :: "m"(line))
|
||||
|
||||
static void handle_exit (Thread *old_current):
|
||||
if !current || (current == &idle):
|
||||
schedule ()
|
||||
@ -26,6 +31,7 @@ static void handle_exit (Thread *old_current):
|
||||
current = &idle
|
||||
if old_current == current:
|
||||
return
|
||||
arch_flush_cache ()
|
||||
if current != &idle:
|
||||
if (Memory *)asids[current->address_space->arch.asid] != current->address_space:
|
||||
if asids[0]:
|
||||
@ -146,40 +152,48 @@ Thread *exception ():
|
||||
switch (cause >> 2) & 0x1f:
|
||||
case 0:
|
||||
// Interrupt. This shouldn't happen, since CAUSE[IV] == 1.
|
||||
panic (0x11223344, "Interrupt on exception vector.")
|
||||
panic (0x01223344, "Interrupt on exception vector.")
|
||||
case 1:
|
||||
// TLB modification.
|
||||
panic (0x21223344, "TLB modification.")
|
||||
panic (0x11223344, "TLB modification.")
|
||||
case 2:
|
||||
// TLB load or instruction fetch.
|
||||
unsigned a
|
||||
cp0_get (CP0_EPC, a)
|
||||
dbg_send (a)
|
||||
panic (0x31223344, "TLB load or instruction fetch.")
|
||||
panic (0x21223344, "TLB load or instruction fetch.")
|
||||
case 3:
|
||||
// TLB store.
|
||||
unsigned a
|
||||
cp0_get (CP0_EPC, a)
|
||||
dbg_send (a)
|
||||
panic (0x41223344, "TLB store.")
|
||||
cp0_get (CP0_BAD_V_ADDR, a)
|
||||
dbg_send (a)
|
||||
panic (0x31223344, "TLB store.")
|
||||
case 4:
|
||||
// Address error load or instruction fetch.
|
||||
unsigned a
|
||||
cp0_get (CP0_EPC, a)
|
||||
dbg_send (a)
|
||||
panic (0x51223344, "Address error load or instruction fetch.")
|
||||
cp0_get (CP0_BAD_V_ADDR, a)
|
||||
dbg_send (a)
|
||||
panic (0x41223344, "Address error load or instruction fetch.")
|
||||
case 5:
|
||||
// Address error store.
|
||||
dbg_send (current->arch.v1, 4)
|
||||
unsigned a
|
||||
cp0_get (CP0_EPC, a)
|
||||
dbg_send (*(unsigned *)(a & ~3), 32)
|
||||
dbg_send (a, 32)
|
||||
cp0_get (CP0_BAD_V_ADDR, a)
|
||||
dbg_send (a, 32)
|
||||
panic (0x61223344, "Address error store.")
|
||||
panic (0x51223344, "Address error store.")
|
||||
case 6:
|
||||
// Bus error instruction fetch.
|
||||
panic (0x71223344, "Bus error instruction fetch.")
|
||||
panic (0x61223344, "Bus error instruction fetch.")
|
||||
case 7:
|
||||
// Bus error load or store.
|
||||
panic (0x81223344, "Bus error load or store.")
|
||||
panic (0x71223344, "Bus error load or store.")
|
||||
case 8:
|
||||
// Syscall.
|
||||
current->pc += 4
|
||||
@ -202,13 +216,13 @@ Thread *exception ():
|
||||
panic (0xc1223344, "Arithmetic overflow.")
|
||||
case 13:
|
||||
// Trap.
|
||||
panic (0xe1223344, "Trap.")
|
||||
panic (0xd1223344, "Trap.")
|
||||
case 15:
|
||||
// Floating point exception.
|
||||
panic (0xf1223344, "Floating point exception.")
|
||||
panic (0xe1223344, "Floating point exception.")
|
||||
case 23:
|
||||
// Reference to WatchHi/WatchLo address.
|
||||
panic (0xf2223344, "Reference to WatchHi/WatchLo address.")
|
||||
panic (0xf1223344, "Reference to WatchHi/WatchLo address.")
|
||||
case 24:
|
||||
// Machine check.
|
||||
panic (0xf3223344, "Machine check.")
|
||||
|
@ -92,13 +92,8 @@ void schedule ():
|
||||
current = &idle
|
||||
|
||||
void timer_interrupt ():
|
||||
//panic (0x88877744, "Timer interrupt")
|
||||
Receiver *recv, *next
|
||||
for recv = first_alarm; recv; recv = next:
|
||||
next = recv->next
|
||||
alarm_tick (recv)
|
||||
schedule ()
|
||||
//#ifndef NDEBUG
|
||||
//static bool ledstate = false
|
||||
//dbg_led (false, false, ledstate = !ledstate)
|
||||
//#endif
|
||||
//schedule ()
|
||||
|
Loading…
Reference in New Issue
Block a user