mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
bug hunting
This commit is contained in:
@@ -166,6 +166,9 @@ static void tlb_reset (unsigned address, unsigned asid, unsigned value):
|
||||
__asm__ volatile ("tlbwi")
|
||||
|
||||
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:
|
||||
p->prev_mapped->next_mapped = p->next_mapped
|
||||
else:
|
||||
|
||||
@@ -119,6 +119,9 @@ static void init_threads ():
|
||||
kMemory *mem = top_memory.alloc_memory ()
|
||||
assert (mem)
|
||||
kThread *thread = mem->alloc_thread (NUM_SLOTS)
|
||||
#ifndef NDEBUG
|
||||
thread->id = i
|
||||
#endif
|
||||
kPage **pages = (kPage **)mem->zalloc ()
|
||||
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
|
||||
for unsigned j = 0; j < SELFMAG; ++j:
|
||||
@@ -150,12 +153,21 @@ static void init_threads ():
|
||||
//bool executable = shdr->sh_flags & SHF_EXEC_INSTR
|
||||
if shdr->sh_type != SHT_NOBITS:
|
||||
unsigned file_offset = shdr->sh_offset >> PAGE_BITS
|
||||
if ((file_offset + shdr->sh_size) >> PAGE_BITS) >= (PAGE_SIZE >> 2):
|
||||
if (file_offset + ((shdr->sh_size + PAGE_SIZE - 1) >> PAGE_BITS)) >= (PAGE_SIZE >> 2):
|
||||
panic (0x87446809, "initial thread too large")
|
||||
return
|
||||
for unsigned p = (shdr->sh_addr & PAGE_MASK); p < shdr->sh_addr + shdr->sh_size; p += PAGE_SIZE:
|
||||
unsigned section_offset = (p - (shdr->sh_addr & PAGE_MASK)) >> PAGE_BITS
|
||||
unsigned idx = file_offset + section_offset
|
||||
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]:
|
||||
pages[idx] = mem->alloc_page ()
|
||||
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))
|
||||
|
||||
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).
|
||||
must_wait = false
|
||||
if !current || (current == &idle):
|
||||
schedule ()
|
||||
if !current:
|
||||
current = &idle
|
||||
if (current->flags & (Kernel::Thread::RUNNING | Kernel::Thread::WAITING)) != Kernel::Thread::RUNNING:
|
||||
panic (current->flags, "non-scheduled thread running")
|
||||
if !current:
|
||||
current = &idle
|
||||
//if (current->flags & (Kernel::Thread::RUNNING | Kernel::Thread::WAITING)) != Kernel::Thread::RUNNING:
|
||||
//panic (current->flags, "non-scheduled thread running")
|
||||
if old_current == current:
|
||||
return
|
||||
//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.
|
||||
/// Otherwise, the ultra-fast code in entry.S is used.
|
||||
kThread *tlb_refill ():
|
||||
++dbg_code.h
|
||||
old_current = current
|
||||
if !directory:
|
||||
unsigned addr
|
||||
@@ -89,6 +89,7 @@ kThread *tlb_refill ():
|
||||
|
||||
/// An interrupt which is not an exception has occurred.
|
||||
kThread *interrupt ():
|
||||
++dbg_code.h
|
||||
old_current = current
|
||||
unsigned ipr = INTC_IPR
|
||||
for unsigned i = 0; i < 32; ++i:
|
||||
@@ -155,6 +156,7 @@ static void arch_invoke ():
|
||||
|
||||
/// A general exception has occurred.
|
||||
kThread *exception ():
|
||||
++dbg_code.h
|
||||
old_current = current
|
||||
unsigned cause
|
||||
cp0_get (CP0_CAUSE, cause)
|
||||
@@ -225,6 +227,7 @@ kThread *exception ():
|
||||
if !dbg_cap.valid ():
|
||||
dpanic (0, "no log capability provided")
|
||||
break
|
||||
dbg_log ("log capability registered.\n")
|
||||
break
|
||||
dbg_log_char (current->arch.a[1])
|
||||
#endif
|
||||
@@ -287,6 +290,7 @@ kThread *exception ():
|
||||
|
||||
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
||||
kThread *cache_error ():
|
||||
++dbg_code.h
|
||||
panic (0x33333333, "cache error")
|
||||
old_current = current
|
||||
handle_exit ()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
load = 0x80000000
|
||||
|
||||
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-
|
||||
OBJDUMP = $(CROSS)objdump
|
||||
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
|
||||
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
|
||||
.PHONY: test
|
||||
|
||||
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
|
||||
echo "shutdown" | nc localhost 5050
|
||||
sleep 1
|
||||
|
||||
%.elf: %.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))
|
||||
$(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
|
||||
|
||||
.PRECIOUS: mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
||||
.PHONY: server
|
||||
|
||||
@@ -27,4 +27,7 @@ PYPP = /usr/bin/pypp
|
||||
%.cc: %.ccp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
|
||||
run:
|
||||
$(top_buiddir)/usb-server
|
||||
|
||||
BUILT_SOURCES = usb-server.cc
|
||||
|
||||
@@ -54,15 +54,34 @@ struct data:
|
||||
VR_FLUSH_CACHES = 3
|
||||
VR_PROGRAM_START1 = 4
|
||||
VR_PROGRAM_START2 = 5
|
||||
POLL = 10
|
||||
void request (requests num, unsigned data = 0)
|
||||
void send_file (unsigned address, unsigned size, char const *data)
|
||||
void reboot ():
|
||||
// This always fails, because the device doesn't answer. However, that means there's nothing wrong, so don't complain.
|
||||
usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VR_GET_CPU_INFO, 0, 0, NULL, 8, timeout)
|
||||
char buffer[8]
|
||||
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_close (handle)
|
||||
handle = NULL
|
||||
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:
|
||||
static Glib::RefPtr <client> create ():
|
||||
@@ -75,6 +94,9 @@ struct client : public shevek::server <client, data *>::connection:
|
||||
unsigned entry
|
||||
if l ("reboot %x%", entry):
|
||||
get_server ()->data ()->boot (entry)
|
||||
else if l ("shutdown%"):
|
||||
std::cerr << "shutting down\n"
|
||||
shevek::end_loop ()
|
||||
else:
|
||||
out->write ("invalid command\n")
|
||||
if !keep:
|
||||
@@ -112,10 +134,11 @@ void data::get_device (unsigned vendor, unsigned product, unsigned tries):
|
||||
continue
|
||||
handle = usb_open (dev)
|
||||
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)
|
||||
handle = NULL
|
||||
continue
|
||||
(shevek::absolute_time () + shevek::relative_time (1, 0)).schedule (sigc::mem_fun (*this, &data::poll))
|
||||
return
|
||||
if i + 1 < tries:
|
||||
//std::cerr << "failed to find device, still trying...\n"
|
||||
|
||||
@@ -25,7 +25,7 @@ thread0:
|
||||
|
||||
.balign 0x1000
|
||||
thread1:
|
||||
.incbin "lcd.elf"
|
||||
.incbin "udc.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread2:
|
||||
@@ -41,8 +41,9 @@ thread4:
|
||||
|
||||
.balign 0x1000
|
||||
thread5:
|
||||
.incbin "udc.elf"
|
||||
.incbin "lcd.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread6:
|
||||
|
||||
// Everything from here may be freed after kernel initialization.
|
||||
|
||||
@@ -31,6 +31,7 @@ thread1:
|
||||
thread2:
|
||||
.incbin "gpio.elf"
|
||||
|
||||
.balign 0x1000
|
||||
thread3:
|
||||
|
||||
// Everything from here may be freed after kernel initialization.
|
||||
|
||||
Reference in New Issue
Block a user