got IRQs working on 3ds9

This commit is contained in:
Morten Delenk 2017-07-29 09:53:39 +01:00
parent 7d6c2a0dd1
commit 3a60a712b2
11 changed files with 78 additions and 134 deletions

View file

@ -13,8 +13,7 @@ void drivers_init() {
pmm=(PMM*)(&lpmm); pmm=(PMM*)(&lpmm);
setMainTTY(&term); setMainTTY(&term);
--term; --term;
initVectors();
*((volatile uint32_t*)0x17E00600)=67108; *((volatile uint32_t*)0x17E00600)=67108;
*((volatile uint32_t*)0x17E00608=3; *((volatile uint32_t*)0x17E00608)=3;
asm volatile("CPSIE aif"); asm volatile("CPSIE aif");
} }

View file

@ -14,19 +14,19 @@ _start:
mov r1, r2 mov r1, r2
orr r1, #0b10001 //FIQ orr r1, #0b10001 //FIQ
msr cpsr, r1 msr cpsr, r1
ldr sp, =interrupt_stack ldr sp, =fiq_stack
mov r1, r2 mov r1, r2
orr r1, #0b10010 //IRQ orr r1, #0b10010 //IRQ
msr cpsr, r1 msr cpsr, r1
ldr sp, =interrupt_stack ldr sp, =irq_stack
mov r1, r2 mov r1, r2
orr r1, #0b10111 //Abort orr r1, #0b10111 //Abort
msr cpsr, r1 msr cpsr, r1
ldr sp, =exception_stack ldr sp, =abt_stack
mov r1, r2 mov r1, r2
orr r1, #0b11011 //Undefined orr r1, #0b11011 //Undefined
msr cpsr, r1 msr cpsr, r1
ldr sp, =exception_stack ldr sp, =und_stack
orr r1, #0b11111 //SYS orr r1, #0b11111 //SYS
msr cpsr, r1 msr cpsr, r1
ldr sp, =kernel_stack ldr sp, =kernel_stack
@ -46,10 +46,14 @@ _start:
.section .bss .section .bss
.align 16 .align 16
.space 4096 .space 4096
interrupt_stack: irq_stack:
.space 4096 .space 4096
exception_stack: fiq_stack:
.space 4096
abt_stack:
.space 4096
und_stack:
.space 4096 .space 4096
svc_stack: svc_stack:
.space 16384 .space 4096
kernel_stack: kernel_stack:

View file

@ -8,6 +8,7 @@
PICAfb term; PICAfb term;
PMM_MMAP lpmm; PMM_MMAP lpmm;
void main(); void main();
extern "C" void enable_irqs();
extern "C" void start() { main(); extern "C" void start() { main();
for(;;); for(;;);
} }
@ -15,11 +16,10 @@ void drivers_init() {
pmm=(PMM*)(&lpmm); pmm=(PMM*)(&lpmm);
setMainTTY(&term); setMainTTY(&term);
--term; --term;
initVectors();
//Init 1000Hz timer //Init 1000Hz timer
enable_irqs();
*((volatile uint16_t*)0x10003002)=0; *((volatile uint16_t*)0x10003002)=0;
*((volatile uint16_t*)0x10003000)=65; *((volatile uint16_t*)0x10003000)=65;
*((volatile uint16_t*)0x10003002)=0b11000011; *((volatile uint16_t*)0x10003002)=0b11000011;
*((volatile uint32_t*)0x10001000)|=1<<8; *((volatile uint32_t*)0x10001000)|=1<<8;
asm volatile("CPSIE aif");
} }

View file

@ -4,29 +4,9 @@
.section .text.boot .section .text.boot
_start: _start:
mrs r0, cpsr mrs r0, cpsr
orr r0, r0, #0x80 orr r0, r0, #0b111000000
msr cpsr_c, r0 //Disable IRQs msr cpsr_c, r0 //Disable IRQs
/* //Flush instruction cache
mov r0, #0
mcr p15, 0, r0, c7, c5, 0
//Use nintendos data cache flusher here, because I don't want to reverse it
ldr r0, =0xFFFF0830
blx r0
//Disable caches and MPU
mrc p15, 0, r0, c1, c0, 0 //read
bic r0, r0, #(1<<12) //Disable instruction cache
bic r0, r0, #(1<<2) //Disable data cache
bic r0, r0, #(1<<0) //disable mpu
mcr p15, 0, r0, c1, c0, 0 //write
//clear caches again
mov r0, #0
mcr p15, 0, r0, c7, c5, 0
ldr r0, =0xFFFF0830
blx r0
*/
ldr sp, =kernel_stack //set stack ldr sp, =kernel_stack //set stack
//Set other stacks //Set other stacks
mrs r0, cpsr mrs r0, cpsr
@ -34,19 +14,19 @@ _start:
mov r1, r2 mov r1, r2
orr r1, #0b10001 //FIQ orr r1, #0b10001 //FIQ
msr cpsr, r1 msr cpsr, r1
ldr sp, =interrupt_stack ldr sp, =fiq_stack
mov r1, r2 mov r1, r2
orr r1, #0b10010 //IRQ orr r1, #0b10010 //IRQ
msr cpsr, r1 msr cpsr, r1
ldr sp, =interrupt_stack ldr sp, =irq_stack
mov r1, r2 mov r1, r2
orr r1, #0b10111 //Abort orr r1, #0b10111 //Abort
msr cpsr, r1 msr cpsr, r1
ldr sp, =exception_stack ldr sp, =abt_stack
mov r1, r2 mov r1, r2
orr r1, #0b11011 //Undefined orr r1, #0b11011 //Undefined
msr cpsr, r1 msr cpsr, r1
ldr sp, =exception_stack ldr sp, =und_stack
mov r1, r2 mov r1, r2
orr r1, #0b10011 //SVC orr r1, #0b10011 //SVC
msr cpsr, r1 msr cpsr, r1
@ -54,64 +34,7 @@ _start:
orr r1, #0b11111 //SYS orr r1, #0b11111 //SYS
msr cpsr, r1 msr cpsr, r1
ldr sp, =kernel_stack ldr sp, =kernel_stack
/*
//Configure ITCM tosomething
mrc p15, 0, r0, c9, c1, 1
bic r0, #0b111110
orr r0, #0b100010
mcr p15, 0, r0, c9, c1, 1
//Configure DTCM to address 0x30000000
mrc p15, 0, r0, c9, c1, 0
bic r0, #0b111110
orr r0, #0b001010
ldr r1, =0xFFFFF000
bic r0, r1
ldr r1, =0x30000000
orr r0, r1
mcr p15, 0, r0, c9, c1, 0
//Enable both
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<18)
bic r0, r0, #(1<<17)
orr r0, r0, #(1<<16)
mcr p15, 0, r0, c1, c0, 0
//Give RW permissions to all memory regions
ldr r0, =0x33333333
mcr p15, 0, r0, c5, c0, 2 //Write Data
mcr p15, 0, r0, c5, c0, 3 //Write instructions
//Set MPU and caching
ldr r0, =0xFFFF001F // ffff0000 64k bootrom
ldr r1, =0x3000001B // 30000000 16k dtcm
ldr r2, =0x00000035 // 00000000 128M ITCM
ldr r3, =0x08000029 // 08000000 2M arm9 mem
ldr r4, =0x10000029 // 10000000 2M IO mem
ldr r5, =0x20000037 // 20000000 256M fcram
ldr r6, =0x1FF00027 // 1FF00000 1M DSP
ldr r7, =0x1800002D // 18000000 8M VRAM
mcr p15, 0, r0, c6, c0, 0
mcr p15, 0, r1, c6, c1, 0
mcr p15, 0, r2, c6, c2, 0
mcr p15, 0, r3, c6, c3, 0
mcr p15, 0, r4, c6, c4, 0
mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0
mov r0, #0b10101001 // unprot | arm9 | fcram | VRAM
mcr p15, 0, r0, c2, c0, 0 // Data cacheable
mcr p15, 0, r0, c2, c0, 1 // Instruction cacheable
mcr p15, 0, r0, c3, c0, 0 // Data bufferable
// Enable MPU and caching
mcr p15, 0, r0, c3, c0, 0
orr r0, r0, #(1<<12)
orr r0, r0, #(1<<2)
orr r0, r0, #(1<<0)
mcr p15, 0, r0, c1, c0, 0
*/
//Certain bootloaders put the interrupt vectors in ITCM. //Certain bootloaders put the interrupt vectors in ITCM.
//We don't want to mess with ITCM, so we put it back //We don't want to mess with ITCM, so we put it back
mrc p15, 0, r0, c1, c0, 0 mrc p15, 0, r0, c1, c0, 0
@ -119,14 +42,23 @@ _start:
mcr p15, 0, r0, c1, c0, 0 mcr p15, 0, r0, c1, c0, 0
//Start start //Start start
blx start blx start
.global enable_irqs
enable_irqs:
mrs r0, cpsr
bic r0, #0b111000000
msr cpsr, r0
bx lr
.section .bss .section .bss
.align 16 .align 16
.space 4096 .space 4096
interrupt_stack: fiq_stack:
.space 4096 .space 4096
exception_stack: irq_stack:
.space 4096
abt_stack:
.space 4096
und_stack:
.space 4096 .space 4096
svc_stack: svc_stack:
.space 16384 .space 4096
kernel_stack: kernel_stack:

View file

@ -1,5 +1,6 @@
#include "include/regs.h" #include "include/regs.h"
#include <base.hpp> #include <base.hpp>
#include <irq.hpp>
void print_regdump(cpu_state *state) { void print_regdump(cpu_state *state) {
(*out << "r0: ").puti(state->r0); (*out << "r0: ").puti(state->r0);
(*out << " r1: ").puti(state->r1); (*out << " r1: ").puti(state->r1);
@ -21,17 +22,11 @@ void print_regdump(cpu_state *state) {
(*out << " returnAddr: ").puti(state->returnAddr); (*out << " returnAddr: ").puti(state->returnAddr);
*out << "\n"; *out << "\n";
} }
extern "C" void panic2(char *msg, cpu_state *state);
extern "C" cpu_state *handleINT(int number, cpu_state *state) { extern "C" cpu_state *handleINT(int number, cpu_state *state) {
*out << "Interrupt"; *out << "Interrupt";
out->puti(number); out->puti(number);
*out << " occurred!\n"; *out << " occurred!\n";
if (number != 4) {
out->setColor(Color::RED);
print_regdump(state);
*out << "KERNEL PANIC: Unhandled CPU exception\n";
for (;;);
} else {
}
switch(number) { switch(number) {
case 0: case 0:
case 1: case 1:
@ -42,8 +37,18 @@ extern "C" cpu_state *handleINT(int number, cpu_state *state) {
else else
state->returnAddr -= 4; state->returnAddr -= 4;
} }
out->puti(state->cpsr); print_regdump(state);
return state; cpu_state *new_cpu = state;
switch(number) {
case 1:
case 2:
new_cpu = (cpu_state*)irqs->handleIRQ(new_cpu);
case 4:
break;
default:
panic2("Unhandled CPU exception!", state);
}
return new_cpu;
} }
extern "C" void panic2(char *msg, cpu_state *state) { extern "C" void panic2(char *msg, cpu_state *state) {
out->setColor(Color::RED); out->setColor(Color::RED);

View file

@ -15,19 +15,19 @@ _start:
mov r1, r2 mov r1, r2
orr r1, #0b10001 //FIQ orr r1, #0b10001 //FIQ
msr cpsr, r1 msr cpsr, r1
ldr sp, =interrupt_stack ldr sp, =fiq_stack
mov r1, r2 mov r1, r2
orr r1, #0b10010 //IRQ orr r1, #0b10010 //IRQ
msr cpsr, r1 msr cpsr, r1
ldr sp, =interrupt_stack ldr sp, =irq_stack
mov r1, r2 mov r1, r2
orr r1, #0b10111 //Abort orr r1, #0b10111 //Abort
msr cpsr, r1 msr cpsr, r1
ldr sp, =exception_stack ldr sp, =abt_stack
mov r1, r2 mov r1, r2
orr r1, #0b11011 //Undefined orr r1, #0b11011 //Undefined
msr cpsr, r1 msr cpsr, r1
ldr sp, =exception_stack ldr sp, =und_stack
orr r1, #0b11111 //SYS orr r1, #0b11111 //SYS
msr cpsr, r1 msr cpsr, r1
ldr sp, =kernel_stack ldr sp, =kernel_stack
@ -45,9 +45,13 @@ _start:
.section .bss .section .bss
.align 16 .align 16
.space 4096 .space 4096
interrupt_stack: fiq_stack:
.space 4096 .space 4096
exception_stack: irq_stack:
.space 4096
abt_stack:
.space 4096
und_stack:
.space 4096 .space 4096
svc_stack: svc_stack:
.space 16384 .space 16384

View file

@ -24,25 +24,25 @@ void initVectors() {
vectors[10] = branch_macro; vectors[10] = branch_macro;
vectors[11] = (uintptr_t)&data_abort; vectors[11] = (uintptr_t)&data_abort;
} }
IRQ_IO::IRQ_IO() { IRQ_IO::IRQ_IO() {
initVectors();
*((volatile uint32_t*)0x17E00100)=1; *((volatile uint32_t*)0x17E00100)=1;
*((volatile uint32_t*)0x17E00104)=0xF0; *((volatile uint32_t*)0x17E00104)=0xF0;
for(int i=0;i<32;i+=4) { for(int i=0;i<32;i+=4) {
*((volatile uint32_t*)(0x7E01100+i))=~0; *((volatile uint32_t*)(0x17E01100+i))=~0;
} }
uint32_t intid; uint32_t intid;
while((intid=*((volatile uint32_t*)0x7E00118))!=1023) { while((intid=*((volatile uint32_t*)0x17E00118))!=1023) {
*((volatile uint32_t*)0x7E00110)=intid; *((volatile uint32_t*)0x17E00110)=intid;
} }
} }
IRQ_IO::~IRQ_IO() {} IRQ_IO::~IRQ_IO() {}
void IRQ_IO::handleIRQ(void *data) { void *IRQ_IO::handleIRQ(void *data) {
uint32_t interrupt=*((volatile uint32_t*)0x7E0010C); uint32_t interrupt=*((volatile uint32_t*)0x17E0010C);
int intid = interrupt & 255; int intid = interrupt & 255;
data = handlers[intid](data); data = handlers[intid](data);
*((volatile uint32_t*)0x7E00110) = interrupt; *((volatile uint32_t*)0x17E00110) = interrupt;
return data; return data;
} }

View file

@ -3,7 +3,7 @@
#include <irq.hpp> #include <irq.hpp>
void initVectors(); void initVectors();
struct IRQ_IO { struct IRQ_IO: IRQ {
IRQ_IO(); IRQ_IO();
virtual ~IRQ_IO(); virtual ~IRQ_IO();
virtual void* handleIRQ(void *data); virtual void* handleIRQ(void *data);

View file

@ -1,4 +1,5 @@
#include "vectorinit.hpp" #include "vectorinit.hpp"
#include <base.hpp>
extern "C" { extern "C" {
extern uintptr_t branch_macro; extern uintptr_t branch_macro;
void data_abort(); void data_abort();
@ -26,10 +27,10 @@ void initVectors() {
vectors[11] = (uintptr_t)&data_abort; vectors[11] = (uintptr_t)&data_abort;
flushAll(); flushAll();
} }
IRQ_IO::IRQ_IO() { IRQ_IO::IRQ_IO() {
initVectors();
*((volatile uint32_t*)0x10001000)=~0; *((volatile uint32_t*)0x10001000)=~0;
*((volatile uint32_t*)0x10001004)=0; *((volatile uint32_t*)0x10001004)=~0;
} }
IRQ_IO::~IRQ_IO() {} IRQ_IO::~IRQ_IO() {}
@ -38,7 +39,7 @@ void* IRQ_IO::handleIRQ(void *data) {
int bit; int bit;
while(bit=__builtin_ffs(*((volatile int*)0x10001004))) { while(bit=__builtin_ffs(*((volatile int*)0x10001004))) {
data = handlers[bit-1](data); data = handlers[bit-1](data);
*((volatile int*)0x10001004)&=~(1<<(bit-1)); *((volatile int*)0x10001004)=(1<<(bit-1));
} }
return data; return data;
} }

View file

@ -2,8 +2,7 @@
#include <stdint.h> #include <stdint.h>
#include <irq.hpp> #include <irq.hpp>
void initVectors(); void initVectors();
struct IRQ_IO: IRQ {
struct IRQ_IO {
IRQ_IO(); IRQ_IO();
virtual ~IRQ_IO(); virtual ~IRQ_IO();
virtual void* handleIRQ(void *data); virtual void* handleIRQ(void *data);

View file

@ -7,7 +7,7 @@ constexpr int get_max_irq() {
if constexpr(same_string(ARCH, "x86") || same_string(ARCH, "x86_64")) { if constexpr(same_string(ARCH, "x86") || same_string(ARCH, "x86_64")) {
return 32; return 32;
} else if constexpr(same_string(SYSTEM, "3ds9")) { } else if constexpr(same_string(SYSTEM, "3ds9")) {
return 30; return 32;
} else if constexpr(same_string(SYSTEM, "3ds11")) { } else if constexpr(same_string(SYSTEM, "3ds11")) {
return 256; return 256;
} else { } else {