argv: .int 0x00000000
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, #0b10101001 // 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.
+ // 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, #0b10101001 // 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
- // Launch main(argc, argv)
- adr r2, main_offset
- ldr r3, [r2]
- add r2, r3, r2
- blx r2
- bx lr
+ // 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???)
+ 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-.
.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
+ //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
+ // 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
+ // 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
+ bx lr
enable_mpu_and_caching:
- // Enable caches, MPU, and itcm
- mrc p15, 0, r0, c1, c0, 0 // read control register
- orr r0, r0, #(1<<18) // - itcm enable
- 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
+ // Enable caches, MPU, and itcm
+ mrc p15, 0, r0, c1, c0, 0 // read control register
+ orr r0, r0, #(1<<18) // - itcm enable
+ 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
+ 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
+ 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:
+ .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
+ 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
+ // 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
+ // 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