Add exception handler. This one *does* work!

This commit is contained in:
marcan 2009-01-16 08:53:57 +01:00 committed by bushing
parent 26816ee411
commit debfa55f86
7 changed files with 244 additions and 24 deletions

View File

@ -11,7 +11,8 @@ MAKEBIN = python ../makebin.py
TARGET = miniios.bin TARGET = miniios.bin
ELF = miniios.elf ELF = miniios.elf
OBJECTS = start.o ipcstruct.o main.o ipc.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ OBJECTS = start.o ipcstruct.o main.o ipc.o vsprintf.o string.o gecko.o memory.o memory_asm.o \
utils_asm.o utils.o ff.o diskio.o sdhc.o powerpc_elf.o powerpc.o panic.o irq.o irq_asm.o utils_asm.o utils.o ff.o diskio.o sdhc.o powerpc_elf.o powerpc.o panic.o irq.o irq_asm.o \
exception.o exception_asm.o
$(TARGET) : $(ELF) $(ELFLOADER) $(TARGET) : $(ELF) $(ELFLOADER)
@echo "MAKEBIN $@" @echo "MAKEBIN $@"

87
exception.c Normal file
View File

@ -0,0 +1,87 @@
#include "irq.h"
#include "hollywood.h"
#include "gecko.h"
#include "utils.h"
#include "ipc.h"
#include "memory.h"
const char *exceptions[] = {
"RESET", "UNDEFINED", "SWI", "INSTR ABORT", "DATA ABORT", "RESERVED", "IRQ", "FIQ"
};
const char *aborts[] = {
"UNDEFINED",
"Alignment",
"UNDEFINED",
"Alignment",
"UNDEFINED",
"Translation",
"UNDEFINED",
"Translation",
"External abort",
"Domain",
"External abort",
"Domain",
"External abort on translation (first level)",
"Permission",
"External abort on translation (second level)",
"Permission"
};
u8 domvalid[] = {0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,1};
void exc_setup_stack(void);
void exception_initialize(void)
{
exc_setup_stack();
u32 cr = get_cr();
cr |= 0x2; // Data alignment fault checking enable
set_cr(cr);
}
void exc_handler(u32 type, u32 spsr, u32 *regs)
{
gecko_printf("\nException %d (%s):\n", type, exceptions[type]);
u32 pc;
switch(type) {
case 3:
case 7:
pc = regs[15] - 4;
break;
case 4:
pc = regs[15] - 8;
break;
default:
pc = regs[15];
break;
}
gecko_printf("Registers (%p):\n", regs);
gecko_printf(" R0-R3: %08x %08x %08x %08x\n", regs[0], regs[1], regs[2], regs[3]);
gecko_printf(" R4-R7: %08x %08x %08x %08x\n", regs[4], regs[5], regs[6], regs[7]);
gecko_printf(" R8-R11: %08x %08x %08x %08x\n", regs[8], regs[9], regs[10], regs[11]);
gecko_printf("R12-R15: %08x %08x %08x %08x\n", regs[12], regs[13], regs[14], pc);
gecko_printf("SPSR: %08x\n", spsr);
gecko_printf("CR: %08x\n", get_cr());
gecko_printf("TTBR: %08x\n", get_ttbr());
gecko_printf("DACR: %08x\n", get_dacr());
if(type == 3 || type == 4) {
u32 fsr;
if(type == 3)
fsr = get_ifsr();
else
fsr = get_dfsr();
gecko_printf("Abort type: %s\n", aborts[fsr&0xf]);
if(domvalid[fsr&0xf])
gecko_printf("Domain: %d\n", (fsr>>4)&0xf);
if(type == 4)
gecko_printf("Address: 0x%08x\n", get_far());
}
panic(0xA3);
}

7
exception.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef __EXCEPTION_H__
#define __EXCEPTION_H__
void exception_initialize(void);
#endif

124
exception_asm.S Normal file
View File

@ -0,0 +1,124 @@
.globl v_undf
.globl v_swi
.globl v_instr_abrt
.globl v_data_abrt
.globl v_reserved
.globl v_fiq
.globl exc_setup_stack
.extern __excstack_addr
.extern exc_handler
exc_setup_stack:
mrs r0, cpsr
@ Switch to FIQ mode
msr cpsr_c, #0xd1
@ Setup exception stack
ldr sp, =__excstack_addr
@ Switch to SVC mode
msr cpsr_c, #0xd3
@ Setup exception stack
ldr sp, =__excstack_addr
@ Switch to ABORT mode
msr cpsr_c, #0xd7
@ Setup exception stack
ldr sp, =__excstack_addr
@ Switch to UNDF mode
msr cpsr_c, #0xdb
@ Setup exception stack
ldr sp, =__excstack_addr
@ Restore mode
msr cpsr_c, r0
bx lr
.pool
v_undf:
stmfd sp!, {lr}
stmfd sp, {r0-lr}^
sub sp, sp, #0x3c
mov r2, sp
mrs r1, spsr
mov r0, #1
blx exc_handler
ldmfd sp!, {r0-r12}
add sp, sp, #8
movs pc, lr
v_swi:
stmfd sp!, {lr}
stmfd sp, {r0-lr}^
sub sp, sp, #0x3c
mov r2, sp
mrs r1, spsr
mov r0, #2
blx exc_handler
ldmfd sp!, {r0-r12}
add sp, sp, #8
movs pc, lr
v_instr_abrt:
stmfd sp!, {lr}
stmfd sp, {r0-lr}^
sub sp, sp, #0x3c
mov r2, sp
mrs r1, spsr
mov r0, #3
blx exc_handler
ldmfd sp!, {r0-r12}
add sp, sp, #8
subs pc, lr, #4
v_data_abrt:
stmfd sp!, {lr}
stmfd sp, {r0-lr}^
sub sp, sp, #0x3c
mov r2, sp
mrs r1, spsr
mov r0, #4
blx exc_handler
ldmfd sp!, {r0-r12}
add sp, sp, #8
subs pc, lr, #8
v_reserved:
stmfd sp!, {lr}
stmfd sp, {r0-lr}^
sub sp, sp, #0x3c
mov r2, sp
mrs r1, spsr
mov r0, #5
blx exc_handler
ldmfd sp!, {r0-r12}
add sp, sp, #8
movs pc, lr
v_fiq:
stmfd sp!, {lr}
stmfd sp, {r0-lr}^
sub sp, sp, #0x3c
mov r2, sp
mrs r1, spsr
mov r0, #7
blx exc_handler
ldmfd sp!, {r0-r12}
add sp, sp, #8
subs pc, lr, #4

5
main.c
View File

@ -12,6 +12,7 @@
#include "powerpc_elf.h" #include "powerpc_elf.h"
#include "irq.h" #include "irq.h"
#include "ipc.h" #include "ipc.h"
#include "exception.h"
void *vector; void *vector;
@ -150,11 +151,11 @@ void *_main(void *base)
gecko_init(); gecko_init();
gecko_puts("MiniIOS v0.1 loading\n"); gecko_puts("MiniIOS v0.1 loading\n");
gecko_puts("Initializing exceptions...\n");
exception_initialize();
gecko_puts("Configuring caches and MMU...\n"); gecko_puts("Configuring caches and MMU...\n");
mem_initialize(); mem_initialize();
irq_initialize(); irq_initialize();
irq_enable(IRQ_TIMER); irq_enable(IRQ_TIMER);
irq_enable(IRQ_NAND); irq_enable(IRQ_NAND);

View File

@ -5,6 +5,7 @@ ENTRY(_start)
__stack_size = 0x800; __stack_size = 0x800;
__irqstack_size = 0x100; __irqstack_size = 0x100;
__excstack_size = 0x100;
MEMORY { MEMORY {
sram : ORIGIN = 0xffff0000, LENGTH = 64K sram : ORIGIN = 0xffff0000, LENGTH = 64K
@ -103,14 +104,28 @@ SECTIONS
. = . +__irqstack_size; . = . +__irqstack_size;
. = ALIGN(64); . = ALIGN(64);
__irqstack_addr = .; __irqstack_addr = .;
__excstack_end = .;
. = . +__excstack_size;
. = ALIGN(64);
__excstack_addr = .;
} >sram2
.pagetable :
{
. = ALIGN(16384);
__page_table = .;
. = . + 16384;
} >sram2 } >sram2
} }
PROVIDE (__page_table = __page_table);
PROVIDE (__stack_end = __stack_end); PROVIDE (__stack_end = __stack_end);
PROVIDE (__stack_addr = __stack_addr); PROVIDE (__stack_addr = __stack_addr);
PROVIDE (__irqstack_end = __irqstack_end); PROVIDE (__irqstack_end = __irqstack_end);
PROVIDE (__irqstack_addr = __irqstack_addr); PROVIDE (__irqstack_addr = __irqstack_addr);
PROVIDE (__excstack_end = __excstack_end);
PROVIDE (__excstack_addr = __excstack_addr);
PROVIDE (__bss_start = __bss_start); PROVIDE (__bss_start = __bss_start);
PROVIDE (__bss_end = __bss_end); PROVIDE (__bss_end = __bss_end);
PROVIDE (__bss2_start = __bss2_start); PROVIDE (__bss2_start = __bss2_start);

27
start.S
View File

@ -11,7 +11,13 @@
.globl _start .globl _start
.globl debug_output .globl debug_output
.extern v_undf
.extern v_swi
.extern v_instr_abrt
.extern v_data_abrt
.extern v_reserved
.extern v_irq .extern v_irq
.extern v_fiq
.section .init .section .init
@ -80,27 +86,6 @@ done_bss2:
.pool .pool
v_undf:
b v_undf
v_swi:
b v_swi
v_instr_abrt:
b v_instr_abrt
v_data_abrt:
b v_data_abrt
v_reserved:
b v_reserved
#v_irq:
# b v_irq
v_fiq:
b v_fiq
debug_output: debug_output:
@ load address of port @ load address of port
mov r3, #0xd800000 mov r3, #0xd800000