123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // this file was taken from libogc, see http://www.devkitpro.org/
- #include "asm.h"
- #define _SDA_BASE_ 32768
- #define _SDA2_BASE_ 32768
- .text
- .section .init
- # crt0.s file for the GameCube V1.1 by Costis (costis@gbaemu.com)!
- #
- # Updates: Added support for clearing the BSS section so that global
- # variables are cleared to 0 upon start-up.
- #
- # This is start-up code for initializing the GameCube system and hardware
- # before executing the actual user program code. It clears the GPR's,
- # initializes the FPR's, initializes the Data, Code, and L2 caches, clears
- # and initializes SPR's, and disables exceptions (interrupts).
- #
- # Have fun!!! Please e-mail any suggestions or bugs to costis@gbaemu.com.
- # Entry Point
- .extern __PSInit
- .extern __SyscallInit
- .extern __CacheInit
- .extern __SystemInit
- .extern __sbss_start, __bss_end
- .extern __bat_config
- .extern _main
- .globl _start, __main
- _start:
- b startup
- .ascii "STUB"
- .ascii "HAXX"
- .long 0
- startup:
- # Disable interrupts first thing
- mfmsr r3
- rlwinm r4,r3,0,17,15
- rlwinm r4,r4,0,26,24
- mtmsr r4
- # Go into real mode
- isync
- lis r3,real@h
- ori r3,r3,real@l
- clrlwi r3,r3,2
- mtsrr0 r3
- mfmsr r3
- li r4,0x30
- andc r3,r3,r4
- mtsrr1 r3
- rfi
-
- real:
- # Set up the BATs the way we like them
- // HID0 = 00110c64:
- // bus checkstops off, sleep modes off,
- // caches off, caches invalidate,
- // store gathering off, enable data cache
- // flush assist, enable branch target cache,
- // enable branch history table
- lis 3,0x0011 ; ori 3,3,0x0c64 ; mtspr 1008,3 ; isync
- // MSR = 00002000 (FP on)
- li 4,0x2000 ; mtmsr 4
- // HID0 |= 0000c000 (caches on)
- ori 3,3,0xc000 ; mtspr 1008,3 ; isync
- // clear all BATs
- li 0,0
- mtspr 528,0 ; mtspr 530,0 ; mtspr 532,0 ; mtspr 534,0 // IBATU 0..3
- mtspr 536,0 ; mtspr 538,0 ; mtspr 540,0 ; mtspr 542,0 // DBATU 0..3
- mtspr 560,0 ; mtspr 562,0 ; mtspr 564,0 ; mtspr 566,0 // IBATU 4..7
- mtspr 568,0 ; mtspr 570,0 ; mtspr 572,0 ; mtspr 574,0 // DBATU 4..7
- isync
- // clear all SRs
- lis 0,0x8000
- mtsr 0,0 ; mtsr 1,0 ; mtsr 2,0 ; mtsr 3,0
- mtsr 4,0 ; mtsr 5,0 ; mtsr 6,0 ; mtsr 7,0
- mtsr 8,0 ; mtsr 9,0 ; mtsr 10,0 ; mtsr 11,0
- mtsr 12,0 ; mtsr 13,0 ; mtsr 14,0 ; mtsr 15,0
- isync
- // set [DI]BAT0 for 256MB@80000000,
- // real 00000000, WIMG=0000, R/W
- li 3,2 ; lis 4,0x8000 ; ori 4,4,0x1fff
- mtspr IBAT0L,3 ; mtspr IBAT0U,4 ; mtspr DBAT0L,3 ; mtspr DBAT0U,4 ; isync
- // set [DI]BAT4 for 256MB@90000000,
- // real 10000000, WIMG=0000, R/W
- addis 3,3,0x1000 ; addis 4,4,0x1000
- mtspr IBAT4L,3 ; mtspr IBAT4U,4 ; mtspr DBAT4L,3 ; mtspr DBAT4U,4 ; isync
- // set DBAT1 for 256MB@c0000000,
- // real 00000000, WIMG=0101, R/W
- li 3,0x2a ; lis 4,0xc000 ; ori 4,4,0x1fff
- mtspr DBAT1L,3 ; mtspr DBAT1U,4 ; isync
- // set DBAT5 for 256MB@d0000000,
- // real 10000000, WIMG=0101, R/W
- addis 3,3,0x1000 ; addis 4,4,0x1000
- mtspr DBAT5L,3 ; mtspr DBAT5U,4 ; isync
- // enable [DI]BAT4-7 in HID4
- lis 3, 0x8200
- mtspr 1011,3
- // set MSR[DR:IR] = 11, jump to _start
- lis 3,virtual@h ; ori 3,3, virtual@l ; mtsrr0 3
- mfmsr 3 ; ori 3,3,0x30 ; mtsrr1 3
- rfi
- virtual:
- bl InitGPRS # Initialize the General Purpose Registers
- bl __CacheInit # Initialize the system caches
- bl __SyscallInit # Initialize the System Call handler
- bl __SystemInit # Initialize more cache aspects, clear a few SPR's, and disable interrupts.
- # Clear the BSS section!
- lis r3,__sbss_start@h
- ori r3,r3,__sbss_start@l
- li r4,0
- lis r5,__bss_end@h
- ori r5,r5,__bss_end@l
- sub r5,r5,r3
- bl _memset
- bl _main # Branch to the user code!
- eloop:
- b eloop # If the main function returns, which should never happen then just loop endlessly.
- InitGPRS:
- # Clear all of the GPR's to 0
- li r0,0
- li r3,0
- li r4,0
- li r5,0
- li r6,0
- li r7,0
- li r8,0
- li r9,0
- li r10,0
- li r11,0
- li r12,0
- li r14,0
- li r15,0
- li r16,0
- li r17,0
- li r18,0
- li r19,0
- li r20,0
- li r21,0
- li r22,0
- li r23,0
- li r24,0
- li r25,0
- li r26,0
- li r27,0
- li r28,0
- li r29,0
- li r30,0
- li r31,0
- lis sp,__crt0stack@h # we take 0x8173FFF0 as the topmost starting point for our stack,this gives us ~128Kb Stack
- ori sp,sp,__crt0stack@l
- addi sp,sp,-4
- stw r0,0(sp)
- stwu sp,-56(sp)
- lis r2,_SDA2_BASE_@h
- ori r2,r2,_SDA2_BASE_@l # Set the Small Data 2 (Read Only) base register.
- lis r13,_SDA_BASE_@h
- ori r13,r13,_SDA_BASE_@l # Set the Small Data (Read\Write) base register.
- blr
- //r3 = ptr, r4 = fill, r5 = size
- .globl _memset
- _memset:
- clrlwi. r6,r5,29
- srwi r5,r5,2
- subi r3,r3,4
- mtctr r5
- 1: stwu r4,4(r3)
- bdnz 1b
- cmplwi r6,0
- beq 3f
- 2: stbu r4,1(r3)
- addic. r6,r6,-1
- bne+ 2b
- 3: blr
- .section .bss
- .balign 8
- __crt0stack_end:
- .space 0x8000
- __crt0stack:
|