From 3a60a712b207aca597cce18986bb3afad041817f Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Sat, 29 Jul 2017 09:53:39 +0100 Subject: [PATCH] got IRQs working on 3ds9 --- kernel/arch/arm/3ds11/start.cpp | 3 +- kernel/arch/arm/3ds11/start.s | 18 ++-- kernel/arch/arm/3ds9/start.cpp | 4 +- kernel/arch/arm/3ds9/start.s | 104 ++++------------------ kernel/arch/arm/interrupt.cpp | 39 ++++---- kernel/arch/arm/raspi2/start.s | 16 ++-- kernel/hw/3ds11/vectorinit/vectorinit.cpp | 14 +-- kernel/hw/3ds11/vectorinit/vectorinit.hpp | 2 +- kernel/hw/3ds9/vectorinit/vectorinit.cpp | 7 +- kernel/hw/3ds9/vectorinit/vectorinit.hpp | 3 +- kernel/src/include/irq.hpp | 2 +- 11 files changed, 78 insertions(+), 134 deletions(-) diff --git a/kernel/arch/arm/3ds11/start.cpp b/kernel/arch/arm/3ds11/start.cpp index b77a5b9..ba7b849 100644 --- a/kernel/arch/arm/3ds11/start.cpp +++ b/kernel/arch/arm/3ds11/start.cpp @@ -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"); } diff --git a/kernel/arch/arm/3ds11/start.s b/kernel/arch/arm/3ds11/start.s index 58f1284..8a57281 100644 --- a/kernel/arch/arm/3ds11/start.s +++ b/kernel/arch/arm/3ds11/start.s @@ -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: diff --git a/kernel/arch/arm/3ds9/start.cpp b/kernel/arch/arm/3ds9/start.cpp index c8d1f00..3f65e22 100644 --- a/kernel/arch/arm/3ds9/start.cpp +++ b/kernel/arch/arm/3ds9/start.cpp @@ -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"); } diff --git a/kernel/arch/arm/3ds9/start.s b/kernel/arch/arm/3ds9/start.s index d79bb42..ef754c2 100644 --- a/kernel/arch/arm/3ds9/start.s +++ b/kernel/arch/arm/3ds9/start.s @@ -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: diff --git a/kernel/arch/arm/interrupt.cpp b/kernel/arch/arm/interrupt.cpp index edec6fb..fefbf8a 100644 --- a/kernel/arch/arm/interrupt.cpp +++ b/kernel/arch/arm/interrupt.cpp @@ -1,5 +1,6 @@ #include "include/regs.h" #include +#include 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); diff --git a/kernel/arch/arm/raspi2/start.s b/kernel/arch/arm/raspi2/start.s index 170c32a..8774e52 100644 --- a/kernel/arch/arm/raspi2/start.s +++ b/kernel/arch/arm/raspi2/start.s @@ -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 diff --git a/kernel/hw/3ds11/vectorinit/vectorinit.cpp b/kernel/hw/3ds11/vectorinit/vectorinit.cpp index 09dbdec..ee0fb09 100644 --- a/kernel/hw/3ds11/vectorinit/vectorinit.cpp +++ b/kernel/hw/3ds11/vectorinit/vectorinit.cpp @@ -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; } diff --git a/kernel/hw/3ds11/vectorinit/vectorinit.hpp b/kernel/hw/3ds11/vectorinit/vectorinit.hpp index 9d983eb..d037b06 100644 --- a/kernel/hw/3ds11/vectorinit/vectorinit.hpp +++ b/kernel/hw/3ds11/vectorinit/vectorinit.hpp @@ -3,7 +3,7 @@ #include void initVectors(); -struct IRQ_IO { +struct IRQ_IO: IRQ { IRQ_IO(); virtual ~IRQ_IO(); virtual void* handleIRQ(void *data); diff --git a/kernel/hw/3ds9/vectorinit/vectorinit.cpp b/kernel/hw/3ds9/vectorinit/vectorinit.cpp index 0309eee..e4fed9d 100644 --- a/kernel/hw/3ds9/vectorinit/vectorinit.cpp +++ b/kernel/hw/3ds9/vectorinit/vectorinit.cpp @@ -1,4 +1,5 @@ #include "vectorinit.hpp" +#include 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; } diff --git a/kernel/hw/3ds9/vectorinit/vectorinit.hpp b/kernel/hw/3ds9/vectorinit/vectorinit.hpp index 9d983eb..f82a8fe 100644 --- a/kernel/hw/3ds9/vectorinit/vectorinit.hpp +++ b/kernel/hw/3ds9/vectorinit/vectorinit.hpp @@ -2,8 +2,7 @@ #include #include void initVectors(); - -struct IRQ_IO { +struct IRQ_IO: IRQ { IRQ_IO(); virtual ~IRQ_IO(); virtual void* handleIRQ(void *data); diff --git a/kernel/src/include/irq.hpp b/kernel/src/include/irq.hpp index c68a448..fbc3cd6 100644 --- a/kernel/src/include/irq.hpp +++ b/kernel/src/include/irq.hpp @@ -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 {