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);
setMainTTY(&term);
--term;
initVectors();
*((volatile uint32_t*)0x17E00600)=67108;
*((volatile uint32_t*)0x17E00608=3;
*((volatile uint32_t*)0x17E00608)=3;
asm volatile("CPSIE aif");
}

View file

@ -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:

View file

@ -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");
}

View file

@ -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 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.
//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:

View file

@ -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);

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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 {