mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-01-17 07:01:05 +02:00
bug hunting
This commit is contained in:
parent
ad2f531ab0
commit
d97f1a4ff2
12
.gitignore
vendored
12
.gitignore
vendored
@ -16,3 +16,15 @@ nanonote-gpio
|
|||||||
boot-programs/charset.data
|
boot-programs/charset.data
|
||||||
mips/nanonote/sdram-setup.raw
|
mips/nanonote/sdram-setup.raw
|
||||||
nanonote-boot
|
nanonote-boot
|
||||||
|
mips/nanonote/server/.deps/
|
||||||
|
mips/nanonote/server/Makefile
|
||||||
|
mips/nanonote/server/Makefile.in
|
||||||
|
mips/nanonote/server/aclocal.m4
|
||||||
|
mips/nanonote/server/autom4te.cache/
|
||||||
|
mips/nanonote/server/config.log
|
||||||
|
mips/nanonote/server/config.status
|
||||||
|
mips/nanonote/server/configure
|
||||||
|
mips/nanonote/server/depcomp
|
||||||
|
mips/nanonote/server/install-sh
|
||||||
|
mips/nanonote/server/missing
|
||||||
|
mips/nanonote/server/usb-server
|
||||||
|
2
Makefile
2
Makefile
@ -50,4 +50,4 @@ clean:
|
|||||||
rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES)
|
rm -f *.o boot-programs/*.o $(BUILT_SOURCES) $(ARCH_CLEAN_FILES)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
.PRECIOUS: iris.hh boot-programs/crt0.o
|
.PRECIOUS: iris.hh kernel.hh boot-programs/crt0.o
|
||||||
|
@ -187,6 +187,7 @@ kThread *kMemory::alloc_thread (unsigned size):
|
|||||||
ret->sp = 0
|
ret->sp = 0
|
||||||
kThread_arch_init (ret)
|
kThread_arch_init (ret)
|
||||||
ret->flags = 0
|
ret->flags = 0
|
||||||
|
ret->id = ~0
|
||||||
ret->schedule_prev = NULL
|
ret->schedule_prev = NULL
|
||||||
ret->schedule_next = NULL
|
ret->schedule_next = NULL
|
||||||
ret->slots = size
|
ret->slots = size
|
||||||
|
@ -53,6 +53,7 @@ enum codes:
|
|||||||
BUZZER = 32
|
BUZZER = 32
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
|
Kernel::schedule ()
|
||||||
map_tcu ()
|
map_tcu ()
|
||||||
|
|
||||||
DevBuzzer buzzer
|
DevBuzzer buzzer
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "iris.hh"
|
#include "iris.hh"
|
||||||
|
|
||||||
static Keyboard sysreq
|
static Keyboard sysreq
|
||||||
static Device kbd_dev, buz_dev
|
static Device kbd_dev, buz_dev, backlight_dev
|
||||||
static unsigned slot
|
static unsigned slot
|
||||||
|
|
||||||
// Event types.
|
// Event types.
|
||||||
@ -28,6 +28,7 @@ enum type:
|
|||||||
SYSREQ
|
SYSREQ
|
||||||
KBDDEV
|
KBDDEV
|
||||||
BUZDEV
|
BUZDEV
|
||||||
|
BACKLIGHTDEV
|
||||||
|
|
||||||
static void user_reply (Kernel::Cap target, unsigned dev):
|
static void user_reply (Kernel::Cap target, unsigned dev):
|
||||||
switch dev:
|
switch dev:
|
||||||
@ -91,6 +92,12 @@ static void setup ():
|
|||||||
reply.invoke ()
|
reply.invoke ()
|
||||||
Kernel::free_cap (reply)
|
Kernel::free_cap (reply)
|
||||||
break
|
break
|
||||||
|
case Setting::ID:
|
||||||
|
caps.set (BACKLIGHTDEV, arg.copy ())
|
||||||
|
backlight_dev = Kernel::Cap (slot, BACKLIGHTDEV)
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
kdebug ("unexpected device\n")
|
kdebug ("unexpected device\n")
|
||||||
break
|
break
|
||||||
@ -106,7 +113,7 @@ static void setup ():
|
|||||||
Kernel::free_cap (arg)
|
Kernel::free_cap (arg)
|
||||||
continue
|
continue
|
||||||
Kernel::free_cap (arg)
|
Kernel::free_cap (arg)
|
||||||
if ++state == 4:
|
if ++state == 5:
|
||||||
break
|
break
|
||||||
// sysreq
|
// sysreq
|
||||||
kdebug ("using sysreq\n")
|
kdebug ("using sysreq\n")
|
||||||
@ -119,8 +126,13 @@ static void setup ():
|
|||||||
Kernel::free_cap (user)
|
Kernel::free_cap (user)
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
|
Kernel::schedule ()
|
||||||
setup ()
|
setup ()
|
||||||
kdebug ("init set up\n")
|
kdebug ("init set up\n")
|
||||||
|
// claim backlight
|
||||||
|
kdebug ("claiming backlight\n")
|
||||||
|
Setting backlight = backlight_dev.create_user (Kernel::Cap ())
|
||||||
|
backlight_dev.use (backlight)
|
||||||
while true:
|
while true:
|
||||||
Kernel::wait ()
|
Kernel::wait ()
|
||||||
switch Kernel::recv.protected_data.value ():
|
switch Kernel::recv.protected_data.value ():
|
||||||
@ -129,8 +141,10 @@ Kernel::Num start ():
|
|||||||
kdebug ("\n\nSystem request ")
|
kdebug ("\n\nSystem request ")
|
||||||
if code & Keyboard::RELEASE:
|
if code & Keyboard::RELEASE:
|
||||||
kdebug ("released.\n\n")
|
kdebug ("released.\n\n")
|
||||||
|
backlight.set (~0)
|
||||||
else:
|
else:
|
||||||
kdebug ("pressed.\n\n")
|
kdebug ("pressed.\n\n")
|
||||||
|
backlight.set (0)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
if Kernel::recv.data[0].l != Parent::GET_DEVICE:
|
if Kernel::recv.data[0].l != Parent::GET_DEVICE:
|
||||||
|
@ -28,8 +28,12 @@ extern unsigned char const charset[127-32][6]
|
|||||||
|
|
||||||
#if defined (TRENDTAC)
|
#if defined (TRENDTAC)
|
||||||
static unsigned h = 800, v = 480, fps = 60, Bpp = 2
|
static unsigned h = 800, v = 480, fps = 60, Bpp = 2
|
||||||
|
#define LOG_X_BASE 1
|
||||||
|
#define LOG_Y_BASE 1
|
||||||
#elif defined (NANONOTE)
|
#elif defined (NANONOTE)
|
||||||
static unsigned h = 320, v = 240, fps = 60, Bpp = 4
|
static unsigned h = 320, v = 240, fps = 60, Bpp = 4
|
||||||
|
#define LOG_X_BASE 0
|
||||||
|
#define LOG_Y_BASE 0
|
||||||
#else
|
#else
|
||||||
#error unknown board
|
#error unknown board
|
||||||
#endif
|
#endif
|
||||||
@ -200,12 +204,12 @@ static void putchar (unsigned x, unsigned y, unsigned ch, unsigned fg = 0xffff,
|
|||||||
for unsigned r = 0; r < 8; ++r:
|
for unsigned r = 0; r < 8; ++r:
|
||||||
LCD_FRAMEBUFFER_BASE[(y * 8 + r) * h + x * 6 + k] = lookup[charset[ch][k] & (1 << r) ? 1 : 0]
|
LCD_FRAMEBUFFER_BASE[(y * 8 + r) * h + x * 6 + k] = lookup[charset[ch][k] & (1 << r) ? 1 : 0]
|
||||||
|
|
||||||
static unsigned log_x = 1, log_y = 1
|
static unsigned log_x = LOG_X_BASE, log_y = LOG_Y_BASE
|
||||||
static void inc_logx ():
|
static void inc_logx ():
|
||||||
if ++log_x >= h / 6:
|
if ++log_x >= h / 6:
|
||||||
log_x = 1
|
log_x = LOG_X_BASE
|
||||||
if ++log_y >= v / 8:
|
if ++log_y >= v / 8:
|
||||||
log_y = 1
|
log_y = LOG_Y_BASE
|
||||||
|
|
||||||
static void log_char (unsigned ch):
|
static void log_char (unsigned ch):
|
||||||
switch ch:
|
switch ch:
|
||||||
@ -241,10 +245,9 @@ static void log_msg ():
|
|||||||
log_char ('\n')
|
log_char ('\n')
|
||||||
|
|
||||||
enum captype:
|
enum captype:
|
||||||
#ifdef TRENDTAC
|
LOG = 32
|
||||||
LOG
|
|
||||||
#endif
|
|
||||||
SET_EOF_CB
|
SET_EOF_CB
|
||||||
|
BACKLIGHT
|
||||||
|
|
||||||
static unsigned spot (unsigned x, unsigned y, unsigned cx, unsigned cy):
|
static unsigned spot (unsigned x, unsigned y, unsigned cx, unsigned cy):
|
||||||
unsigned dx2 = (x - cx) * (x - cx)
|
unsigned dx2 = (x - cx) * (x - cx)
|
||||||
@ -256,6 +259,7 @@ static unsigned spot (unsigned x, unsigned y, unsigned cx, unsigned cy):
|
|||||||
return ((l * l - d2 - 1) << 8) / (l * l)
|
return ((l * l - d2 - 1) << 8) / (l * l)
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
|
Kernel::schedule ()
|
||||||
map_lcd ()
|
map_lcd ()
|
||||||
map_cpm ()
|
map_cpm ()
|
||||||
#ifdef NANONOTE
|
#ifdef NANONOTE
|
||||||
@ -300,32 +304,118 @@ Kernel::Num start ():
|
|||||||
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Register the backlight device.
|
||||||
|
Kernel::Cap backlight = Kernel::my_receiver.create_capability (BACKLIGHT)
|
||||||
|
Kernel::my_parent.provide_device <Setting> (backlight)
|
||||||
|
|
||||||
Kernel::Cap eof_cb
|
Kernel::Cap eof_cb
|
||||||
bool have_eof = false
|
bool have_eof = false
|
||||||
|
bool is_on = true
|
||||||
|
unsigned backlight_user = 0
|
||||||
|
Kernel::Num current_backlight = 0
|
||||||
while true:
|
while true:
|
||||||
Kernel::wait ()
|
Kernel::wait ()
|
||||||
//log_msg ()
|
//log_msg ()
|
||||||
|
switch Kernel::recv.protected_data.h:
|
||||||
|
case 0:
|
||||||
switch Kernel::recv.protected_data.l:
|
switch Kernel::recv.protected_data.l:
|
||||||
case IRQ_LCD:
|
case IRQ_LCD:
|
||||||
lcd_clr_eof ()
|
lcd_clr_eof ()
|
||||||
eof_cb.invoke ()
|
eof_cb.invoke ()
|
||||||
break
|
have_eof = false
|
||||||
case SET_EOF_CB:
|
|
||||||
if have_eof:
|
|
||||||
Kernel::free_cap (eof_cb)
|
Kernel::free_cap (eof_cb)
|
||||||
else:
|
|
||||||
have_eof = true
|
|
||||||
eof_cb = Kernel::get_arg ()
|
|
||||||
Kernel::Cap reply = Kernel::get_reply ()
|
|
||||||
Kernel::register_interrupt (IRQ_LCD)
|
|
||||||
reply.invoke ()
|
|
||||||
Kernel::free_cap (reply)
|
|
||||||
break
|
break
|
||||||
#ifdef TRENDTAC
|
#if defined (TRENDTAC)
|
||||||
case LOG:
|
case LOG:
|
||||||
log_char (Kernel::recv.data[0].l)
|
log_char (Kernel::recv.data[0].l)
|
||||||
break
|
break
|
||||||
#endif
|
#endif
|
||||||
|
case BACKLIGHT:
|
||||||
|
switch Kernel::recv.data[0].l:
|
||||||
|
case Device::CREATE_USER:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
Kernel::Cap c = Kernel::my_receiver.create_capability (Kernel::Num (backlight_user++, BACKLIGHT))
|
||||||
|
reply.invoke (0, 0, c.copy ())
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
|
case Device::DESTROY_USER:
|
||||||
|
Kernel::recv.reply.invoke ()
|
||||||
|
break
|
||||||
|
case Device::USE:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
|
current_backlight = Kernel::my_receiver.get_protected (arg)
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (arg)
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
|
case Device::UNUSE:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
|
if current_backlight.value () == Kernel::my_receiver.get_protected (arg).value ():
|
||||||
|
current_backlight = 0
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (arg)
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
log_char ('@')
|
||||||
|
break
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
log_char ('#')
|
||||||
|
log_num (Kernel::recv.protected_data)
|
||||||
|
log_char ('\n')
|
||||||
|
break
|
||||||
|
break
|
||||||
|
case BACKLIGHT:
|
||||||
|
if current_backlight.value () != Kernel::recv.protected_data.value ():
|
||||||
|
log_char ('&')
|
||||||
|
log_num (current_backlight)
|
||||||
|
log_num (Kernel::recv.protected_data)
|
||||||
|
log_char ('\n')
|
||||||
|
break
|
||||||
|
switch Kernel::recv.data[0].l:
|
||||||
|
case Setting::SET:
|
||||||
|
// TODO
|
||||||
|
unsigned state = Kernel::recv.data[1].l
|
||||||
|
if !state:
|
||||||
|
#if defined (NANONOTE)
|
||||||
|
if is_on:
|
||||||
|
write_reg (BACKLIGHT1, 0x5e)
|
||||||
|
is_on = false
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
else:
|
||||||
|
#if defined (NANONOTE)
|
||||||
|
if !is_on:
|
||||||
|
write_reg (BACKLIGHT1, 0x5f)
|
||||||
|
is_on = true
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
Kernel::recv.reply.invoke ()
|
||||||
|
break
|
||||||
|
case Setting::GET_RANGE:
|
||||||
|
Kernel::recv.reply.invoke (~0)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
log_char ('$')
|
||||||
|
break
|
||||||
|
break
|
||||||
|
case SET_EOF_CB:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
if have_eof:
|
||||||
|
Kernel::free_cap (eof_cb)
|
||||||
|
else:
|
||||||
|
Kernel::register_interrupt (IRQ_LCD)
|
||||||
|
have_eof = true
|
||||||
|
eof_cb = Kernel::get_arg ()
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
log_char ('~')
|
log_char ('~')
|
||||||
|
log_num (Kernel::recv.protected_data)
|
||||||
|
log_char ('\n')
|
||||||
break
|
break
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "keys.hh"
|
#include "keys.hh"
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
|
Kernel::schedule ()
|
||||||
kdebug ("metronome started\n")
|
kdebug ("metronome started\n")
|
||||||
Buzzer buzzer = Kernel::my_parent.get_device <Buzzer> ()
|
Buzzer buzzer = Kernel::my_parent.get_device <Buzzer> ()
|
||||||
Keyboard kbd = Kernel::my_parent.get_device <Keyboard> ()
|
Keyboard kbd = Kernel::my_parent.get_device <Keyboard> ()
|
||||||
|
@ -195,6 +195,7 @@ enum codes:
|
|||||||
PWR
|
PWR
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
|
Kernel::schedule ()
|
||||||
map_gpio ()
|
map_gpio ()
|
||||||
|
|
||||||
DevKbd kbd
|
DevKbd kbd
|
||||||
|
@ -154,6 +154,9 @@ class Udc:
|
|||||||
bool vendor (Setup *s)
|
bool vendor (Setup *s)
|
||||||
bool get_descriptor (unsigned type, unsigned idx, unsigned len)
|
bool get_descriptor (unsigned type, unsigned idx, unsigned len)
|
||||||
bool handle_setup (Setup *s)
|
bool handle_setup (Setup *s)
|
||||||
|
char log_buffer[1000]
|
||||||
|
unsigned log_buffer_size
|
||||||
|
unsigned log_buffer_start
|
||||||
public:
|
public:
|
||||||
void init ()
|
void init ()
|
||||||
void log (unsigned c)
|
void log (unsigned c)
|
||||||
@ -193,6 +196,8 @@ void Udc::init ():
|
|||||||
s_langs = (String <1>){ sizeof (String <1>), String <1>::Type, { 0x0409 } }
|
s_langs = (String <1>){ sizeof (String <1>), String <1>::Type, { 0x0409 } }
|
||||||
s_manufacturer = (String <6>){ sizeof (String <6>), String <6>::Type, { 's', 'h', 'e', 'v', 'e', 'k' } }
|
s_manufacturer = (String <6>){ sizeof (String <6>), String <6>::Type, { 's', 'h', 'e', 'v', 'e', 'k' } }
|
||||||
s_product = (String <16>){ sizeof (String <16>), String <16>::Type, { 'I', 'r', 'i', 's', ' ', 'o', 'n', ' ', 'N', 'a', 'n', 'o', 'N', 'o', 't', 'e' } }
|
s_product = (String <16>){ sizeof (String <16>), String <16>::Type, { 'I', 'r', 'i', 's', ' ', 'o', 'n', ' ', 'N', 'a', 'n', 'o', 'N', 'o', 't', 'e' } }
|
||||||
|
log_buffer_size = 0
|
||||||
|
log_buffer_start = 0
|
||||||
|
|
||||||
// Disconnect from the bus and don't try to get high-speed.
|
// Disconnect from the bus and don't try to get high-speed.
|
||||||
UDC_POWER &= ~(UDC_POWER_SOFTCONN | UDC_POWER_HSENAB)
|
UDC_POWER &= ~(UDC_POWER_SOFTCONN | UDC_POWER_HSENAB)
|
||||||
@ -210,31 +215,41 @@ void Udc::init ():
|
|||||||
// enable interrupts on endpoint 0.
|
// enable interrupts on endpoint 0.
|
||||||
UDC_INTRINE |= 1 << 0
|
UDC_INTRINE |= 1 << 0
|
||||||
UDC_INDEX = 0
|
UDC_INDEX = 0
|
||||||
// Wait a bit and connect to the host.
|
// Connect to the host.
|
||||||
Kernel::my_receiver.sleep (10)
|
|
||||||
UDC_POWER |= UDC_POWER_SOFTCONN
|
UDC_POWER |= UDC_POWER_SOFTCONN
|
||||||
|
|
||||||
bool Udc::vendor (Setup *s):
|
bool Udc::vendor (Setup *s):
|
||||||
if s->request_type & 0x80:
|
if !(s->request_type & 0x80):
|
||||||
|
return true
|
||||||
|
if s->request == 10:
|
||||||
|
static char b[2]
|
||||||
|
ptr = b
|
||||||
|
size = s->length < 2 ? s->length : 2
|
||||||
|
b[0] = '#'
|
||||||
|
if log_buffer_start == log_buffer_size:
|
||||||
|
size = 1
|
||||||
|
else:
|
||||||
|
b[1] = log_buffer[log_buffer_start++]
|
||||||
|
if log_buffer_start == log_buffer_size:
|
||||||
|
log_buffer_start = 0
|
||||||
|
log_buffer_size = 0
|
||||||
|
else:
|
||||||
static char const *name = "Reboot"
|
static char const *name = "Reboot"
|
||||||
ptr = name
|
ptr = name
|
||||||
size = s->length < 6 ? s->length : 6
|
size = s->length < 6 ? s->length : 6
|
||||||
state = TX
|
|
||||||
rebooting = true
|
rebooting = true
|
||||||
return true
|
state = TX
|
||||||
return true
|
return true
|
||||||
|
|
||||||
bool Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
|
bool Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
|
||||||
switch type:
|
switch type:
|
||||||
case Configuration::Type:
|
case Configuration::Type:
|
||||||
//kdebug ("config\n")
|
|
||||||
if idx != 0:
|
if idx != 0:
|
||||||
return false
|
return false
|
||||||
ptr = reinterpret_cast <char const *> (&config_descriptor)
|
ptr = reinterpret_cast <char const *> (&config_descriptor)
|
||||||
size = (len < sizeof (config_descriptor) ? len : sizeof (config_descriptor))
|
size = (len < sizeof (config_descriptor) ? len : sizeof (config_descriptor))
|
||||||
break
|
break
|
||||||
case Device::Type:
|
case Device::Type:
|
||||||
//kdebug ("device\n")
|
|
||||||
if idx != 0:
|
if idx != 0:
|
||||||
return false
|
return false
|
||||||
ptr = reinterpret_cast <char const *> (&device_descriptor)
|
ptr = reinterpret_cast <char const *> (&device_descriptor)
|
||||||
@ -249,7 +264,6 @@ bool Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
|
|||||||
return false
|
return false
|
||||||
// The 6 is an arbitrary number, except that String <6> in instantiated already.
|
// The 6 is an arbitrary number, except that String <6> in instantiated already.
|
||||||
case String <6>::Type:
|
case String <6>::Type:
|
||||||
//kdebug ("string\n")
|
|
||||||
switch idx:
|
switch idx:
|
||||||
case 0:
|
case 0:
|
||||||
ptr = reinterpret_cast <char const *> (&s_langs)
|
ptr = reinterpret_cast <char const *> (&s_langs)
|
||||||
@ -272,17 +286,6 @@ bool Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
|
|||||||
return true
|
return true
|
||||||
|
|
||||||
bool Udc::handle_setup (Setup *s):
|
bool Udc::handle_setup (Setup *s):
|
||||||
//kdebug ("udc: setup: type=")
|
|
||||||
//kdebug_num (s->request_type, 2)
|
|
||||||
//kdebug ("; request=")
|
|
||||||
//kdebug_num (s->request, 2)
|
|
||||||
//kdebug ("; value=")
|
|
||||||
//kdebug_num (s->value, 4)
|
|
||||||
//kdebug ("; index=")
|
|
||||||
//kdebug_num (s->index, 4)
|
|
||||||
//kdebug ("; length=")
|
|
||||||
//kdebug_num (s->length, 4)
|
|
||||||
//kdebug ("\n")
|
|
||||||
switch s->request_type:
|
switch s->request_type:
|
||||||
case STANDARD_TO_DEVICE:
|
case STANDARD_TO_DEVICE:
|
||||||
switch s->request:
|
switch s->request:
|
||||||
@ -333,7 +336,6 @@ bool Udc::handle_setup (Setup *s):
|
|||||||
void Udc::interrupt ():
|
void Udc::interrupt ():
|
||||||
unsigned i = UDC_INTRUSB
|
unsigned i = UDC_INTRUSB
|
||||||
if i & UDC_INTR_RESET:
|
if i & UDC_INTR_RESET:
|
||||||
//kdebug ("udc: reset\n")
|
|
||||||
state = IDLE
|
state = IDLE
|
||||||
return
|
return
|
||||||
i = UDC_INTRIN
|
i = UDC_INTRIN
|
||||||
@ -357,24 +359,18 @@ void Udc::interrupt ():
|
|||||||
packet.d[1] = UDC_FIFO (0)
|
packet.d[1] = UDC_FIFO (0)
|
||||||
UDC_CSR0 = csr | UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
|
UDC_CSR0 = csr | UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
|
||||||
if !handle_setup (&packet.s):
|
if !handle_setup (&packet.s):
|
||||||
//kdebug ("stall 1\n")
|
|
||||||
csr |= UDC_CSR0_SENDSTALL
|
csr |= UDC_CSR0_SENDSTALL
|
||||||
break
|
break
|
||||||
if size == 0:
|
if size == 0:
|
||||||
return
|
return
|
||||||
// Fall through.
|
// Fall through.
|
||||||
case TX:
|
case TX:
|
||||||
//kdebug ("udc: send next:")
|
|
||||||
unsigned i
|
unsigned i
|
||||||
for i = 0; (size & ~3) > 0 && i < max_packet_size0; i += 4, size -= 4:
|
for i = 0; (size & ~3) > 0 && i < max_packet_size0; i += 4, size -= 4:
|
||||||
//for unsigned i = 0; i < 4; ++i:
|
|
||||||
//kdebug_num (ptr[i], 2)
|
|
||||||
UDC_FIFO (0) = *(unsigned *)ptr
|
UDC_FIFO (0) = *(unsigned *)ptr
|
||||||
ptr += 4
|
ptr += 4
|
||||||
for ; size > 0 && i < max_packet_size0; ++i, --size:
|
for ; size > 0 && i < max_packet_size0; ++i, --size:
|
||||||
//kdebug_num (*ptr, 2)
|
|
||||||
UDC_FIFO8 (0) = *ptr++
|
UDC_FIFO8 (0) = *ptr++
|
||||||
//kdebug ("\n")
|
|
||||||
if i == max_packet_size0:
|
if i == max_packet_size0:
|
||||||
csr |= UDC_CSR0_INPKTRDY
|
csr |= UDC_CSR0_INPKTRDY
|
||||||
else:
|
else:
|
||||||
@ -383,19 +379,19 @@ void Udc::interrupt ():
|
|||||||
break
|
break
|
||||||
case RX:
|
case RX:
|
||||||
// Not supported.
|
// Not supported.
|
||||||
//kdebug ("stall 2\n")
|
|
||||||
csr |= UDC_CSR0_SVDOUTPKTRDY | UDC_CSR0_SENDSTALL
|
csr |= UDC_CSR0_SVDOUTPKTRDY | UDC_CSR0_SENDSTALL
|
||||||
state = IDLE
|
state = IDLE
|
||||||
break
|
break
|
||||||
UDC_CSR0 = csr
|
UDC_CSR0 = csr
|
||||||
|
|
||||||
void Udc::log (unsigned c):
|
void Udc::log (unsigned c):
|
||||||
kdebug ("udc: log ")
|
if log_buffer_size >= sizeof (log_buffer):
|
||||||
kdebug_char (c)
|
return
|
||||||
kdebug ("\n")
|
log_buffer[log_buffer_size++] = c
|
||||||
|
|
||||||
enum pdata:
|
enum pdata:
|
||||||
LOG = 32
|
LOG = 32
|
||||||
|
FS
|
||||||
|
|
||||||
Kernel::Num start ():
|
Kernel::Num start ():
|
||||||
map_udc ()
|
map_udc ()
|
||||||
@ -403,12 +399,18 @@ Kernel::Num start ():
|
|||||||
map_cpm ()
|
map_cpm ()
|
||||||
Udc udc
|
Udc udc
|
||||||
|
|
||||||
udc.init ()
|
|
||||||
Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG)
|
Kernel::Cap logcap = Kernel::my_receiver.create_capability (LOG)
|
||||||
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
||||||
|
udc.init ()
|
||||||
Kernel::register_interrupt (IRQ_UDC)
|
Kernel::register_interrupt (IRQ_UDC)
|
||||||
|
Device fs_dev = Kernel::my_receiver.create_capability (FS)
|
||||||
|
Kernel::my_parent.provide_device <Directory> (fs_dev)
|
||||||
|
Kernel::Num current_user = 0
|
||||||
|
unsigned next_user
|
||||||
while true:
|
while true:
|
||||||
Kernel::wait ()
|
Kernel::wait ()
|
||||||
|
switch Kernel::recv.protected_data.h:
|
||||||
|
case 0:
|
||||||
switch Kernel::recv.protected_data.l:
|
switch Kernel::recv.protected_data.l:
|
||||||
case IRQ_UDC:
|
case IRQ_UDC:
|
||||||
udc.interrupt ()
|
udc.interrupt ()
|
||||||
@ -417,6 +419,57 @@ Kernel::Num start ():
|
|||||||
case LOG:
|
case LOG:
|
||||||
udc.log (Kernel::recv.data[0].l)
|
udc.log (Kernel::recv.data[0].l)
|
||||||
break
|
break
|
||||||
|
case FS:
|
||||||
|
switch Kernel::recv.data[0].l:
|
||||||
|
case Device::CREATE_USER:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
Kernel::Cap c = Kernel::my_receiver.create_capability (Kernel::Num (next_user++, FS))
|
||||||
|
reply.invoke (0, 0, c.copy ())
|
||||||
|
Kernel::free_cap (c)
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
|
case Device::DESTROY_USER:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
break
|
||||||
|
case Device::USE:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
|
current_user = Kernel::my_receiver.get_protected (arg)
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
Kernel::free_cap (arg)
|
||||||
|
break
|
||||||
|
case Device::UNUSE:
|
||||||
|
Kernel::Cap reply = Kernel::get_reply ()
|
||||||
|
Kernel::Cap arg = Kernel::get_arg ()
|
||||||
|
if current_user.value () == Kernel::my_receiver.get_protected (arg).value ():
|
||||||
|
current_user = 0
|
||||||
|
reply.invoke ()
|
||||||
|
Kernel::free_cap (reply)
|
||||||
|
Kernel::free_cap (arg)
|
||||||
|
break
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
udc.log ('~')
|
udc.log ('~')
|
||||||
|
char digit[] = "0123456789abcdef"
|
||||||
|
for unsigned i = 0; i < 8; ++i:
|
||||||
|
udc.log (digit[(Kernel::recv.protected_data.l >> (4 * (7 - i))) & 0xf])
|
||||||
|
udc.log ('\n')
|
||||||
|
break
|
||||||
|
case FS:
|
||||||
|
if current_user.value () != Kernel::recv.protected_data.value ():
|
||||||
|
break
|
||||||
|
switch Kernel::recv.data[0].l:
|
||||||
|
case Directory::GET_SIZE:
|
||||||
|
case Directory::GET_NAME:
|
||||||
|
case Directory::GET_FILE_RO:
|
||||||
|
case Directory::LOCK_RO:
|
||||||
|
case Directory::UNLOCK_RO:
|
||||||
|
Kernel::recv.reply.invoke ()
|
||||||
|
break
|
||||||
|
case Directory::GET_FILE_INFO:
|
||||||
|
default:
|
||||||
|
Kernel::recv.reply.invoke (~0)
|
||||||
break
|
break
|
||||||
|
18
devices.hhp
18
devices.hhp
@ -171,6 +171,7 @@ struct Display : public Kernel::Cap:
|
|||||||
CREATE_FB
|
CREATE_FB
|
||||||
USE_FB
|
USE_FB
|
||||||
GET_INFO
|
GET_INFO
|
||||||
|
SET_STATE
|
||||||
ID
|
ID
|
||||||
// Register an end-of-frame callback.
|
// Register an end-of-frame callback.
|
||||||
// At end of frame, the callback is invoked and forgotten. It must be reregistered to keep a stream of events.
|
// At end of frame, the callback is invoked and forgotten. It must be reregistered to keep a stream of events.
|
||||||
@ -192,6 +193,19 @@ struct Display : public Kernel::Cap:
|
|||||||
// TODO: Interface is to be designed.
|
// TODO: Interface is to be designed.
|
||||||
|
|
||||||
|
|
||||||
|
// Numeric setting, such as a display backlight.
|
||||||
|
struct Setting : public Kernel::Cap:
|
||||||
|
Setting (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
|
enum request:
|
||||||
|
SET = Display::ID
|
||||||
|
GET_RANGE
|
||||||
|
ID
|
||||||
|
// Set a new value.
|
||||||
|
void set (unsigned value):
|
||||||
|
call (CAP_MASTER_DIRECT | SET, value)
|
||||||
|
// Get the maximum value for this setting. Using a higher value with SET gives undefined results.
|
||||||
|
unsigned get_range ():
|
||||||
|
return call (CAP_MASTER_DIRECT | GET_RANGE).l
|
||||||
|
|
||||||
// File system interface.
|
// File system interface.
|
||||||
// filesystem-related interfaces: directory, stream, seekable.
|
// filesystem-related interfaces: directory, stream, seekable.
|
||||||
@ -202,7 +216,7 @@ struct Display : public Kernel::Cap:
|
|||||||
struct Directory : public Kernel::Cap:
|
struct Directory : public Kernel::Cap:
|
||||||
Directory (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
Directory (Kernel::Cap c = Kernel::Cap ()) : Kernel::Cap (c):
|
||||||
enum request:
|
enum request:
|
||||||
GET_SIZE = Display::ID
|
GET_SIZE = Setting::ID
|
||||||
GET_NAME
|
GET_NAME
|
||||||
GET_FILE_RO
|
GET_FILE_RO
|
||||||
GET_FILE_INFO
|
GET_FILE_INFO
|
||||||
@ -254,7 +268,7 @@ struct WDirectory : public Directory:
|
|||||||
call (CAP_MASTER_DIRECT | LOCK)
|
call (CAP_MASTER_DIRECT | LOCK)
|
||||||
// Unlock the directory. Write operations can only be done when the directory is locked.
|
// Unlock the directory. Write operations can only be done when the directory is locked.
|
||||||
void unlock ():
|
void unlock ():
|
||||||
call (CAP_MASTER_DIRECT | LOCK)
|
call (CAP_MASTER_DIRECT | UNLOCK)
|
||||||
|
|
||||||
// Stream interface.
|
// Stream interface.
|
||||||
struct Stream : public Kernel::Cap:
|
struct Stream : public Kernel::Cap:
|
||||||
|
@ -49,6 +49,8 @@ static void log_message (char const *prefix, unsigned target, unsigned pdata, kC
|
|||||||
void kThread::raise (unsigned code, unsigned data):
|
void kThread::raise (unsigned code, unsigned data):
|
||||||
dpanic (code, "raise")
|
dpanic (code, "raise")
|
||||||
dbg_log ("raise ")
|
dbg_log ("raise ")
|
||||||
|
dbg_log_num (old_current->id, 2)
|
||||||
|
dbg_log_char (':')
|
||||||
dbg_log_num ((unsigned)old_current)
|
dbg_log_num ((unsigned)old_current)
|
||||||
dbg_log_char ('/')
|
dbg_log_char ('/')
|
||||||
if code < Kernel::NUM_EXCEPTION_CODES:
|
if code < Kernel::NUM_EXCEPTION_CODES:
|
||||||
|
2
iris.hhp
2
iris.hhp
@ -492,7 +492,7 @@ namespace Kernel:
|
|||||||
|
|
||||||
void Receiver::sleep (unsigned value):
|
void Receiver::sleep (unsigned value):
|
||||||
my_receiver.set_alarm (value)
|
my_receiver.set_alarm (value)
|
||||||
wait ()
|
Cap ().call ()
|
||||||
|
|
||||||
// The start function has this prototype (there is no main function).
|
// The start function has this prototype (there is no main function).
|
||||||
Kernel::Num start ()
|
Kernel::Num start ()
|
||||||
|
@ -120,6 +120,9 @@ struct kThread : public kObject:
|
|||||||
unsigned recv_reply, recv_arg
|
unsigned recv_reply, recv_arg
|
||||||
// caps is an array of slots pointers to kCapses.
|
// caps is an array of slots pointers to kCapses.
|
||||||
unsigned slots
|
unsigned slots
|
||||||
|
#ifndef NDEBUG
|
||||||
|
unsigned id
|
||||||
|
#endif
|
||||||
struct caps_store:
|
struct caps_store:
|
||||||
_slot_data prev, next
|
_slot_data prev, next
|
||||||
kCapsP caps
|
kCapsP caps
|
||||||
|
12
memory.ccp
12
memory.ccp
@ -10,7 +10,7 @@ static void clear_page (unsigned page, unsigned num = 1):
|
|||||||
if *((unsigned *)page) != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0:
|
if *((unsigned *)page) != 0 || ((unsigned *)page)[(num << (PAGE_BITS - 2)) - 1] != 0:
|
||||||
dpanic (0, "clear_page didn't work")
|
dpanic (0, "clear_page didn't work")
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
|
|
||||||
static unsigned free_begin
|
static unsigned free_begin
|
||||||
static unsigned free_end
|
static unsigned free_end
|
||||||
@ -33,10 +33,12 @@ void phys_free (unsigned page, unsigned num):
|
|||||||
// Not supported.
|
// Not supported.
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void check_impl (kObject *o, unsigned num, char const *msg):
|
/*void check_impl (kObject *o, unsigned num, char const *msg):
|
||||||
for ; o; o = o->next:
|
// for ; o; o = (kObject *)o->next:
|
||||||
if (unsigned)o >= (unsigned)free_begin && (unsigned)o < (unsigned)free_end:
|
// if (unsigned)o >= (unsigned)free_begin && (unsigned)o < (unsigned)free_end:
|
||||||
panic (num, msg)
|
*/ // panic (num, msg)
|
||||||
|
bool check_free (kObject *o, unsigned size):
|
||||||
|
return true
|
||||||
void print_free ():
|
void print_free ():
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
@ -166,6 +166,9 @@ static void tlb_reset (unsigned address, unsigned asid, unsigned value):
|
|||||||
__asm__ volatile ("tlbwi")
|
__asm__ volatile ("tlbwi")
|
||||||
|
|
||||||
static void free_page (arch_page_table *t, arch_page *p):
|
static void free_page (arch_page_table *t, arch_page *p):
|
||||||
|
dbg_log ("free page ")
|
||||||
|
dbg_log_num ((unsigned)p)
|
||||||
|
dbg_log_char ('\n')
|
||||||
if p->prev_mapped:
|
if p->prev_mapped:
|
||||||
p->prev_mapped->next_mapped = p->next_mapped
|
p->prev_mapped->next_mapped = p->next_mapped
|
||||||
else:
|
else:
|
||||||
|
@ -119,6 +119,9 @@ static void init_threads ():
|
|||||||
kMemory *mem = top_memory.alloc_memory ()
|
kMemory *mem = top_memory.alloc_memory ()
|
||||||
assert (mem)
|
assert (mem)
|
||||||
kThread *thread = mem->alloc_thread (NUM_SLOTS)
|
kThread *thread = mem->alloc_thread (NUM_SLOTS)
|
||||||
|
#ifndef NDEBUG
|
||||||
|
thread->id = i
|
||||||
|
#endif
|
||||||
kPage **pages = (kPage **)mem->zalloc ()
|
kPage **pages = (kPage **)mem->zalloc ()
|
||||||
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
|
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
|
||||||
for unsigned j = 0; j < SELFMAG; ++j:
|
for unsigned j = 0; j < SELFMAG; ++j:
|
||||||
@ -150,12 +153,21 @@ 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):
|
if (file_offset + ((shdr->sh_size + PAGE_SIZE - 1) >> PAGE_BITS)) >= (PAGE_SIZE >> 2):
|
||||||
panic (0x87446809, "initial thread too large")
|
panic (0x87446809, "initial thread too large")
|
||||||
return
|
return
|
||||||
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
|
||||||
|
kPage *page = mem->get_mapping (p, &readonly)
|
||||||
|
if page:
|
||||||
|
if !pages[idx]:
|
||||||
|
panic (0, "multiple pages mapped to one address in initial file")
|
||||||
|
return
|
||||||
|
if pages[idx]->frame != page->frame:
|
||||||
|
panic (0, "different pages mapped to one address in intitial file")
|
||||||
|
return
|
||||||
|
continue
|
||||||
if !pages[idx]:
|
if !pages[idx]:
|
||||||
pages[idx] = mem->alloc_page ()
|
pages[idx] = mem->alloc_page ()
|
||||||
pages[idx]->frame = thread_start[i] + (idx << PAGE_BITS)
|
pages[idx]->frame = thread_start[i] + (idx << PAGE_BITS)
|
||||||
|
@ -25,16 +25,15 @@ void arch_flush_cache ():
|
|||||||
__asm__ volatile ("lw $k0, %0; cache 0, 0($k0); cache 1, 0($k0)" :: "m"(line))
|
__asm__ volatile ("lw $k0, %0; cache 0, 0($k0); cache 1, 0($k0)" :: "m"(line))
|
||||||
|
|
||||||
static void handle_exit ():
|
static void handle_exit ():
|
||||||
|
--dbg_code.h
|
||||||
// Set must_wait to false, so random threads are not set to waiting when the kernel invokes something (such as a dbg_cap).
|
// Set must_wait to false, so random threads are not set to waiting when the kernel invokes something (such as a dbg_cap).
|
||||||
must_wait = false
|
must_wait = false
|
||||||
if !current || (current == &idle):
|
if !current || (current == &idle):
|
||||||
schedule ()
|
schedule ()
|
||||||
if !current:
|
if !current:
|
||||||
current = &idle
|
current = &idle
|
||||||
if (current->flags & (Kernel::Thread::RUNNING | Kernel::Thread::WAITING)) != Kernel::Thread::RUNNING:
|
//if (current->flags & (Kernel::Thread::RUNNING | Kernel::Thread::WAITING)) != Kernel::Thread::RUNNING:
|
||||||
panic (current->flags, "non-scheduled thread running")
|
//panic (current->flags, "non-scheduled thread running")
|
||||||
if !current:
|
|
||||||
current = &idle
|
|
||||||
if old_current == current:
|
if old_current == current:
|
||||||
return
|
return
|
||||||
//dbg_send ((unsigned)current >> 12, 3)
|
//dbg_send ((unsigned)current >> 12, 3)
|
||||||
@ -64,6 +63,7 @@ static void handle_exit ():
|
|||||||
/// when k0 or k1 is not 0, or when an error occurs.
|
/// when k0 or k1 is not 0, or when an error occurs.
|
||||||
/// Otherwise, the ultra-fast code in entry.S is used.
|
/// Otherwise, the ultra-fast code in entry.S is used.
|
||||||
kThread *tlb_refill ():
|
kThread *tlb_refill ():
|
||||||
|
++dbg_code.h
|
||||||
old_current = current
|
old_current = current
|
||||||
if !directory:
|
if !directory:
|
||||||
unsigned addr
|
unsigned addr
|
||||||
@ -89,6 +89,7 @@ kThread *tlb_refill ():
|
|||||||
|
|
||||||
/// An interrupt which is not an exception has occurred.
|
/// An interrupt which is not an exception has occurred.
|
||||||
kThread *interrupt ():
|
kThread *interrupt ():
|
||||||
|
++dbg_code.h
|
||||||
old_current = current
|
old_current = current
|
||||||
unsigned ipr = INTC_IPR
|
unsigned ipr = INTC_IPR
|
||||||
for unsigned i = 0; i < 32; ++i:
|
for unsigned i = 0; i < 32; ++i:
|
||||||
@ -155,6 +156,7 @@ static void arch_invoke ():
|
|||||||
|
|
||||||
/// A general exception has occurred.
|
/// A general exception has occurred.
|
||||||
kThread *exception ():
|
kThread *exception ():
|
||||||
|
++dbg_code.h
|
||||||
old_current = current
|
old_current = current
|
||||||
unsigned cause
|
unsigned cause
|
||||||
cp0_get (CP0_CAUSE, cause)
|
cp0_get (CP0_CAUSE, cause)
|
||||||
@ -225,6 +227,7 @@ kThread *exception ():
|
|||||||
if !dbg_cap.valid ():
|
if !dbg_cap.valid ():
|
||||||
dpanic (0, "no log capability provided")
|
dpanic (0, "no log capability provided")
|
||||||
break
|
break
|
||||||
|
dbg_log ("log capability registered.\n")
|
||||||
break
|
break
|
||||||
dbg_log_char (current->arch.a[1])
|
dbg_log_char (current->arch.a[1])
|
||||||
#endif
|
#endif
|
||||||
@ -287,6 +290,7 @@ kThread *exception ():
|
|||||||
|
|
||||||
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
||||||
kThread *cache_error ():
|
kThread *cache_error ():
|
||||||
|
++dbg_code.h
|
||||||
panic (0x33333333, "cache error")
|
panic (0x33333333, "cache error")
|
||||||
old_current = current
|
old_current = current
|
||||||
handle_exit ()
|
handle_exit ()
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
load = 0x80000000
|
load = 0x80000000
|
||||||
|
|
||||||
ARCH_CXXFLAGS = -DNUM_THREADS=6
|
ARCH_CXXFLAGS = -DNUM_THREADS=6
|
||||||
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE #-DUSE_SERIAL
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
OBJDUMP = $(CROSS)objdump
|
OBJDUMP = $(CROSS)objdump
|
||||||
junk = mdebug.abi32 reginfo comment pdr
|
junk = mdebug.abi32 reginfo comment pdr
|
||||||
@ -30,12 +30,14 @@ boot_sources = mips/init.cc mips/nanonote/board.cc
|
|||||||
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
||||||
boot_threads = init udc nanonote-gpio buzzer metronome lcd
|
boot_threads = init udc nanonote-gpio buzzer metronome lcd
|
||||||
|
|
||||||
test: iris.raw mips/nanonote/server/usb-server
|
test: iris.raw mips/nanonote/server/usb-server mips/nanonote/sdram-setup.raw
|
||||||
echo "reboot 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8')" | nc localhost 5050
|
echo "reboot 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8')" | nc localhost 5050
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
mips/nanonote/server/usb-server: mips/nanonote/server/usb-server.ccp mips/nanonote/server/Makefile.am mips/nanonote/server/configure.ac
|
mips/nanonote/server/usb-server: mips/nanonote/server/usb-server.ccp mips/nanonote/server/Makefile.am mips/nanonote/server/configure.ac
|
||||||
$(MAKE) -C mips/nanonote/server
|
$(MAKE) -C mips/nanonote/server
|
||||||
|
echo "shutdown" | nc localhost 5050
|
||||||
|
sleep 1
|
||||||
|
|
||||||
%.elf: %.o
|
%.elf: %.o
|
||||||
$(LD) $(LDFLAGS) -o $@ $<
|
$(LD) $(LDFLAGS) -o $@ $<
|
||||||
@ -66,6 +68,10 @@ boot-programs/charset.data: boot-programs/charset
|
|||||||
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
||||||
$(LD) $(LDFLAGS) $^ -o $@
|
$(LD) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
server:
|
||||||
|
while mips/nanonote/server/usb-server ; do : ; done
|
||||||
|
|
||||||
ARCH_CLEAN_FILES = $(boot_sources) $(addsuffix .elf,$(boot_threads)) $(arch_headers) devices.hh keys.hh mips/*.o mips/nanonote/*.o boot-programs/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw
|
ARCH_CLEAN_FILES = $(boot_sources) $(addsuffix .elf,$(boot_threads)) $(arch_headers) devices.hh keys.hh mips/*.o mips/nanonote/*.o boot-programs/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw
|
||||||
|
|
||||||
.PRECIOUS: mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
.PRECIOUS: mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
||||||
|
.PHONY: server
|
||||||
|
@ -27,4 +27,7 @@ PYPP = /usr/bin/pypp
|
|||||||
%.cc: %.ccp
|
%.cc: %.ccp
|
||||||
$(PYPP) --name $< < $< > $@
|
$(PYPP) --name $< < $< > $@
|
||||||
|
|
||||||
|
run:
|
||||||
|
$(top_buiddir)/usb-server
|
||||||
|
|
||||||
BUILT_SOURCES = usb-server.cc
|
BUILT_SOURCES = usb-server.cc
|
||||||
|
@ -54,15 +54,34 @@ struct data:
|
|||||||
VR_FLUSH_CACHES = 3
|
VR_FLUSH_CACHES = 3
|
||||||
VR_PROGRAM_START1 = 4
|
VR_PROGRAM_START1 = 4
|
||||||
VR_PROGRAM_START2 = 5
|
VR_PROGRAM_START2 = 5
|
||||||
|
POLL = 10
|
||||||
void request (requests num, unsigned data = 0)
|
void request (requests num, unsigned data = 0)
|
||||||
void send_file (unsigned address, unsigned size, char const *data)
|
void send_file (unsigned address, unsigned size, char const *data)
|
||||||
void reboot ():
|
void reboot ():
|
||||||
// This always fails, because the device doesn't answer. However, that means there's nothing wrong, so don't complain.
|
char buffer[8]
|
||||||
usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VR_GET_CPU_INFO, 0, 0, NULL, 8, timeout)
|
if usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VR_GET_CPU_INFO, 0, 0, buffer, 8, timeout) < 0:
|
||||||
|
std::cerr << "unable to send reboot message to device: " << usb_strerror () << std::endl
|
||||||
usb_release_interface (handle, 0)
|
usb_release_interface (handle, 0)
|
||||||
usb_close (handle)
|
usb_close (handle)
|
||||||
handle = NULL
|
handle = NULL
|
||||||
void get_device (unsigned vendor, unsigned product, unsigned tries)
|
void get_device (unsigned vendor, unsigned product, unsigned tries)
|
||||||
|
void poll ()
|
||||||
|
|
||||||
|
void data::poll ():
|
||||||
|
while true:
|
||||||
|
char buffer[2]
|
||||||
|
int s = usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, POLL, 0, 0, buffer, 8, timeout)
|
||||||
|
if s < 1 || s > 2 || buffer[0] != '#':
|
||||||
|
std::cerr << "unable to send poll message to device: " << usb_strerror () << std::endl
|
||||||
|
usb_release_interface (handle, 0)
|
||||||
|
usb_close (handle)
|
||||||
|
handle = NULL
|
||||||
|
return
|
||||||
|
if s != 1:
|
||||||
|
std::cout << buffer[1] << std::flush
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
(shevek::absolute_time () + shevek::relative_time (1, 0)).schedule (sigc::mem_fun (*this, &data::poll))
|
||||||
|
|
||||||
struct client : public shevek::server <client, data *>::connection:
|
struct client : public shevek::server <client, data *>::connection:
|
||||||
static Glib::RefPtr <client> create ():
|
static Glib::RefPtr <client> create ():
|
||||||
@ -75,6 +94,9 @@ struct client : public shevek::server <client, data *>::connection:
|
|||||||
unsigned entry
|
unsigned entry
|
||||||
if l ("reboot %x%", entry):
|
if l ("reboot %x%", entry):
|
||||||
get_server ()->data ()->boot (entry)
|
get_server ()->data ()->boot (entry)
|
||||||
|
else if l ("shutdown%"):
|
||||||
|
std::cerr << "shutting down\n"
|
||||||
|
shevek::end_loop ()
|
||||||
else:
|
else:
|
||||||
out->write ("invalid command\n")
|
out->write ("invalid command\n")
|
||||||
if !keep:
|
if !keep:
|
||||||
@ -112,10 +134,11 @@ void data::get_device (unsigned vendor, unsigned product, unsigned tries):
|
|||||||
continue
|
continue
|
||||||
handle = usb_open (dev)
|
handle = usb_open (dev)
|
||||||
if usb_claim_interface (handle, 0) < 0:
|
if usb_claim_interface (handle, 0) < 0:
|
||||||
std::cerr << "unable to claim interface\n"
|
std::cerr << "unable to claim interface: " << usb_strerror () << "\n"
|
||||||
usb_close (handle)
|
usb_close (handle)
|
||||||
handle = NULL
|
handle = NULL
|
||||||
continue
|
continue
|
||||||
|
(shevek::absolute_time () + shevek::relative_time (1, 0)).schedule (sigc::mem_fun (*this, &data::poll))
|
||||||
return
|
return
|
||||||
if i + 1 < tries:
|
if i + 1 < tries:
|
||||||
//std::cerr << "failed to find device, still trying...\n"
|
//std::cerr << "failed to find device, still trying...\n"
|
||||||
|
@ -25,7 +25,7 @@ thread0:
|
|||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread1:
|
thread1:
|
||||||
.incbin "lcd.elf"
|
.incbin "udc.elf"
|
||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread2:
|
thread2:
|
||||||
@ -41,8 +41,9 @@ thread4:
|
|||||||
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
thread5:
|
thread5:
|
||||||
.incbin "udc.elf"
|
.incbin "lcd.elf"
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
thread6:
|
thread6:
|
||||||
|
|
||||||
// Everything from here may be freed after kernel initialization.
|
// Everything from here may be freed after kernel initialization.
|
||||||
|
@ -31,6 +31,7 @@ thread1:
|
|||||||
thread2:
|
thread2:
|
||||||
.incbin "gpio.elf"
|
.incbin "gpio.elf"
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
thread3:
|
thread3:
|
||||||
|
|
||||||
// Everything from here may be freed after kernel initialization.
|
// Everything from here may be freed after kernel initialization.
|
||||||
|
@ -25,7 +25,7 @@ void dbg_log_char (unsigned ch):
|
|||||||
UART0_TDR = ch
|
UART0_TDR = ch
|
||||||
#else
|
#else
|
||||||
void dbg_log_char (unsigned ch):
|
void dbg_log_char (unsigned ch):
|
||||||
if !dbg_cap.valid ():
|
if !dbg_cap.valid () || dbg_code.l:
|
||||||
return
|
return
|
||||||
kCapability::Context c
|
kCapability::Context c
|
||||||
c.data[0] = ch
|
c.data[0] = ch
|
||||||
@ -63,6 +63,8 @@ void panic_impl (unsigned n, unsigned line, char const *name, char const *messag
|
|||||||
#endif
|
#endif
|
||||||
// Use the (now running) log thread to display the message.
|
// Use the (now running) log thread to display the message.
|
||||||
dbg_log ("Panic: caller = ")
|
dbg_log ("Panic: caller = ")
|
||||||
|
dbg_log_num (old_current->id, 2)
|
||||||
|
dbg_log (":")
|
||||||
dbg_log_num ((unsigned)old_current)
|
dbg_log_num ((unsigned)old_current)
|
||||||
if old_current:
|
if old_current:
|
||||||
dbg_log_char ('@')
|
dbg_log_char ('@')
|
||||||
@ -75,6 +77,8 @@ void panic_impl (unsigned n, unsigned line, char const *name, char const *messag
|
|||||||
dbg_log (message)
|
dbg_log (message)
|
||||||
dbg_log_char ('/')
|
dbg_log_char ('/')
|
||||||
dbg_log_num (n)
|
dbg_log_num (n)
|
||||||
|
dbg_log_char (';')
|
||||||
|
dbg_log_num (dbg_code.h)
|
||||||
dbg_log (" bad vaddr = ")
|
dbg_log (" bad vaddr = ")
|
||||||
unsigned a
|
unsigned a
|
||||||
cp0_get (CP0_BAD_V_ADDR, a)
|
cp0_get (CP0_BAD_V_ADDR, a)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user