mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-01-30 19:01: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
|
*.hh
|
||||||
gpio
|
gpio
|
||||||
lcd
|
lcd
|
||||||
|
init
|
||||||
|
boot-programs/charset.data
|
||||||
|
2
Makefile
2
Makefile
@ -42,7 +42,7 @@ PYPP = /usr/bin/pypp
|
|||||||
%.o:%.cc Makefile Makefile.arch $(headers)
|
%.o:%.cc Makefile Makefile.arch $(headers)
|
||||||
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
$(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 $@
|
$(LD) $(filter %.o,$^) -o $@
|
||||||
#$(OBJCOPY) -S $(OBJCOPYFLAGS) $@
|
#$(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_thread
|
||||||
.globl __my_memory
|
.globl __my_memory
|
||||||
.globl __my_call
|
.globl __my_call
|
||||||
|
.globl __my_parent
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
__start:
|
__start:
|
||||||
@ -37,6 +38,8 @@ __hack_label:
|
|||||||
sw $a2, ($v0)
|
sw $a2, ($v0)
|
||||||
la $v0, __my_call
|
la $v0, __my_call
|
||||||
sw $a3, ($v0)
|
sw $a3, ($v0)
|
||||||
|
la $v0, __my_parent
|
||||||
|
sw $t0, ($v0)
|
||||||
la $t9, main
|
la $t9, main
|
||||||
la $ra, 1f
|
la $ra, 1f
|
||||||
jr $t9
|
jr $t9
|
||||||
@ -51,3 +54,4 @@ __hack_label:
|
|||||||
.comm __my_thread, 4
|
.comm __my_thread, 4
|
||||||
.comm __my_memory, 4
|
.comm __my_memory, 4
|
||||||
.comm __my_call, 4
|
.comm __my_call, 4
|
||||||
|
.comm __my_parent, 4
|
@ -19,8 +19,9 @@
|
|||||||
#ifndef __IRIS_DEVICES_HH
|
#ifndef __IRIS_DEVICES_HH
|
||||||
#define __IRIS_DEVICES_HH
|
#define __IRIS_DEVICES_HH
|
||||||
|
|
||||||
// lcd driver.
|
enum init_requests:
|
||||||
#define LCD_BACKLIGHT 1
|
INIT_SET_GPIO_0
|
||||||
#define LCD_RESET 2
|
INIT_SET_GPIO_1
|
||||||
|
INIT_SET_LCD
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,15 +46,56 @@
|
|||||||
// Battery presence and charge detection: 3.29 (note that this is also a keyboard column.)
|
// 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.
|
// 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:
|
class Keyboard:
|
||||||
enum { NUM_COLS = 17 }
|
enum { NUM_COLS = 17 }
|
||||||
enum { COL_MASK = 0x2000ffff }
|
enum { COL_MASK = 0x2000ffff }
|
||||||
enum { ROW_MASK = 0x000000ff }
|
enum { ROW_MASK = 0x000000ff }
|
||||||
|
|
||||||
unsigned keys[NUM_COLS]
|
unsigned keys[NUM_COLS]
|
||||||
void event (bool release, unsigned row, unsigned col):
|
bool scanning
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool is_scanning ():
|
||||||
|
return scanning
|
||||||
Keyboard ():
|
Keyboard ():
|
||||||
// Set all columns to input and disable the pull-ups.
|
// Set all columns to input and disable the pull-ups.
|
||||||
GPIO_GPDIR (3) &= ~COL_MASK
|
GPIO_GPDIR (3) &= ~COL_MASK
|
||||||
@ -66,6 +107,7 @@ class Keyboard:
|
|||||||
// Enable interrupts on falling edge.
|
// Enable interrupts on falling edge.
|
||||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & 0xffff) | (GPIO_IRQ_FALLEDG * 0xaaaa)
|
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & 0xffff) | (GPIO_IRQ_FALLEDG * 0xaaaa)
|
||||||
GPIO_GPIER (0) |= 0xff
|
GPIO_GPIER (0) |= 0xff
|
||||||
|
scanning = false
|
||||||
|
|
||||||
for unsigned i = 0; i < NUM_COLS; ++i:
|
for unsigned i = 0; i < NUM_COLS; ++i:
|
||||||
keys[i] = 0xff
|
keys[i] = 0xff
|
||||||
@ -81,31 +123,39 @@ class Keyboard:
|
|||||||
// Generate events.
|
// Generate events.
|
||||||
for unsigned row = 0; row < 8; ++row:
|
for unsigned row = 0; row < 8; ++row:
|
||||||
if (data ^ keys[col]) & (1 << 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
|
keys[col] = data
|
||||||
if data != ROW_MASK:
|
if data != ROW_MASK:
|
||||||
key_pressed = true
|
key_pressed = true
|
||||||
if key_pressed:
|
if key_pressed:
|
||||||
// TODO: schedule keyboard scan.
|
scanning = true
|
||||||
|
|
||||||
class Touchpad:
|
class Touchpad:
|
||||||
enum { LEFT = 1 << 16 }
|
|
||||||
enum { RIGHT = 1 << 13 }
|
|
||||||
unsigned old_state
|
unsigned old_state
|
||||||
void event ():
|
public:
|
||||||
|
enum buttons:
|
||||||
|
LEFT = 1 << 16
|
||||||
|
RIGHT = 1 << 13
|
||||||
|
void check_events ():
|
||||||
unsigned state = GPIO_GPDR (0)
|
unsigned state = GPIO_GPDR (0)
|
||||||
if (state ^ old_state) & LEFT:
|
if (state ^ old_state) & LEFT:
|
||||||
if state & LEFT:
|
if state & LEFT:
|
||||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_FALLEDG << (2 * 0))
|
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_FALLEDG << (2 * 0))
|
||||||
|
event (TOUCHPAD_EVENT, 0)
|
||||||
else:
|
else:
|
||||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_RAISEDG << (2 * 0))
|
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 ^ old_state) & RIGHT:
|
||||||
if state & RIGHT:
|
if state & RIGHT:
|
||||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
||||||
|
event (TOUCHPAD_EVENT, 1)
|
||||||
else:
|
else:
|
||||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_RAISEDG << (2 * 13))
|
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_RAISEDG << (2 * 13))
|
||||||
|
event (TOUCHPAD_EVENT, 0x10001)
|
||||||
old_state = state
|
old_state = state
|
||||||
public:
|
|
||||||
Touchpad ():
|
Touchpad ():
|
||||||
// Set pins to input with pull-ups.
|
// Set pins to input with pull-ups.
|
||||||
GPIO_GPDIR (0) &= ~(LEFT | RIGHT)
|
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))
|
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
||||||
old_state = 0
|
old_state = 0
|
||||||
// See if they are already pressed. If so, the interrupt detection is changed.
|
// See if they are already pressed. If so, the interrupt detection is changed.
|
||||||
event ()
|
check_events ()
|
||||||
// Now enable the interrupts.
|
// Now enable the interrupts.
|
||||||
GPIO_GPIER (0) |= LEFT | RIGHT
|
GPIO_GPIER (0) |= LEFT | RIGHT
|
||||||
|
|
||||||
@ -130,16 +180,16 @@ class Lockleds:
|
|||||||
GPIO_GPDR (0) &= ~(SCROLL | CAPS)
|
GPIO_GPDR (0) &= ~(SCROLL | CAPS)
|
||||||
GPIO_GPDIR (2) |= NUM
|
GPIO_GPDIR (2) |= NUM
|
||||||
GPIO_GPDIR (0) |= CAPS | SCROLL
|
GPIO_GPDIR (0) |= CAPS | SCROLL
|
||||||
void set (bool num, bool caps, bool scroll):
|
void set (unsigned state):
|
||||||
if num:
|
if state & 4:
|
||||||
GPIO_GPDR (2) &= ~NUM
|
GPIO_GPDR (2) &= ~NUM
|
||||||
else:
|
else:
|
||||||
GPIO_GPDR (2) |= NUM
|
GPIO_GPDR (2) |= NUM
|
||||||
if caps:
|
if state & 2:
|
||||||
GPIO_GPDR (0) &= ~CAPS
|
GPIO_GPDR (0) &= ~CAPS
|
||||||
else:
|
else:
|
||||||
GPIO_GPDR (0) |= CAPS
|
GPIO_GPDR (0) |= CAPS
|
||||||
if scroll:
|
if state & 1:
|
||||||
GPIO_GPDR (0) &= ~SCROLL
|
GPIO_GPDR (0) &= ~SCROLL
|
||||||
else:
|
else:
|
||||||
GPIO_GPDR (0) |= SCROLL
|
GPIO_GPDR (0) |= SCROLL
|
||||||
@ -151,6 +201,7 @@ class Power:
|
|||||||
enum { BATTERY = 1 << 29 }
|
enum { BATTERY = 1 << 29 }
|
||||||
unsigned old_state
|
unsigned old_state
|
||||||
bool was_present
|
bool was_present
|
||||||
|
public:
|
||||||
void poll ():
|
void poll ():
|
||||||
// Switch off keyboard interrupts, because this may interfere with them.
|
// Switch off keyboard interrupts, because this may interfere with them.
|
||||||
GPIO_GPIER (0) &= ~0xff
|
GPIO_GPIER (0) &= ~0xff
|
||||||
@ -159,25 +210,26 @@ class Power:
|
|||||||
udelay (100)
|
udelay (100)
|
||||||
unsigned state = GPIO_GPDR (3)
|
unsigned state = GPIO_GPDR (3)
|
||||||
if (state ^ old_state) & PWR_IN:
|
if (state ^ old_state) & PWR_IN:
|
||||||
// TODO: event
|
event (POWERBUTTON_EVENT, state & PWR_IN ? 0 : 0x10000)
|
||||||
if (state ^ old_state) & BATTERY:
|
if (state ^ old_state) & BATTERY:
|
||||||
if !(state & BATTERY):
|
if !(state & BATTERY):
|
||||||
GPIO_GPPUR (3) |= BATTERY
|
GPIO_GPPUR (3) |= BATTERY
|
||||||
udelay (100)
|
udelay (100)
|
||||||
if GPIO_GPDR (3) & BATTERY:
|
if GPIO_GPDR (3) & BATTERY:
|
||||||
if !was_present:
|
if !was_present:
|
||||||
// TODO: event
|
event (BATTERY_EVENT, BATTERY_CHARGED)
|
||||||
was_present = true
|
was_present = true
|
||||||
else:
|
else:
|
||||||
if was_present:
|
if was_present:
|
||||||
// TODO: event
|
event (BATTERY_EVENT, BATTERY_ABSENT)
|
||||||
was_present = false
|
was_present = false
|
||||||
|
else:
|
||||||
|
event (BATTERY_EVENT, BATTERY_CHARGING)
|
||||||
old_state = state
|
old_state = state
|
||||||
GPIO_GPPUR (3) &= ~BATTERY
|
GPIO_GPPUR (3) &= ~BATTERY
|
||||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||||
udelay (100)
|
udelay (100)
|
||||||
GPIO_GPIER (3) |= 0xff
|
GPIO_GPIER (3) |= 0xff
|
||||||
public:
|
|
||||||
Power ():
|
Power ():
|
||||||
GPIO_GPDR (2) |= PWR_OUT
|
GPIO_GPDR (2) |= PWR_OUT
|
||||||
GPIO_GPDIR (2) |= PWR_OUT
|
GPIO_GPDIR (2) |= PWR_OUT
|
||||||
@ -186,23 +238,90 @@ class Power:
|
|||||||
poll ()
|
poll ()
|
||||||
void poweroff ():
|
void poweroff ():
|
||||||
GPIO_GPDR (2) &= ~PWR_OUT
|
GPIO_GPDR (2) &= ~PWR_OUT
|
||||||
|
GPIO_GPDIR (2) |= PWR_OUT
|
||||||
while true:
|
while true:
|
||||||
// Do nothing; wait until the device stops running.
|
// 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 ():
|
int main ():
|
||||||
map_gpio ()
|
map_gpio ()
|
||||||
|
map_pwm0 ()
|
||||||
|
|
||||||
Keyboard kbd
|
Keyboard kbd
|
||||||
Touchpad tp
|
Touchpad tp
|
||||||
Lockleds leds
|
//Lockleds leds
|
||||||
Power power
|
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:
|
while true:
|
||||||
Message msg
|
Message msg
|
||||||
wait (&msg)
|
wait (&msg)
|
||||||
switch msg.protected_data:
|
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_GPIO0:
|
||||||
case IRQ_GPIO1:
|
unsigned irq = GPIO_GPFR (0)
|
||||||
case IRQ_GPIO2:
|
// Ack all. This works because they are all edge triggered.
|
||||||
case IRQ_GPIO3:
|
GPIO_GPFR (0) = irq
|
||||||
// TODO
|
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
|
#define ARCH
|
||||||
#include "arch.hh"
|
#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)
|
#define assert(x) do { while (!(x)) kdebug (0, 0); } while (0)
|
||||||
|
|
||||||
|
enum types:
|
||||||
|
LCD_EOF_CB = 32
|
||||||
|
|
||||||
// For now, support only 16 bpp.
|
// For now, support only 16 bpp.
|
||||||
// Screen is 800x480 tft.
|
// Screen is 800x480 tft.
|
||||||
unsigned h = 800, v = 480, hs = 80, vs = 20, fps = 60, Bpp = 2
|
unsigned h = 800, v = 480, hs = 80, vs = 20, fps = 60, Bpp = 2
|
||||||
#define frame_size (v * h * Bpp)
|
#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:
|
struct Descriptor:
|
||||||
unsigned next
|
unsigned next
|
||||||
unsigned frame
|
unsigned frame
|
||||||
@ -51,18 +41,6 @@ struct Descriptor:
|
|||||||
unsigned cmd
|
unsigned cmd
|
||||||
|
|
||||||
static void reset (unsigned physical_descriptor):
|
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_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
|
||||||
LCD_VSYNC = vs
|
LCD_VSYNC = vs
|
||||||
LCD_HSYNC = hs
|
LCD_HSYNC = hs
|
||||||
@ -92,6 +70,88 @@ static void reset (unsigned physical_descriptor):
|
|||||||
lcd_set_ena ()
|
lcd_set_ena ()
|
||||||
lcd_enable_eof_intr ()
|
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 ():
|
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.
|
// 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 ()
|
map_gpio ()
|
||||||
@ -119,12 +179,8 @@ int main ():
|
|||||||
alloc_physical (page, physical + (i + CAPPAGE_SIZE) * PAGE_SIZE, 0, 1)
|
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)
|
memory_map (__my_memory, page, (unsigned)LCD_FRAMEBUFFER_BASE + (i + CAPPAGE_SIZE) * PAGE_SIZE, 1)
|
||||||
drop (page)
|
drop (page)
|
||||||
unsigned og = 0
|
|
||||||
for unsigned y = 0; y < 480; ++y:
|
for unsigned y = 0; y < 480; ++y:
|
||||||
unsigned g = (y << 6) / 480
|
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)
|
unsigned olr = 0, ob = ((25 * y * y) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
|
||||||
for unsigned x = 0; x < 800; ++x:
|
for unsigned x = 0; x < 800; ++x:
|
||||||
unsigned r = (x << 5) / 800
|
unsigned r = (x << 5) / 800
|
||||||
@ -139,6 +195,7 @@ int main ():
|
|||||||
ob = b
|
ob = b
|
||||||
b = 0x1f
|
b = 0x1f
|
||||||
LCD_FRAMEBUFFER_BASE[y * 800 + x] = (r << 11) | (g << 5) | (b)
|
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)
|
Descriptor *descriptor = (Descriptor *)((unsigned)LCD_FRAMEBUFFER_BASE + frame_size)
|
||||||
unsigned physical_descriptor = physical + frame_size
|
unsigned physical_descriptor = physical + frame_size
|
||||||
descriptor->next = physical_descriptor
|
descriptor->next = physical_descriptor
|
||||||
@ -147,7 +204,12 @@ int main ():
|
|||||||
descriptor->cmd = LCD_CMD_EOFINT | ((frame_size / 4) << LCD_CMD_LEN_BIT)
|
descriptor->cmd = LCD_CMD_EOFINT | ((frame_size / 4) << LCD_CMD_LEN_BIT)
|
||||||
reset (physical_descriptor)
|
reset (physical_descriptor)
|
||||||
register_interrupt (IRQ_LCD)
|
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:
|
while true:
|
||||||
Message msg
|
Message msg
|
||||||
@ -156,13 +218,11 @@ int main ():
|
|||||||
case IRQ_LCD:
|
case IRQ_LCD:
|
||||||
lcd_clr_eof ()
|
lcd_clr_eof ()
|
||||||
register_interrupt (IRQ_LCD)
|
register_interrupt (IRQ_LCD)
|
||||||
// TODO: allow callback
|
if eof_cb:
|
||||||
|
invoke_00 (eof_cb)
|
||||||
break
|
break
|
||||||
#if 0
|
case LCD_EOF_CB:
|
||||||
case LCD_BACKLIGHT:
|
if eof_cb:
|
||||||
set_backlight (msg.data[0])
|
drop (eof_cb)
|
||||||
|
eof_cb = msg.cap[0]
|
||||||
break
|
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_capability (msg->capabilities[j])
|
||||||
address_space->free_message (this, msg)
|
address_space->free_message (this, msg)
|
||||||
return false
|
return false
|
||||||
if tried_direct:
|
|
||||||
Thread_arch_receive_fail (owner)
|
|
||||||
owner->unwait ()
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
static Capability *reply
|
static Capability *reply
|
||||||
@ -141,8 +138,6 @@ static void fill_cap (Capability *r, unsigned target, unsigned protected_data):
|
|||||||
ref = &((Receiver *)target)->capabilities
|
ref = &((Receiver *)target)->capabilities
|
||||||
else:
|
else:
|
||||||
ref = &((Object_base *)protected_data)->refs
|
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.
|
// 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)
|
top_memory.alloc_capability ((Receiver *)target, NULL, ref, protected_data, r)
|
||||||
|
|
||||||
|
130
iris.h
130
iris.h
@ -29,6 +29,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Number of clock interrupts per second.
|
||||||
|
#define HZ 10
|
||||||
|
|
||||||
#define PAGE_BITS (12)
|
#define PAGE_BITS (12)
|
||||||
#define PAGE_SIZE (1 << PAGE_BITS)
|
#define PAGE_SIZE (1 << PAGE_BITS)
|
||||||
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
||||||
@ -135,6 +138,7 @@ extern Capability __my_receiver;
|
|||||||
extern Capability __my_thread;
|
extern Capability __my_thread;
|
||||||
extern Capability __my_memory;
|
extern Capability __my_memory;
|
||||||
extern Capability __my_call;
|
extern Capability __my_call;
|
||||||
|
extern Capability __my_parent;
|
||||||
|
|
||||||
Capability cap_copy (Capability src)
|
Capability cap_copy (Capability src)
|
||||||
{
|
{
|
||||||
@ -169,23 +173,23 @@ static void invoke (Capability target, Message *msg)
|
|||||||
"\tsyscall"
|
"\tsyscall"
|
||||||
:
|
:
|
||||||
: "m"(target), "m"(msg)
|
: "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)
|
static void wait (Message *msg)
|
||||||
{
|
{
|
||||||
__asm__ volatile ("li $v0, 2\n"
|
__asm__ volatile ("li $v0, 2\n"
|
||||||
"\tsyscall\n"
|
"\tsyscall\n"
|
||||||
"\tlw $v0, %0\n"
|
"\tlw $v1, %0\n"
|
||||||
"\tsw $t0, 0($v0)\n"
|
"\tsw $t0, 0($v1)\n"
|
||||||
"\tsw $t1, 4($v0)\n"
|
"\tsw $t1, 4($v1)\n"
|
||||||
"\tsw $t2, 8($v0)\n"
|
"\tsw $t2, 8($v1)\n"
|
||||||
"\tsw $t3, 12($v0)\n"
|
"\tsw $t3, 12($v1)\n"
|
||||||
"\tsw $a0, 16($v0)\n"
|
"\tsw $a0, 16($v1)\n"
|
||||||
"\tsw $a1, 20($v0)\n"
|
"\tsw $a1, 20($v1)\n"
|
||||||
"\tsw $a2, 24($v0)\n"
|
"\tsw $a2, 24($v1)\n"
|
||||||
"\tsw $a3, 28($v0)\n"
|
"\tsw $a3, 28($v1)\n"
|
||||||
"\tsw $v1, 32($v0)"
|
"\tsw $v0, 32($v1)"
|
||||||
:
|
:
|
||||||
: "m"(msg)
|
: "m"(msg)
|
||||||
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
|
: "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 $a2, 24($v1)\n"
|
||||||
"\tlw $a3, 28($v1)\n"
|
"\tlw $a3, 28($v1)\n"
|
||||||
"\tsyscall\n"
|
"\tsyscall\n"
|
||||||
"\tlw $v0, %1\n"
|
"\tlw $v1, %1\n"
|
||||||
"\tsw $t0, 0($v0)\n"
|
"\tsw $t0, 0($v1)\n"
|
||||||
"\tsw $t1, 4($v0)\n"
|
"\tsw $t1, 4($v1)\n"
|
||||||
"\tsw $t2, 8($v0)\n"
|
"\tsw $t2, 8($v1)\n"
|
||||||
"\tsw $t3, 12($v0)\n"
|
"\tsw $t3, 12($v1)\n"
|
||||||
"\tsw $a0, 16($v0)\n"
|
"\tsw $a0, 16($v1)\n"
|
||||||
"\tsw $a1, 20($v0)\n"
|
"\tsw $a1, 20($v1)\n"
|
||||||
"\tsw $a2, 24($v0)\n"
|
"\tsw $a2, 24($v1)\n"
|
||||||
"\tsw $a3, 28($v0)\n"
|
"\tsw $a3, 28($v1)\n"
|
||||||
"\tsw $v1, 32($v0)"
|
"\tsw $v0, 32($v1)"
|
||||||
:
|
:
|
||||||
: "m"(t), "m"(msg)
|
: "m"(t), "m"(msg)
|
||||||
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
|
: "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)
|
static void invoke_01 (Capability t, unsigned d)
|
||||||
{
|
{
|
||||||
Message msg;
|
Message msg;
|
||||||
@ -276,6 +294,20 @@ static void invoke_04 (Capability t, unsigned d0, unsigned d1, unsigned d2, unsi
|
|||||||
invoke (t, &msg);
|
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)
|
static void invoke_11 (Capability t, Capability c, unsigned d)
|
||||||
{
|
{
|
||||||
Message msg;
|
Message msg;
|
||||||
@ -318,6 +350,62 @@ static void invoke_13 (Capability t, Capability c, unsigned d0, unsigned d1, uns
|
|||||||
invoke (t, &msg);
|
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)
|
static Capability call_c01 (Capability c, unsigned d)
|
||||||
{
|
{
|
||||||
Message msg;
|
Message msg;
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
#ifndef _KERNEL_HH
|
#ifndef _KERNEL_HH
|
||||||
#define _KERNEL_HH
|
#define _KERNEL_HH
|
||||||
|
|
||||||
// Number of clock interrupts per second.
|
|
||||||
#define HZ 10
|
|
||||||
|
|
||||||
// Include definitions which are shared with user space.
|
// Include definitions which are shared with user space.
|
||||||
#define __KERNEL
|
#define __KERNEL
|
||||||
#include "iris.h"
|
#include "iris.h"
|
||||||
@ -205,7 +202,6 @@ void phys_free (unsigned page, unsigned num)
|
|||||||
// Defined by architecture-specific files.
|
// Defined by architecture-specific files.
|
||||||
void Thread_arch_init (Thread *thread)
|
void Thread_arch_init (Thread *thread)
|
||||||
void Thread_arch_receive (Thread *thread, unsigned protected_data, Capability::Context *c)
|
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)
|
unsigned *Thread_arch_info (Thread *thread, unsigned num)
|
||||||
void Memory_arch_init (Memory *mem)
|
void Memory_arch_init (Memory *mem)
|
||||||
void Memory_arch_free (Memory *mem)
|
void Memory_arch_free (Memory *mem)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
load = 0x80000000
|
load = 0x80000000
|
||||||
|
|
||||||
ARCH_CXXFLAGS = -DNUM_THREADS=1
|
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
||||||
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
OBJDUMP = $(CROSS)objdump
|
OBJDUMP = $(CROSS)objdump
|
||||||
@ -26,9 +26,8 @@ OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
|||||||
|
|
||||||
arch_kernel_sources = mips/interrupts.cc mips/test.cc mips/arch.cc
|
arch_kernel_sources = mips/interrupts.cc mips/test.cc mips/arch.cc
|
||||||
boot_sources = mips/init.cc
|
boot_sources = mips/init.cc
|
||||||
BUILT_SOURCES = $(kernel_sources) $(boot_sources)
|
|
||||||
arch_headers = mips/arch.hh mips/jz4730.hh
|
arch_headers = mips/arch.hh mips/jz4730.hh
|
||||||
boot_threads = gpio lcd
|
boot_threads = init gpio lcd
|
||||||
|
|
||||||
uimage:
|
uimage:
|
||||||
|
|
||||||
@ -36,6 +35,10 @@ mips/entry.o: $(boot_threads)
|
|||||||
mips/init.o: TARGET_FLAGS = -I/usr/include
|
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||||
$(boot_threads): TARGET_FLAGS = -I.
|
$(boot_threads): TARGET_FLAGS = -I.
|
||||||
$(boot_threads): boot-programs/devices.hh
|
$(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.
|
# Transform ':' into ';' so vim doesn't think there are errors.
|
||||||
uimage: kernel.raw.gz Makefile mips/Makefile.arch
|
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: %
|
%.gz: %
|
||||||
gzip < $< > $@
|
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.t1 = c->data[1]
|
||||||
thread->arch.t2 = c->data[2]
|
thread->arch.t2 = c->data[2]
|
||||||
thread->arch.t3 = c->data[3]
|
thread->arch.t3 = c->data[3]
|
||||||
thread->arch.v1 = protected_data
|
thread->arch.v0 = protected_data
|
||||||
thread->arch.v0 = 1
|
|
||||||
|
|
||||||
void Thread_arch_receive_fail (Thread *thread):
|
|
||||||
thread->arch.v0 = 0
|
|
||||||
|
|
||||||
unsigned *Thread_arch_info (Thread *thread, unsigned num):
|
unsigned *Thread_arch_info (Thread *thread, unsigned num):
|
||||||
switch 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
|
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.
|
// Set kseg0 cachable.
|
||||||
li $k0, 0x3
|
li $k0, 0x3
|
||||||
@ -67,3 +74,4 @@ thread_start:
|
|||||||
.word thread0
|
.word thread0
|
||||||
.word thread1
|
.word thread1
|
||||||
.word thread2
|
.word thread2
|
||||||
|
.word thread3
|
||||||
|
@ -231,10 +231,14 @@ save_regs:
|
|||||||
.globl thread0
|
.globl thread0
|
||||||
.globl thread1
|
.globl thread1
|
||||||
.globl thread2
|
.globl thread2
|
||||||
|
.globl thread3
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread0:
|
thread0:
|
||||||
.incbin "lcd"
|
.incbin "init"
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread1:
|
thread1:
|
||||||
.incbin "gpio"
|
.incbin "lcd"
|
||||||
|
.balign 0x1000
|
||||||
thread2:
|
thread2:
|
||||||
|
.incbin "gpio"
|
||||||
|
thread3:
|
||||||
|
@ -141,6 +141,8 @@ static void init_threads ():
|
|||||||
//bool executable = shdr->sh_flags & SHF_EXEC_INSTR
|
//bool executable = shdr->sh_flags & SHF_EXEC_INSTR
|
||||||
if shdr->sh_type != SHT_NOBITS:
|
if shdr->sh_type != SHT_NOBITS:
|
||||||
unsigned file_offset = shdr->sh_offset >> PAGE_BITS
|
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:
|
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 section_offset = (p - (shdr->sh_addr & PAGE_MASK)) >> PAGE_BITS
|
||||||
unsigned idx = file_offset + section_offset
|
unsigned idx = file_offset + section_offset
|
||||||
@ -238,11 +240,9 @@ void init (unsigned mem):
|
|||||||
// Set up initial threads.
|
// Set up initial threads.
|
||||||
init_threads ()
|
init_threads ()
|
||||||
|
|
||||||
// Disable all gpio pins initially.
|
// Disable all gpio interrupts and alternate functions initially.
|
||||||
for unsigned i = 0; i < 4; ++i:
|
for unsigned i = 0; i < 4; ++i:
|
||||||
GPIO_GPIER (i) = 0
|
GPIO_GPIER (i) = 0
|
||||||
GPIO_GPDIR (i) = 0
|
|
||||||
GPIO_GPPUR (i) = 0
|
|
||||||
GPIO_GPALR (i) = 0
|
GPIO_GPALR (i) = 0
|
||||||
GPIO_GPAUR (i) = 0
|
GPIO_GPAUR (i) = 0
|
||||||
// Set up the rest of the hardware (copied from Linux).
|
// Set up the rest of the hardware (copied from Linux).
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
#define ARCH
|
#define ARCH
|
||||||
#include "../kernel.hh"
|
#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):
|
static void handle_exit (Thread *old_current):
|
||||||
if !current || (current == &idle):
|
if !current || (current == &idle):
|
||||||
schedule ()
|
schedule ()
|
||||||
@ -26,6 +31,7 @@ static void handle_exit (Thread *old_current):
|
|||||||
current = &idle
|
current = &idle
|
||||||
if old_current == current:
|
if old_current == current:
|
||||||
return
|
return
|
||||||
|
arch_flush_cache ()
|
||||||
if current != &idle:
|
if current != &idle:
|
||||||
if (Memory *)asids[current->address_space->arch.asid] != current->address_space:
|
if (Memory *)asids[current->address_space->arch.asid] != current->address_space:
|
||||||
if asids[0]:
|
if asids[0]:
|
||||||
@ -146,40 +152,48 @@ Thread *exception ():
|
|||||||
switch (cause >> 2) & 0x1f:
|
switch (cause >> 2) & 0x1f:
|
||||||
case 0:
|
case 0:
|
||||||
// Interrupt. This shouldn't happen, since CAUSE[IV] == 1.
|
// Interrupt. This shouldn't happen, since CAUSE[IV] == 1.
|
||||||
panic (0x11223344, "Interrupt on exception vector.")
|
panic (0x01223344, "Interrupt on exception vector.")
|
||||||
case 1:
|
case 1:
|
||||||
// TLB modification.
|
// TLB modification.
|
||||||
panic (0x21223344, "TLB modification.")
|
panic (0x11223344, "TLB modification.")
|
||||||
case 2:
|
case 2:
|
||||||
// TLB load or instruction fetch.
|
// TLB load or instruction fetch.
|
||||||
unsigned a
|
unsigned a
|
||||||
cp0_get (CP0_EPC, a)
|
cp0_get (CP0_EPC, a)
|
||||||
dbg_send (a)
|
dbg_send (a)
|
||||||
panic (0x31223344, "TLB load or instruction fetch.")
|
panic (0x21223344, "TLB load or instruction fetch.")
|
||||||
case 3:
|
case 3:
|
||||||
// TLB store.
|
// TLB store.
|
||||||
unsigned a
|
unsigned a
|
||||||
cp0_get (CP0_EPC, a)
|
cp0_get (CP0_EPC, a)
|
||||||
dbg_send (a)
|
dbg_send (a)
|
||||||
panic (0x41223344, "TLB store.")
|
cp0_get (CP0_BAD_V_ADDR, a)
|
||||||
|
dbg_send (a)
|
||||||
|
panic (0x31223344, "TLB store.")
|
||||||
case 4:
|
case 4:
|
||||||
// Address error load or instruction fetch.
|
// Address error load or instruction fetch.
|
||||||
unsigned a
|
unsigned a
|
||||||
cp0_get (CP0_EPC, a)
|
cp0_get (CP0_EPC, a)
|
||||||
dbg_send (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:
|
case 5:
|
||||||
// Address error store.
|
// Address error store.
|
||||||
|
dbg_send (current->arch.v1, 4)
|
||||||
unsigned a
|
unsigned a
|
||||||
|
cp0_get (CP0_EPC, a)
|
||||||
|
dbg_send (*(unsigned *)(a & ~3), 32)
|
||||||
|
dbg_send (a, 32)
|
||||||
cp0_get (CP0_BAD_V_ADDR, a)
|
cp0_get (CP0_BAD_V_ADDR, a)
|
||||||
dbg_send (a, 32)
|
dbg_send (a, 32)
|
||||||
panic (0x61223344, "Address error store.")
|
panic (0x51223344, "Address error store.")
|
||||||
case 6:
|
case 6:
|
||||||
// Bus error instruction fetch.
|
// Bus error instruction fetch.
|
||||||
panic (0x71223344, "Bus error instruction fetch.")
|
panic (0x61223344, "Bus error instruction fetch.")
|
||||||
case 7:
|
case 7:
|
||||||
// Bus error load or store.
|
// Bus error load or store.
|
||||||
panic (0x81223344, "Bus error load or store.")
|
panic (0x71223344, "Bus error load or store.")
|
||||||
case 8:
|
case 8:
|
||||||
// Syscall.
|
// Syscall.
|
||||||
current->pc += 4
|
current->pc += 4
|
||||||
@ -202,13 +216,13 @@ Thread *exception ():
|
|||||||
panic (0xc1223344, "Arithmetic overflow.")
|
panic (0xc1223344, "Arithmetic overflow.")
|
||||||
case 13:
|
case 13:
|
||||||
// Trap.
|
// Trap.
|
||||||
panic (0xe1223344, "Trap.")
|
panic (0xd1223344, "Trap.")
|
||||||
case 15:
|
case 15:
|
||||||
// Floating point exception.
|
// Floating point exception.
|
||||||
panic (0xf1223344, "Floating point exception.")
|
panic (0xe1223344, "Floating point exception.")
|
||||||
case 23:
|
case 23:
|
||||||
// Reference to WatchHi/WatchLo address.
|
// Reference to WatchHi/WatchLo address.
|
||||||
panic (0xf2223344, "Reference to WatchHi/WatchLo address.")
|
panic (0xf1223344, "Reference to WatchHi/WatchLo address.")
|
||||||
case 24:
|
case 24:
|
||||||
// Machine check.
|
// Machine check.
|
||||||
panic (0xf3223344, "Machine check.")
|
panic (0xf3223344, "Machine check.")
|
||||||
|
@ -92,13 +92,8 @@ void schedule ():
|
|||||||
current = &idle
|
current = &idle
|
||||||
|
|
||||||
void timer_interrupt ():
|
void timer_interrupt ():
|
||||||
//panic (0x88877744, "Timer interrupt")
|
|
||||||
Receiver *recv, *next
|
Receiver *recv, *next
|
||||||
for recv = first_alarm; recv; recv = next:
|
for recv = first_alarm; recv; recv = next:
|
||||||
next = recv->next
|
next = recv->next
|
||||||
alarm_tick (recv)
|
alarm_tick (recv)
|
||||||
schedule ()
|
//schedule ()
|
||||||
//#ifndef NDEBUG
|
|
||||||
//static bool ledstate = false
|
|
||||||
//dbg_led (false, false, ledstate = !ledstate)
|
|
||||||
//#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user