From: chaoskagami Date: Fri, 15 Jul 2016 04:11:22 +0000 (-0400) Subject: Fix up start.s for libctr9_io exception handling X-Git-Tag: v0.2.0~20 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=0baba95284d57997871a82b13140bfbbc114e784;p=corbenik%2Fcorbenik.git Fix up start.s for libctr9_io exception handling --- diff --git a/linker.ld b/linker.ld index 802a17d..aba1eaa 100644 --- a/linker.ld +++ b/linker.ld @@ -1,37 +1,31 @@ +OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x23F00000; - START_SECTION = .; - .text.start : { - *(.text.start) - } - START_SECTION_END = .; + .text.start : { + *(.text.start) + } - TEXT_SECTION = .; - .text : { - *(.text) - } - TEXT_SECTION_END = .; + .text : { + *(.text) + } - DATA_SECTION = .; - .data : { - *(.data) - } - DATA_SECTION_END = .; + .data : { + *(.data) + } - BSS_SECTION = .; - .bss : { - *(.bss COMMON) - } - BSS_SECTION_END = .; + .bss : { + __bss_start = .; + *(.bss COMMON) + } + __bss_end = .; - RODATA_SECTION = .; - .rodata : { - *(.rodata) - } - RODATA_SECTION_END = .; + .rodata : { + *(.rodata) + } . = ALIGN(4); + __end__ = 0x20400000; } diff --git a/source/start.s b/source/start.s index 04e29d1..6593805 100644 --- a/source/start.s +++ b/source/start.s @@ -1,6 +1,6 @@ -.section .text.start .align 4 .global _start +.section .text.start, "x" _start: ldr r2, =argc str r0, [r2] @@ -8,74 +8,249 @@ _start: ldr r2, =argv str r1, [r2] - b mpu + b init argc: .int 0x00000000 argv: .int 0x00000000 -mpu: - // Change the stack pointer - mov sp, #0x27000000 - - // Disable caches / mpu - mrc p15, 0, r4, c1, c0, 0 // read control register - bic r4, #(1<<12) // - instruction cache disable - bic r4, #(1<<2) // - data cache disable - bic r4, #(1<<0) // - mpu disable - mcr p15, 0, r4, c1, c0, 0 // write control register - - // Give read/write access to all the memory regions - ldr r5, =0x33333333 - mcr p15, 0, r5, c5, c0, 2 // write data access - mcr p15, 0, r5, c5, c0, 3 // write instruction access - - // Sets MPU permissions and cache settings - ldr r0, =0xFFFF001D // ffff0000 32k - ldr r1, =0x01FF801D // 01ff8000 32k - ldr r2, =0x08000027 // 08000000 1M - ldr r3, =0x10000021 // 10000000 128k - ldr r4, =0x10100025 // 10100000 512k - ldr r5, =0x20000035 // 20000000 128M - ldr r6, =0x1FF00027 // 1FF00000 1M - ldr r7, =0x1800002D // 18000000 8M - mov r10, #0x25 - mov r11, #0x25 - mov r12, #0x25 - 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 - mcr p15, 0, r10, c3, c0, 0 // Write bufferable 0, 2, 5 - mcr p15, 0, r11, c2, c0, 0 // Data cacheable 0, 2, 5 - mcr p15, 0, r12, c2, c0, 1 // Inst cacheable 0, 2, 5 - - // Enable caches - mrc p15, 0, r4, c1, c0, 0 // read control register - orr r4, r4, #(1<<18) // - itcm enable - orr r4, r4, #(1<<12) // - instruction cache enable - orr r4, r4, #(1<<2) // - data cache enable - orr r4, r4, #(1<<0) // - mpu enable - mcr p15, 0, r4, c1, c0, 0 // write control register - - // Flush caches - mov r5, #0 - mcr p15, 0, r5, c7, c5, 0 // flush I-cache - mcr p15, 0, r5, c7, c6, 0 // flush D-cache - mcr p15, 0, r5, c7, c10, 4 // drain write buffer - - // Fixes mounting of SDMC +init: + // Disable IRQ + mrs r0, cpsr + orr r0, r0, #0x80 + msr cpsr_c, r0 + + // Flush caches, make sure to sync memory with what's on the cache before + // turning off the MPU + adr r0, flush_all_caches_offset + ldr r1, [r0] + add r0, r1, r0 + blx r0 + + // Disable caches and MPU + adr r0, disable_mpu_and_caching_offset + ldr r1, [r0] + add r0, r1, r0 + blx r0 + + // Flush caches, for good measure. Makes sure there is nothing in the caches + // when the MPU is brought back online. + adr r0, flush_all_caches_offset + ldr r1, [r0] + add r0, r1, r0 + blx r0 + + // FIXME should we attempt to save the last stack? + // Setup stacks + adr r0, setup_stacks_offset + ldr r1, [r0] + add r0, r1, r0 + blx r0 + + // Switch to system mode + mrs r0, cpsr + orr r1, r0, #0x1F + msr cpsr_c, r1 + + // Change the stack pointer + ldr sp, =0x27F00000 + + // make sure ITCM is accessible + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #(1<<18) + mcr p15, 0, r0, c1, c0, 0 + + // clear bss + adr r0, clear_bss_offset + ldr r1, [r0] + add r0, r1, r0 + blx r0 + + // Give read/write access to all the memory regions + ldr r0, =0x33333333 + mcr p15, 0, r0, c5, c0, 2 // write data access + mcr p15, 0, r0, c5, c0, 3 // write instruction access + + // Set MPU permissions and cache settings + ldr r0, =0xFFFF001D // ffff0000 32k | bootrom unprotected + ldr r1, =0x3000801B // 30000000 16k | dtcm + ldr r2, =0x00000035 // 00000000 128MB | 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 + ldr r7, =0x1800002D // 18000000 8M + 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, #0xA5 // FIXME which sections does this do... stuff to? + 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 caches and MPU + adr r0, enable_mpu_and_caching_offset + ldr r1, [r0] + add r0, r1, r0 + blx r0 + + // Fix mounting of SDMC ldr r0, =0x10000020 mov r1, #0x340 str r1, [r0] + // Reload argc and argv. ldr r0, argc ldr r1, argv - bl main + // Launch main(argc, argv) + adr r2, main_offset + ldr r3, [r2] + add r2, r3, r2 + blx r2 + bx lr + + die: + b die //if we return, just forcibly hang (should we attempt to call the rest vector???) + +disable_mpu_and_caching_offset: +.word disable_mpu_and_caching-. + +enable_mpu_and_caching_offset: +.word enable_mpu_and_caching-. + +relocate_section_offset: +.word relocate_section-. + +flush_all_caches_offset: +.word flush_all_caches-. + +setup_stacks_offset: +.word setup_stacks-. + +__bss_start_offset: +.word __bss_start-. + +__bss_end_offset: +.word __bss_end-. + +clear_bss_offset: +.word clear_bss-. + +main_offset: +.word main-. + +clear_bss: + //clear bss + adr r0, __bss_start_offset + ldr r1, [r0] + add r0, r1, r0 + + adr r1, __bss_end_offset + ldr r2, [r1] + add r1, r2, r1 + mov r2, #0 + .Lclear_bss_loop: + cmp r0, r1 + beq .Lclear_bss_loop_done + str r2, [r0], #4 + b .Lclear_bss_loop + .Lclear_bss_loop_done: + blx lr + +setup_stacks: + // Set up the stacks for all CPU modes + // start by clearing mode bits + mrs r0, cpsr + mov r2, r0 // preserve current mode + bic r0, r0, #0x1F + + // System mode + orr r1, r0, #0x1F + msr cpsr_c, r1 + ldr sp, =0x8000 + + // Abort mode + orr r1, r0, #0x17 + msr cpsr_c, r1 + ldr sp, =0x8000 + + // IRQ mode + orr r1, r0, #0x12 + msr cpsr_c, r1 + ldr sp, =0x8000 + + // FIQ mode + orr r1, r0, #0x11 + msr cpsr_c, r1 + ldr sp, =0x8000 + + // Supervisor mode + orr r1, r0, #0x13 + msr cpsr_c, r1 + ldr sp, =0x8000 + + // Restore prvious mode + msr cpsr_c, r2 + + blx lr + +disable_mpu_and_caching: + // Disable caches and MPU + mrc p15, 0, r0, c1, c0, 0 // read control register + bic r0, r0, #(1<<12) // - instruction cache enable + bic r0, r0, #(1<<2) // - data cache enable + bic r0, r0, #(1<<0) // - mpu enable + mcr p15, 0, r0, c1, c0, 0 // write control register + + bx lr + +enable_mpu_and_caching: + // Enable caches and MPU + mrc p15, 0, r0, c1, c0, 0 // read control register + orr r0, r0, #(1<<12) // - instruction cache enable + orr r0, r0, #(1<<2) // - data cache enable + orr r0, r0, #(1<<0) // - mpu enable + mcr p15, 0, r0, c1, c0, 0 // write control register + + bx lr + +// r0 - region start +// r1 - region end +// r2 - relocation base (usually starting PC address) +relocate_section: + + adr r2, relocation_base_offset + ldr r3, [r2] + add r2, r3, r2 + + .Lreloc_init: + cmp r0, r1 + beq .Lrelocinit_done + ldr r3, [r0] + add r3, r2, r3 + str r3, [r0], #4 + b .Lreloc_init + .Lrelocinit_done: + + bx lr + +relocation_base_offset: +.word _start-. + +flush_all_caches: + + // flush instruction cache, it's not flushed by Nintendo's function + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 + + // Nintendo's function uses r0-r2, r12, all registers that don't need + // to be saved, just be aware that they are changed + // use Nintendo's bx lr to return + ldr r0, =0xFFFF0830 // Nintendo's flush function in unprot. bootrom + bx r0 -.die: - b .die