diff --git a/buildtools/mkfirm.py b/buildtools/mkfirm.py index a9ff4b8..ba0b889 100755 --- a/buildtools/mkfirm.py +++ b/buildtools/mkfirm.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 import sys +import base64 if len(sys.argv) < 4: print("USAGE: mkfirm.py ") -print("WARNING: Currently you cannot install this FIRM, because YOU'LL BRICK YOUR 3DS!") -sighax_sig = b'\x00'*256 #TODO insert sighax signature here. +sighax_sig=base64.a85decode(b'DZ:iLO%T*f"sal5!m5:QU$Gmm[dg)m,&2*-HJLBEU+9e;EeCligEb]Qpn^2!Gp5_g%-,]IDC-MMahK=@9T\\,0,4&6MDgNaP\'t06CY.qpSb;KMn)+PR1>e0IbaRdgDC5J-m3DLB2d$%DNZn-W7=ADNLl+s&Z2gs%A?=ZJ:91F?66n9DXZ.-lL+5$#ebaKH5IB)Y&DTGd%!,O4me2`$F["\\.$Tr)%\\,h,n.Q]LTQGQRH:#a?1l(T-i_m7b\\7Mg5Ga7LDUacTc`!af0V`"\'-*]I]3%SL)@)ll701ok)i') import struct import hashlib def get_elf_seg(f): #Return entry,section_beg,section_size,section @@ -49,6 +49,18 @@ f2 = open(sys.argv[2],"rb") f = open(sys.argv[3],"wb") arm9_entry,arm9_section_beg,arm9_section_size,arm9_section = get_elf_seg(f1) arm11_entry,arm11_section_beg,arm11_section_size,arm11_section = get_elf_seg(f2) +def align(a,b): + if a % b: + return a + b - (a%b) + return a +def align2(a,b): + if len(a) % b: + return a + bytes(512-(len(a)%b)) + return a +arm9_section_size=align(arm9_section_size,512) +arm11_section_size=align(arm11_section_size,512) +arm9_section=align2(arm9_section,512) +arm11_section=align2(arm11_section,512) arm9_hash=hashlib.sha256(arm9_section).digest() arm11_hash=hashlib.sha256(arm11_section).digest() arm9_off = 0x200 diff --git a/do_all.sh b/do_all.sh index 75cc0d0..de9a508 100755 --- a/do_all.sh +++ b/do_all.sh @@ -1,5 +1,5 @@ builddir() { - rm -rvvf build/ && + rm -rf build/ && mkdir -pv build/ } rm -rvvf out/ @@ -59,4 +59,15 @@ mv kernel9 build/kernel && buildtools/sighax-firm.sh && mv sighax.firm out/ && cp -v build/kernel/kernel out/arm11loaderhax.elf -rm -rvvf build/ +rm -rf build/ + +#firmloader +pushd boot/3ds && +builddir && +pushd build && +cmake -DCMAKE_TOOLCHAIN_FILE=../../../toolchains/arm-none-eabi.cmake .. && +make -j$(nproc) && +popd && +mv build/arm9loaderhax.bin ../../out && +rm -rf build/ && +popd diff --git a/kernel/arch/arm/3ds11/start.cpp b/kernel/arch/arm/3ds11/start.cpp index d2b2a18..57ef89a 100644 --- a/kernel/arch/arm/3ds11/start.cpp +++ b/kernel/arch/arm/3ds11/start.cpp @@ -1,4 +1,5 @@ #include "../../../hw/3ds11/picafb/picafb.hpp" +#include "../../../hw/3ds11/vectorinit/vectorinit.hpp" #include #include @@ -8,4 +9,6 @@ extern "C" void start() { main(); } void drivers_init() { setMainTTY(&term); --term; + initVectors(); + asm volatile("svc #0"); } diff --git a/kernel/arch/arm/3ds11/start.s b/kernel/arch/arm/3ds11/start.s index 90fcd9c..946a6b7 100644 --- a/kernel/arch/arm/3ds11/start.s +++ b/kernel/arch/arm/3ds11/start.s @@ -8,6 +8,28 @@ _start: CPSID aif //Disable interrupts ldr sp, =kernel_stack + //set other stacks + mrs r0, cpsr + bic r2, r0, #0x1F + mov r1, r2 + orr r1, #0b10001 //FIQ + msr cpsr, r1 + ldr sp, =interrupt_stack + mov r1, r2 + orr r1, #0b10010 //IRQ + msr cpsr, r1 + ldr sp, =interrupt_stack + mov r1, r2 + orr r1, #0b10111 //Abort + msr cpsr, r1 + ldr sp, =exception_stack + mov r1, r2 + orr r1, #0b11011 //Undefined + msr cpsr, r1 + ldr sp, =exception_stack + orr r1, #0b11111 //SYS + msr cpsr, r1 + ldr sp, =kernel_stack //Enable FPU mov r0, #0 mov r1, #0xF00000 @@ -17,9 +39,14 @@ _start: mov r2, #0x3C00000 fmxr fpexc, r1 fmxr fpscr, r2 + //Start MTGos blx start .section .bss +.space 4096 +interrupt_stack: +.space 4096 +exception_stack: .space 16384 kernel_stack: diff --git a/kernel/arch/arm/3ds9/flags.cmake b/kernel/arch/arm/3ds9/flags.cmake index 081ab5a..2358460 100644 --- a/kernel/arch/arm/3ds9/flags.cmake +++ b/kernel/arch/arm/3ds9/flags.cmake @@ -1,3 +1,3 @@ -SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds9/include -mcpu=arm946e-s -march=armv5te -mthumb-interwork -mthumb -Os") +SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds9/include -mcpu=arm946e-s -march=armv5te -mthumb-interwork -marm -O9") SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}") SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}") diff --git a/kernel/arch/arm/3ds9/start.s b/kernel/arch/arm/3ds9/start.s index 905d01e..f5b1a27 100644 --- a/kernel/arch/arm/3ds9/start.s +++ b/kernel/arch/arm/3ds9/start.s @@ -28,6 +28,32 @@ _start: blx r0 */ ldr sp, =kernel_stack //set stack + //Set other stacks + mrs r0, cpsr + bic r2, r0, #0x1F + mov r1, r2 + orr r1, #0b10001 //FIQ + msr cpsr, r1 + ldr sp, =interrupt_stack + mov r1, r2 + orr r1, #0b10010 //IRQ + msr cpsr, r1 + ldr sp, =interrupt_stack + mov r1, r2 + orr r1, #0b10111 //Abort + msr cpsr, r1 + ldr sp, =exception_stack + mov r1, r2 + orr r1, #0b11011 //Undefined + msr cpsr, r1 + ldr sp, =exception_stack + mov r1, r2 + orr r1, #0b10011 //SVC + msr cpsr, r1 + ldr sp, =kernel_stack + orr r1, #0b11111 //SYS + msr cpsr, r1 + ldr sp, =kernel_stack /* //Configure ITCM to…something mrc p15, 0, r0, c9, c1, 1 @@ -95,5 +121,9 @@ _start: blx start .section .bss +.space 4096 +interrupt_stack: +.space 4096 +exception_stack: .space 16384 kernel_stack: diff --git a/kernel/arch/arm/cache.s b/kernel/arch/arm/cache.s new file mode 100644 index 0000000..9a1fa54 --- /dev/null +++ b/kernel/arch/arm/cache.s @@ -0,0 +1,24 @@ +.arm +.global drainWriteBuffer +drainWriteBuffer: + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 + bx lr + +.global flushAll +flushAll: + mov r1, #0 //Segment +1: + mov r0, #0 //Line +2: + orr r2, r1, r0 + mcr p15, 0, r2, c7, c14, 2 //Flush current line + add r0, #0x20 //Next line + cmp r0, #0x400 + bne 2b + add r1, #0x40000000 + cmp r1, #0x0 + bne 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 //flush instruction cache + b drainWriteBuffer diff --git a/kernel/arch/arm/include/cache.h b/kernel/arch/arm/include/cache.h new file mode 100644 index 0000000..10b273e --- /dev/null +++ b/kernel/arch/arm/include/cache.h @@ -0,0 +1,4 @@ +extern "C" { + void flushAll(); + void drainWriteBuffer(); +} diff --git a/kernel/arch/arm/interrupt.cpp b/kernel/arch/arm/interrupt.cpp index 099add6..71d4857 100644 --- a/kernel/arch/arm/interrupt.cpp +++ b/kernel/arch/arm/interrupt.cpp @@ -15,6 +15,10 @@ void print_regdump(cpu_state *state) { (*out << " r11: ").puti(state->r11); (*out << " r12: ").puti(state->r12); (*out << " pc: ").puti(state->pc); + (*out << " cpsr: ").puti(state->cpsr); + (*out << " sp: ").puti(state->sp); + (*out << " lr: ").puti(state->lr); + (*out << " returnAddr: ").puti(state->returnAddr); *out << "\n"; } extern "C" cpu_state *handleINT(int number, cpu_state *state) { @@ -25,7 +29,8 @@ extern "C" cpu_state *handleINT(int number, cpu_state *state) { out->setColor(Color::RED); print_regdump(state); *out << "KERNEL PANIC: Unhandled CPU exception\n"; - // for(;;); + for (;;); + } else { } switch (number) { case 0: diff --git a/kernel/arch/arm/sourcegen.py b/kernel/arch/arm/sourcegen.py index ceaa4e0..7059a85 100644 --- a/kernel/arch/arm/sourcegen.py +++ b/kernel/arch/arm/sourcegen.py @@ -5,13 +5,14 @@ int_handler.write( .section .bss .space 4096 exception_stack: +.section .data +.space 4 +oldsp: .section .text .global branch_macro branch_macro: ldr pc, [pc, #-4] //Load the next word into PC .macro interrupt_handler intid - //Set to the correct stack - ldr sp, =exception_stack push {r0-r12,lr} //Push registers //Get previous sp and lr @@ -41,7 +42,8 @@ branch_macro: ldr r0, =\intid //Jump to generic handler - blx intr_common_handler + + bl intr_common_handler //pop the special registers pop {r0, r3, r4, lr} @@ -50,6 +52,7 @@ branch_macro: orr lr, lr, #1 //Enable thumb mode on return# 2: str lr, [sp, #0x34] //Set correct lr + ldmfd sp!, {r0-r12, pc}^ //Return back to original mode .endm .global data_abort @@ -81,8 +84,8 @@ if ("ENABLE_HARD" in config) and config["ENABLE_HARD"]: for i,j in enumerate(["fpsid","fpscr","fpexc"]): push_regs.append("fmrx r"+str(i+1)+", "+j) pop_regs.append("fmxr "+j+", r"+str(i+1)) - push_regs.append("push {r1,r2,r3,r4,r5}") - pop_regs.append("pop {r1,r2,r3,r4,r5}") + push_regs.append("push {r1,r2,r3}") + pop_regs.append("pop {r1,r2,r3}") push_regs.append("vpush {d0-d15}") pop_regs.append("vpop {d0-d15}") push_regs.append("mov r1, sp") @@ -102,10 +105,10 @@ int_handler.write(" b panic\n") reg_struct.write("#include \nstruct cpu_state {\n") if ("ENABLE_HARD" in config) and config["ENABLE_HARD"]: - for reg in ["fpsid","fpscr","fpexc"]: - reg_struct.write(" uint32_t "+reg+";\n") for reg in ("d"+str(i) for i in range(16)): reg_struct.write(" double "+reg+";\n") + for reg in ["fpsid","fpscr","fpexc"]: + reg_struct.write(" uint32_t "+reg+";\n") for reg in ["cpsr","sp","lr","returnAddr"]: reg_struct.write(" uint32_t "+reg+";\n") for i in range(13): diff --git a/kernel/hw/3ds11/picafb/picafb.cpp b/kernel/hw/3ds11/picafb/picafb.cpp index 94d702e..a3df578 100644 --- a/kernel/hw/3ds11/picafb/picafb.cpp +++ b/kernel/hw/3ds11/picafb/picafb.cpp @@ -8,7 +8,7 @@ #define GL_RGB565_OES 2 #define GL_RGB5_A1_OES 3 #define GL_RGBA4_OES 4 -PICAfb::PICAfb() : Framebuffer(25, 30) { +PICAfb::PICAfb() : Framebuffer(50, 15) { #ifdef ENABLE_SCREENINIT MCU::enableTopLCD(); MCU::enableBottomLCD(); @@ -93,8 +93,8 @@ PICAfb::PICAfb() : Framebuffer(25, 30) { PICAfb::~PICAfb() {} auto PICAfb::plotPixel(int x, int y, int col) -> void { unsigned char *lfb = (unsigned char *)0x18300000; - // XXX I know it's rotated. But I need more vertical space than horizonal space. - int off = (y * 240 + x) * 3; + y=240-y-1; + int off = (x * 240 + y) * 3; for (int i = 0; i < 3; i++) { lfb[off++] = col; col >>= 8; diff --git a/kernel/hw/3ds9/picafb/picafb.cpp b/kernel/hw/3ds9/picafb/picafb.cpp index 2c43f93..c738eb8 100644 --- a/kernel/hw/3ds9/picafb/picafb.cpp +++ b/kernel/hw/3ds9/picafb/picafb.cpp @@ -1,11 +1,11 @@ #include "picafb.hpp" #include -PICAfb::PICAfb() : Framebuffer(25, 20) {} +PICAfb::PICAfb() : Framebuffer(40, 15) {} PICAfb::~PICAfb() {} auto PICAfb::plotPixel(int x, int y, int col) -> void { unsigned char *lfb = (unsigned char *)0x18300000 + 0x46500; - // XXX I know it's rotated. But I need more vertical space than horizonal space. - int off = (y * 240 + x) * 3; + y=240-y-1; + int off = (x * 240 + y) * 3; for (int i = 0; i < 3; i++) { lfb[off++] = col; col >>= 8; diff --git a/kernel/hw/3ds9/vectorinit/vectorinit.cpp b/kernel/hw/3ds9/vectorinit/vectorinit.cpp index 8ee9afe..aace978 100644 --- a/kernel/hw/3ds9/vectorinit/vectorinit.cpp +++ b/kernel/hw/3ds9/vectorinit/vectorinit.cpp @@ -7,9 +7,12 @@ void normal_irq(); void prefetch_abort(); void svc_call(); void undefined_op(); +void flushAll(); } +#pragma GCC push_options +#pragma GCC optimize("O0") void initVectors() { - uintptr_t *vectors = (uintptr_t *)0x0800000; + uintptr_t *vectors = (uintptr_t *)0x08000000; // branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC vectors[0] = branch_macro; vectors[1] = (uintptr_t)&normal_irq; @@ -23,4 +26,6 @@ void initVectors() { vectors[9] = (uintptr_t)&prefetch_abort; vectors[10] = branch_macro; vectors[11] = (uintptr_t)&data_abort; + flushAll(); } +#pragma GCC pop_options diff --git a/kernel/src/tty.cpp b/kernel/src/tty.cpp index 7186621..f245894 100644 --- a/kernel/src/tty.cpp +++ b/kernel/src/tty.cpp @@ -16,7 +16,7 @@ auto TTY::setColor(unsigned int c) -> void { auto TTY::putChar(int c) -> void { auto scroll = [this]() -> void { for (int x = 0; x < this->width; x++) - for (int y = 0; y < this->height; y++) this->plotChar(x, y, 0); + for (int y = 0; y < this->height; y++) this->plotChar(x, y, 0x20); this->x = this->y = 0; }; switch (c) { @@ -28,7 +28,7 @@ auto TTY::putChar(int c) -> void { default: plotChar(x, y, c); x++; - if (x > width) { + if (x >= width) { y++; x = 0; }