crt0.S 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // this file was taken from libogc, see http://www.devkitpro.org/
  2. #include "asm.h"
  3. #define _SDA_BASE_ 32768
  4. #define _SDA2_BASE_ 32768
  5. .text
  6. .section .init
  7. # crt0.s file for the GameCube V1.1 by Costis (costis@gbaemu.com)!
  8. #
  9. # Updates: Added support for clearing the BSS section so that global
  10. # variables are cleared to 0 upon start-up.
  11. #
  12. # This is start-up code for initializing the GameCube system and hardware
  13. # before executing the actual user program code. It clears the GPR's,
  14. # initializes the FPR's, initializes the Data, Code, and L2 caches, clears
  15. # and initializes SPR's, and disables exceptions (interrupts).
  16. #
  17. # Have fun!!! Please e-mail any suggestions or bugs to costis@gbaemu.com.
  18. # Entry Point
  19. .extern __PSInit
  20. .extern __SyscallInit
  21. .extern __CacheInit
  22. .extern __SystemInit
  23. .extern __sbss_start, __bss_end
  24. .extern __bat_config
  25. .extern _main
  26. .globl _start, __main
  27. _start:
  28. b startup
  29. .ascii "STUB"
  30. .ascii "HAXX"
  31. .long 0
  32. startup:
  33. # Disable interrupts first thing
  34. mfmsr r3
  35. rlwinm r4,r3,0,17,15
  36. rlwinm r4,r4,0,26,24
  37. mtmsr r4
  38. # Go into real mode
  39. isync
  40. lis r3,real@h
  41. ori r3,r3,real@l
  42. clrlwi r3,r3,2
  43. mtsrr0 r3
  44. mfmsr r3
  45. li r4,0x30
  46. andc r3,r3,r4
  47. mtsrr1 r3
  48. rfi
  49. real:
  50. # Set up the BATs the way we like them
  51. // HID0 = 00110c64:
  52. // bus checkstops off, sleep modes off,
  53. // caches off, caches invalidate,
  54. // store gathering off, enable data cache
  55. // flush assist, enable branch target cache,
  56. // enable branch history table
  57. lis 3,0x0011 ; ori 3,3,0x0c64 ; mtspr 1008,3 ; isync
  58. // MSR = 00002000 (FP on)
  59. li 4,0x2000 ; mtmsr 4
  60. // HID0 |= 0000c000 (caches on)
  61. ori 3,3,0xc000 ; mtspr 1008,3 ; isync
  62. // clear all BATs
  63. li 0,0
  64. mtspr 528,0 ; mtspr 530,0 ; mtspr 532,0 ; mtspr 534,0 // IBATU 0..3
  65. mtspr 536,0 ; mtspr 538,0 ; mtspr 540,0 ; mtspr 542,0 // DBATU 0..3
  66. mtspr 560,0 ; mtspr 562,0 ; mtspr 564,0 ; mtspr 566,0 // IBATU 4..7
  67. mtspr 568,0 ; mtspr 570,0 ; mtspr 572,0 ; mtspr 574,0 // DBATU 4..7
  68. isync
  69. // clear all SRs
  70. lis 0,0x8000
  71. mtsr 0,0 ; mtsr 1,0 ; mtsr 2,0 ; mtsr 3,0
  72. mtsr 4,0 ; mtsr 5,0 ; mtsr 6,0 ; mtsr 7,0
  73. mtsr 8,0 ; mtsr 9,0 ; mtsr 10,0 ; mtsr 11,0
  74. mtsr 12,0 ; mtsr 13,0 ; mtsr 14,0 ; mtsr 15,0
  75. isync
  76. // set [DI]BAT0 for 256MB@80000000,
  77. // real 00000000, WIMG=0000, R/W
  78. li 3,2 ; lis 4,0x8000 ; ori 4,4,0x1fff
  79. mtspr IBAT0L,3 ; mtspr IBAT0U,4 ; mtspr DBAT0L,3 ; mtspr DBAT0U,4 ; isync
  80. // set [DI]BAT4 for 256MB@90000000,
  81. // real 10000000, WIMG=0000, R/W
  82. addis 3,3,0x1000 ; addis 4,4,0x1000
  83. mtspr IBAT4L,3 ; mtspr IBAT4U,4 ; mtspr DBAT4L,3 ; mtspr DBAT4U,4 ; isync
  84. // set DBAT1 for 256MB@c0000000,
  85. // real 00000000, WIMG=0101, R/W
  86. li 3,0x2a ; lis 4,0xc000 ; ori 4,4,0x1fff
  87. mtspr DBAT1L,3 ; mtspr DBAT1U,4 ; isync
  88. // set DBAT5 for 256MB@d0000000,
  89. // real 10000000, WIMG=0101, R/W
  90. addis 3,3,0x1000 ; addis 4,4,0x1000
  91. mtspr DBAT5L,3 ; mtspr DBAT5U,4 ; isync
  92. // enable [DI]BAT4-7 in HID4
  93. lis 3, 0x8200
  94. mtspr 1011,3
  95. // set MSR[DR:IR] = 11, jump to _start
  96. lis 3,virtual@h ; ori 3,3, virtual@l ; mtsrr0 3
  97. mfmsr 3 ; ori 3,3,0x30 ; mtsrr1 3
  98. rfi
  99. virtual:
  100. bl InitGPRS # Initialize the General Purpose Registers
  101. bl __CacheInit # Initialize the system caches
  102. bl __SyscallInit # Initialize the System Call handler
  103. bl __SystemInit # Initialize more cache aspects, clear a few SPR's, and disable interrupts.
  104. # Clear the BSS section!
  105. lis r3,__sbss_start@h
  106. ori r3,r3,__sbss_start@l
  107. li r4,0
  108. lis r5,__bss_end@h
  109. ori r5,r5,__bss_end@l
  110. sub r5,r5,r3
  111. bl _memset
  112. bl _main # Branch to the user code!
  113. eloop:
  114. b eloop # If the main function returns, which should never happen then just loop endlessly.
  115. InitGPRS:
  116. # Clear all of the GPR's to 0
  117. li r0,0
  118. li r3,0
  119. li r4,0
  120. li r5,0
  121. li r6,0
  122. li r7,0
  123. li r8,0
  124. li r9,0
  125. li r10,0
  126. li r11,0
  127. li r12,0
  128. li r14,0
  129. li r15,0
  130. li r16,0
  131. li r17,0
  132. li r18,0
  133. li r19,0
  134. li r20,0
  135. li r21,0
  136. li r22,0
  137. li r23,0
  138. li r24,0
  139. li r25,0
  140. li r26,0
  141. li r27,0
  142. li r28,0
  143. li r29,0
  144. li r30,0
  145. li r31,0
  146. lis sp,__crt0stack@h # we take 0x8173FFF0 as the topmost starting point for our stack,this gives us ~128Kb Stack
  147. ori sp,sp,__crt0stack@l
  148. addi sp,sp,-4
  149. stw r0,0(sp)
  150. stwu sp,-56(sp)
  151. lis r2,_SDA2_BASE_@h
  152. ori r2,r2,_SDA2_BASE_@l # Set the Small Data 2 (Read Only) base register.
  153. lis r13,_SDA_BASE_@h
  154. ori r13,r13,_SDA_BASE_@l # Set the Small Data (Read\Write) base register.
  155. blr
  156. //r3 = ptr, r4 = fill, r5 = size
  157. .globl _memset
  158. _memset:
  159. clrlwi. r6,r5,29
  160. srwi r5,r5,2
  161. subi r3,r3,4
  162. mtctr r5
  163. 1: stwu r4,4(r3)
  164. bdnz 1b
  165. cmplwi r6,0
  166. beq 3f
  167. 2: stbu r4,1(r3)
  168. addic. r6,r6,-1
  169. bne+ 2b
  170. 3: blr
  171. .section .bss
  172. .balign 8
  173. __crt0stack_end:
  174. .space 0x8000
  175. __crt0stack: