mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-30 23:24:19 +01:00
Add exception handler. This one *does* work!
This commit is contained in:
parent
26816ee411
commit
debfa55f86
3
Makefile
3
Makefile
@ -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
87
exception.c
Normal 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
7
exception.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef __EXCEPTION_H__
|
||||||
|
#define __EXCEPTION_H__
|
||||||
|
|
||||||
|
void exception_initialize(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
124
exception_asm.S
Normal file
124
exception_asm.S
Normal 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
5
main.c
@ -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);
|
||||||
|
15
miniios.ld
15
miniios.ld
@ -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
27
start.S
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user