fixed arm register saving/restoring 3ds9 is broken rn
This commit is contained in:
parent
d14a3e5919
commit
9fcc1f0950
5 changed files with 105 additions and 30 deletions
|
@ -7,6 +7,11 @@ PICAfb term;
|
|||
void main();
|
||||
extern "C" void start() { main(); }
|
||||
void drivers_init() {
|
||||
term << "initing main tty\n";
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
term << "Initing vectors\n";
|
||||
initVectors();
|
||||
term << "trying svc\n";
|
||||
asm volatile("svc #0");
|
||||
}
|
||||
|
|
|
@ -86,6 +86,11 @@ _start:
|
|||
orr r0, r0, #(1<<0)
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
*/
|
||||
//Certain bootloaders put the interrupt vectors in ITCM.
|
||||
//We don't want to mess with ITCM, so we put it back
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
orr r0, #(1<<13)
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
//Start start
|
||||
blx start
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "include/regs.h"
|
||||
#include <base.hpp>
|
||||
#include <regs.hpp>
|
||||
void print_regdump(cpu_state *state) {
|
||||
(*out << "r0: ").puti(state->r0);
|
||||
(*out << " r1: ").puti(state->r1);
|
||||
|
@ -7,4 +7,42 @@ void print_regdump(cpu_state *state) {
|
|||
(*out << " r3: ").puti(state->r3);
|
||||
(*out << " r4: ").puti(state->r4);
|
||||
(*out << " r5: ").puti(state->r5);
|
||||
(*out << " r6: ").puti(state->r6);
|
||||
(*out << " r7: ").puti(state->r7);
|
||||
(*out << " r8: ").puti(state->r8);
|
||||
(*out << " r9: ").puti(state->r9);
|
||||
(*out << " r10: ").puti(state->r10);
|
||||
(*out << " r11: ").puti(state->r11);
|
||||
(*out << " r12: ").puti(state->r12);
|
||||
(*out << " pc: ").puti(state->pc);
|
||||
*out << "\n";
|
||||
}
|
||||
extern "C" cpu_state *handleINT(int number, cpu_state *state) {
|
||||
*out << "Interrupt";
|
||||
out->puti(number);
|
||||
*out << " occurred!\n";
|
||||
if (number != 4) {
|
||||
out->setColor(Color::RED);
|
||||
print_regdump(state);
|
||||
*out << "KERNEL PANIC: Unhandled CPU exception\n";
|
||||
// for(;;);
|
||||
}
|
||||
switch (number) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if (state->cpsr & 0x20)
|
||||
state->returnAddr -= 2;
|
||||
else
|
||||
state->returnAddr -= 4;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
extern "C" void panic2(char *msg, cpu_state *state) {
|
||||
out->setColor(Color::RED);
|
||||
*out << "KERNEL PANIC: " << msg << "\n";
|
||||
print_regdump(state);
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -2,49 +2,74 @@ int_handler.write(
|
|||
"""\
|
||||
.arm
|
||||
.fpu vfpv2
|
||||
.section .bss
|
||||
.space 4096
|
||||
exception_stack:
|
||||
.section .text
|
||||
.global branch_macro
|
||||
branch_macro:
|
||||
ldr pc, [pc, #-4] //Load the next word into PC
|
||||
.macro interrupt_handler intid
|
||||
//Set to the correct stack
|
||||
ldr sp, =exception_stack
|
||||
push {r0-r12,lr} //Push registers
|
||||
|
||||
//Get previous sp and lr
|
||||
mrs r1, cpsr //Current mode
|
||||
mrs r0, spsr //Previous mode
|
||||
orr r0, #0xC0 //Disable interrupts in the previous mode
|
||||
bic r0, #0x20 //enable ARM mode in there
|
||||
|
||||
//If the mode is user, switch to system mode
|
||||
and r2, r0, #0x1F
|
||||
cmp r2, #0x10
|
||||
bne 1f
|
||||
orr r0, #0x1F
|
||||
1:
|
||||
//Change mode
|
||||
msr cpsr, r0
|
||||
mov r2, sp
|
||||
mov r3, lr
|
||||
//Switch back
|
||||
msr cpsr, r1
|
||||
mrs r0, spsr
|
||||
|
||||
//Push those registers
|
||||
push {r0, r2, r3, lr}
|
||||
|
||||
//Set argument 1
|
||||
ldr r0, =\intid
|
||||
|
||||
//Jump to generic handler
|
||||
blx intr_common_handler
|
||||
|
||||
//pop the special registers
|
||||
pop {r0, r3, r4, lr}
|
||||
tst r0, #0x20 //Is code ARM or thumb?
|
||||
beq 2f
|
||||
orr lr, lr, #1 //Enable thumb mode on return#
|
||||
2:
|
||||
str lr, [sp, #0x34] //Set correct lr
|
||||
ldmfd sp!, {r0-r12, pc}^ //Return back to original mode
|
||||
.endm
|
||||
.global data_abort
|
||||
data_abort:
|
||||
sub lr, #4
|
||||
push {r0-r12,lr}
|
||||
ldr r0, =0
|
||||
blx intr_common_handler
|
||||
pop {r0-r12,pc}
|
||||
interrupt_handler 0
|
||||
.global fast_irq
|
||||
fast_irq:
|
||||
sub lr, #4
|
||||
push {r0-r12,lr}
|
||||
ldr r0, =1
|
||||
blx intr_common_handler
|
||||
pop {r0-r12,pc}
|
||||
interrupt_handler 1
|
||||
.global normal_irq
|
||||
normal_irq:
|
||||
sub lr, #4
|
||||
push {r0-r12,lr}
|
||||
ldr r0, =2
|
||||
blx intr_common_handler
|
||||
pop {r0-r12,pc}
|
||||
interrupt_handler 2
|
||||
.global prefetch_abort
|
||||
prefetch_abort:
|
||||
sub lr, #4
|
||||
push {r0-r12,lr}
|
||||
ldr r0, =3
|
||||
blx intr_common_handler
|
||||
pop {r0-r12,pc}
|
||||
interrupt_handler 3
|
||||
.global svc_call
|
||||
svc_call:
|
||||
push {r0-r12,lr}
|
||||
ldr r0, =4
|
||||
blx intr_common_handler
|
||||
pop {r0-r12,pc}
|
||||
interrupt_handler 4
|
||||
.global undefined_op
|
||||
undefined_op:
|
||||
push {r0-r12,lr}
|
||||
ldr r0, =5
|
||||
blx intr_common_handler
|
||||
pop {r0-r12,pc}
|
||||
interrupt_handler 5
|
||||
|
||||
.extern handleINT
|
||||
intr_common_handler:
|
||||
|
@ -81,6 +106,8 @@ if ("ENABLE_HARD" in config) and config["ENABLE_HARD"]:
|
|||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for reg in ("d"+str(i) for i in range(16)):
|
||||
reg_struct.write(" double "+reg+";\n")
|
||||
for reg in ["cpsr","sp","lr","returnAddr"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for i in range(13):
|
||||
reg_struct.write(" uint32_t r"+str(i)+";\n")
|
||||
reg_struct.write(" uint32_t pc;\n};")
|
||||
|
|
|
@ -9,7 +9,7 @@ void svc_call();
|
|||
void undefined_op();
|
||||
}
|
||||
void initVectors() {
|
||||
uintptr_t *vectors = (uintptr_t *)0x08000000;
|
||||
uintptr_t *vectors = (uintptr_t *)0x0800000;
|
||||
// branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC
|
||||
vectors[0] = branch_macro;
|
||||
vectors[1] = (uintptr_t)&normal_irq;
|
||||
|
|
Loading…
Reference in a new issue