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);
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
initVectors();
|
||||
*((volatile uint32_t*)0x17E00600)=67108;
|
||||
*((volatile uint32_t*)0x17E00608=3;
|
||||
*((volatile uint32_t*)0x17E00608)=3;
|
||||
asm volatile("CPSIE aif");
|
||||
}
|
||||
|
|
|
@ -14,19 +14,19 @@ _start:
|
|||
mov r1, r2
|
||||
orr r1, #0b10001 //FIQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
ldr sp, =fiq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10010 //IRQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
ldr sp, =irq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10111 //Abort
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
ldr sp, =abt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b11011 //Undefined
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
ldr sp, =und_stack
|
||||
orr r1, #0b11111 //SYS
|
||||
msr cpsr, r1
|
||||
ldr sp, =kernel_stack
|
||||
|
@ -46,10 +46,14 @@ _start:
|
|||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
interrupt_stack:
|
||||
irq_stack:
|
||||
.space 4096
|
||||
exception_stack:
|
||||
fiq_stack:
|
||||
.space 4096
|
||||
abt_stack:
|
||||
.space 4096
|
||||
und_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
.space 4096
|
||||
kernel_stack:
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
PICAfb term;
|
||||
PMM_MMAP lpmm;
|
||||
void main();
|
||||
extern "C" void enable_irqs();
|
||||
extern "C" void start() { main();
|
||||
for(;;);
|
||||
}
|
||||
|
@ -15,11 +16,10 @@ void drivers_init() {
|
|||
pmm=(PMM*)(&lpmm);
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
initVectors();
|
||||
//Init 1000Hz timer
|
||||
enable_irqs();
|
||||
*((volatile uint16_t*)0x10003002)=0;
|
||||
*((volatile uint16_t*)0x10003000)=65;
|
||||
*((volatile uint16_t*)0x10003002)=0b11000011;
|
||||
*((volatile uint32_t*)0x10001000)|=1<<8;
|
||||
asm volatile("CPSIE aif");
|
||||
}
|
||||
|
|
|
@ -4,29 +4,9 @@
|
|||
.section .text.boot
|
||||
_start:
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #0x80
|
||||
orr r0, r0, #0b111000000
|
||||
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
|
||||
//Set other stacks
|
||||
mrs r0, cpsr
|
||||
|
@ -34,19 +14,19 @@ _start:
|
|||
mov r1, r2
|
||||
orr r1, #0b10001 //FIQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
ldr sp, =fiq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10010 //IRQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
ldr sp, =irq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10111 //Abort
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
ldr sp, =abt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b11011 //Undefined
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
ldr sp, =und_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10011 //SVC
|
||||
msr cpsr, r1
|
||||
|
@ -54,64 +34,7 @@ _start:
|
|||
orr r1, #0b11111 //SYS
|
||||
msr cpsr, r1
|
||||
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.
|
||||
//We don't want to mess with ITCM, so we put it back
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
|
@ -119,14 +42,23 @@ _start:
|
|||
mcr p15, 0, r0, c1, c0, 0
|
||||
//Start start
|
||||
blx start
|
||||
|
||||
.global enable_irqs
|
||||
enable_irqs:
|
||||
mrs r0, cpsr
|
||||
bic r0, #0b111000000
|
||||
msr cpsr, r0
|
||||
bx lr
|
||||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
interrupt_stack:
|
||||
fiq_stack:
|
||||
.space 4096
|
||||
exception_stack:
|
||||
irq_stack:
|
||||
.space 4096
|
||||
abt_stack:
|
||||
.space 4096
|
||||
und_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
.space 4096
|
||||
kernel_stack:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "include/regs.h"
|
||||
#include <base.hpp>
|
||||
#include <irq.hpp>
|
||||
void print_regdump(cpu_state *state) {
|
||||
(*out << "r0: ").puti(state->r0);
|
||||
(*out << " r1: ").puti(state->r1);
|
||||
|
@ -21,29 +22,33 @@ void print_regdump(cpu_state *state) {
|
|||
(*out << " returnAddr: ").puti(state->returnAddr);
|
||||
*out << "\n";
|
||||
}
|
||||
extern "C" void panic2(char *msg, cpu_state *state);
|
||||
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 (;;);
|
||||
} else {
|
||||
switch(number) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if(state->cpsr & 0x20)
|
||||
state->returnAddr -= 2;
|
||||
else
|
||||
state->returnAddr -= 4;
|
||||
}
|
||||
switch (number) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if (state->cpsr & 0x20)
|
||||
state->returnAddr -= 2;
|
||||
else
|
||||
state->returnAddr -= 4;
|
||||
print_regdump(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);
|
||||
}
|
||||
out->puti(state->cpsr);
|
||||
return state;
|
||||
return new_cpu;
|
||||
}
|
||||
extern "C" void panic2(char *msg, cpu_state *state) {
|
||||
out->setColor(Color::RED);
|
||||
|
|
|
@ -15,19 +15,19 @@ _start:
|
|||
mov r1, r2
|
||||
orr r1, #0b10001 //FIQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
ldr sp, =fiq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10010 //IRQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
ldr sp, =irq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10111 //Abort
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
ldr sp, =abt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b11011 //Undefined
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
ldr sp, =und_stack
|
||||
orr r1, #0b11111 //SYS
|
||||
msr cpsr, r1
|
||||
ldr sp, =kernel_stack
|
||||
|
@ -45,9 +45,13 @@ _start:
|
|||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
interrupt_stack:
|
||||
fiq_stack:
|
||||
.space 4096
|
||||
exception_stack:
|
||||
irq_stack:
|
||||
.space 4096
|
||||
abt_stack:
|
||||
.space 4096
|
||||
und_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
|
|
|
@ -24,25 +24,25 @@ void initVectors() {
|
|||
vectors[10] = branch_macro;
|
||||
vectors[11] = (uintptr_t)&data_abort;
|
||||
}
|
||||
|
||||
IRQ_IO::IRQ_IO() {
|
||||
initVectors();
|
||||
*((volatile uint32_t*)0x17E00100)=1;
|
||||
*((volatile uint32_t*)0x17E00104)=0xF0;
|
||||
for(int i=0;i<32;i+=4) {
|
||||
*((volatile uint32_t*)(0x7E01100+i))=~0;
|
||||
*((volatile uint32_t*)(0x17E01100+i))=~0;
|
||||
}
|
||||
uint32_t intid;
|
||||
while((intid=*((volatile uint32_t*)0x7E00118))!=1023) {
|
||||
*((volatile uint32_t*)0x7E00110)=intid;
|
||||
while((intid=*((volatile uint32_t*)0x17E00118))!=1023) {
|
||||
*((volatile uint32_t*)0x17E00110)=intid;
|
||||
}
|
||||
}
|
||||
IRQ_IO::~IRQ_IO() {}
|
||||
|
||||
void IRQ_IO::handleIRQ(void *data) {
|
||||
uint32_t interrupt=*((volatile uint32_t*)0x7E0010C);
|
||||
void *IRQ_IO::handleIRQ(void *data) {
|
||||
uint32_t interrupt=*((volatile uint32_t*)0x17E0010C);
|
||||
int intid = interrupt & 255;
|
||||
data = handlers[intid](data);
|
||||
*((volatile uint32_t*)0x7E00110) = interrupt;
|
||||
*((volatile uint32_t*)0x17E00110) = interrupt;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <irq.hpp>
|
||||
void initVectors();
|
||||
|
||||
struct IRQ_IO {
|
||||
struct IRQ_IO: IRQ {
|
||||
IRQ_IO();
|
||||
virtual ~IRQ_IO();
|
||||
virtual void* handleIRQ(void *data);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "vectorinit.hpp"
|
||||
#include <base.hpp>
|
||||
extern "C" {
|
||||
extern uintptr_t branch_macro;
|
||||
void data_abort();
|
||||
|
@ -26,10 +27,10 @@ void initVectors() {
|
|||
vectors[11] = (uintptr_t)&data_abort;
|
||||
flushAll();
|
||||
}
|
||||
|
||||
IRQ_IO::IRQ_IO() {
|
||||
initVectors();
|
||||
*((volatile uint32_t*)0x10001000)=~0;
|
||||
*((volatile uint32_t*)0x10001004)=0;
|
||||
*((volatile uint32_t*)0x10001004)=~0;
|
||||
}
|
||||
IRQ_IO::~IRQ_IO() {}
|
||||
|
||||
|
@ -38,7 +39,7 @@ void* IRQ_IO::handleIRQ(void *data) {
|
|||
int bit;
|
||||
while(bit=__builtin_ffs(*((volatile int*)0x10001004))) {
|
||||
data = handlers[bit-1](data);
|
||||
*((volatile int*)0x10001004)&=~(1<<(bit-1));
|
||||
*((volatile int*)0x10001004)=(1<<(bit-1));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
#include <stdint.h>
|
||||
#include <irq.hpp>
|
||||
void initVectors();
|
||||
|
||||
struct IRQ_IO {
|
||||
struct IRQ_IO: IRQ {
|
||||
IRQ_IO();
|
||||
virtual ~IRQ_IO();
|
||||
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")) {
|
||||
return 32;
|
||||
} else if constexpr(same_string(SYSTEM, "3ds9")) {
|
||||
return 30;
|
||||
return 32;
|
||||
} else if constexpr(same_string(SYSTEM, "3ds11")) {
|
||||
return 256;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue