got IRQs working on 3ds9
This commit is contained in:
parent
7d6c2a0dd1
commit
3a60a712b2
11 changed files with 78 additions and 134 deletions
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 to…something
|
|
||||||
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:
|
||||||
|
|
|
@ -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,29 +22,33 @@ 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) {
|
switch(number) {
|
||||||
out->setColor(Color::RED);
|
case 0:
|
||||||
print_regdump(state);
|
case 1:
|
||||||
*out << "KERNEL PANIC: Unhandled CPU exception\n";
|
case 2:
|
||||||
for (;;);
|
case 3:
|
||||||
} else {
|
if(state->cpsr & 0x20)
|
||||||
|
state->returnAddr -= 2;
|
||||||
|
else
|
||||||
|
state->returnAddr -= 4;
|
||||||
}
|
}
|
||||||
switch (number) {
|
print_regdump(state);
|
||||||
case 0:
|
cpu_state *new_cpu = state;
|
||||||
case 1:
|
switch(number) {
|
||||||
case 2:
|
case 1:
|
||||||
case 3:
|
case 2:
|
||||||
if (state->cpsr & 0x20)
|
new_cpu = (cpu_state*)irqs->handleIRQ(new_cpu);
|
||||||
state->returnAddr -= 2;
|
case 4:
|
||||||
else
|
break;
|
||||||
state->returnAddr -= 4;
|
default:
|
||||||
|
panic2("Unhandled CPU exception!", state);
|
||||||
}
|
}
|
||||||
out->puti(state->cpsr);
|
return new_cpu;
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue