startup.s 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /*********************************************************************
  2. *
  3. * Pascal Runtime Startup
  4. *
  5. *********************************************************************
  6. * Filename: startup.s
  7. *
  8. * Processor: PIC32
  9. *
  10. * Compiler: MPLAB XC32
  11. * MPLAB X IDE
  12. * Company: Microchip Technology Inc.
  13. *
  14. * Software License Agreement
  15. *
  16. * This software is developed by Microchip Technology Inc. and its
  17. * subsidiaries ("Microchip").
  18. *
  19. * Redistribution and use in source and binary forms, with or without
  20. * modification, are permitted provided that the following conditions are met:
  21. *
  22. * 1. Redistributions of source code must retain the above copyright
  23. * notice, this list of conditions and the following disclaimer.
  24. *
  25. * 2. Redistributions in binary form must reproduce the above copyright
  26. * notice, this list of conditions and the following disclaimer in the
  27. * documentation and/or other materials provided with the distribution.
  28. *
  29. * 3. Microchip's name may not be used to endorse or promote products
  30. * derived from this software without $specific prior written permission.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY MICROCHIP "AS IS" AND ANY EXPRESS OR IMPLIED
  33. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  34. * MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  35. * MICROCHIP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  36. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO
  37. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;
  38. * OR BUSINESS INTERRUPTION) HOWSOEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  39. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  40. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. ********************************************************************/
  44. ##################################################################
  45. # Entry point of the entire application
  46. ##################################################################
  47. .section .reset,"ax",@progbits
  48. .align 2
  49. .set noreorder
  50. .ent _reset
  51. _reset:
  52. la $k0, _startup
  53. jr $k0 # Jump to startup code
  54. nop
  55. .end _reset
  56. .globl _reset
  57. ##################################################################
  58. # Startup code
  59. ##################################################################
  60. .section .reset.startup,"ax",@progbits
  61. .align 2
  62. .set noreorder
  63. .ent _startup
  64. _startup:
  65. ##################################################################
  66. # If entered because of an NMI, jump to the NMI handler.
  67. ##################################################################
  68. mfc0 $k0,$12, 0 # _CP0_STATUS
  69. ext $k0,$k0,19,1 # Extract NMI bit
  70. beqz $k0,_no_nmi
  71. nop
  72. la $k0,_nmi_handler
  73. jr $k0
  74. nop
  75. _no_nmi:
  76. ##################################################################
  77. # Initialize Stack Pointer
  78. # _stack is initialized by the linker script to point to the
  79. # starting location of the stack in DRM
  80. ##################################################################
  81. la $sp,_stack_top
  82. ##################################################################
  83. # Initialize Global Pointer
  84. # _gp is initialized by the linker script to point to "middle"
  85. # of the small variables region
  86. ##################################################################
  87. la $gp,_gp
  88. ##################################################################
  89. # Initialize Global Pointer in Shadow Set
  90. # The SRSCtl's PSS field must be set to the shadow set in which
  91. # to initialize the global pointer. Since we only have a
  92. # single shadow set (besides the normal), we will initialize
  93. # SRSCtl<PSS> to SRSCtl<HSS>. We then write the global pointer
  94. # to the previous shadow set to ensure that on interrupt, the
  95. # global pointer has been initialized.
  96. ##################################################################
  97. mfc0 $t1,$12, 2 #_CP0_SRSCTL # Read SRSCtl register
  98. add $t3,$t1,$zero # Save off current SRSCtl
  99. ext $t2,$t1,26,4 # to obtain HSS field
  100. ins $t1,$t2,6,4 # Put HSS field
  101. mtc0 $t1,$12, 2 #_CP0_SRSCTL # into SRSCtl<PSS>
  102. ehb # Clear hazard before using new SRSCTL
  103. wrpgpr $gp,$gp # Set global pointer in PSS
  104. mtc0 $t3,$12, 2 #_CP0_SRSCTL # Restore SRSCtl
  105. ##################################################################
  106. # Call the "on reset" procedure
  107. ##################################################################
  108. # la $t0,_on_reset
  109. # jalr $t0
  110. # nop
  111. ##################################################################
  112. # Clear uninitialized data sections
  113. ##################################################################
  114. la $t0,_bss_start
  115. la $t1,_bss_end
  116. b _bss_check
  117. nop
  118. _bss_init:
  119. sw $zero,0x0($t0)
  120. sw $zero,0x4($t0)
  121. sw $zero,0x8($t0)
  122. sw $zero,0xc($t0)
  123. addu $t0,16
  124. _bss_check:
  125. bltu $t0,$t1,_bss_init
  126. nop
  127. ##################################################################
  128. # Copy initialized data from program flash to data memory
  129. # src=_data_image_begin dst=_data_begin stop=_data_end
  130. ##################################################################
  131. la $t0,_etext
  132. la $t1,_data
  133. la $t2,_edata
  134. b _init_check
  135. nop
  136. _init_data:
  137. lw $t3,($t0)
  138. sw $t3,($t1)
  139. addu $t0,4
  140. addu $t1,4
  141. _init_check:
  142. bltu $t1,$t2,_init_data
  143. nop
  144. ##################################################################
  145. # If there are no RAM functions, skip the next two sections --
  146. # copying RAM functions from program flash to data memory and
  147. # initializing bus matrix registers.
  148. ##################################################################
  149. # la $t1,_ramfunc_length
  150. # beqz $t1,_ramfunc_done
  151. # nop
  152. ##################################################################
  153. # Copy RAM functions from program flash to data memory
  154. # src=_ramfunc_image_begin dst=_ramfunc_begin stop=_ramfunc_end
  155. ##################################################################
  156. # la $t0,_ramfunc_image_begin
  157. # la $t1,_ramfunc_begin
  158. # la $t2,_ramfunc_end
  159. #_init_ramfunc:
  160. # lw $t3,($t0)
  161. # sw $t3,($t1)
  162. # addu $t0,4
  163. # addu $t1,4
  164. #_ramfunc_check:
  165. # bltu $t1,$t2,_init_ramfunc
  166. # nop
  167. ##################################################################
  168. # Initialize bus matrix registers if RAM functions exist in the
  169. # application
  170. ##################################################################
  171. # la $t1,_bmxdkpba_address
  172. # la $t2,BMXDKPBA
  173. # sw $t1,0($t2)
  174. # la $t1,_bmxdudba_address
  175. # la $t2,BMXDUDBA
  176. # sw $t1,0($t2)
  177. # la $t1,_bmxdupba_address
  178. # la $t2,BMXDUPBA
  179. # sw $t1,0($t2)
  180. #_ramfunc_done:
  181. ##################################################################
  182. # Initialize CP0 registers
  183. ##################################################################
  184. # Initialize Count register
  185. ##################################################################
  186. mtc0 $zero,$9, 0 #_CP0_COUNT
  187. ##################################################################
  188. # Initialize Compare register
  189. ##################################################################
  190. li $t2,-1
  191. mtc0 $t2,$11, 0 #_CP0_COMPARE
  192. ##################################################################
  193. # Initialize EBase register
  194. ##################################################################
  195. la $t1,_ebase_address
  196. mtc0 $t1,$15, 1 #_CP0_EBASE
  197. ##################################################################
  198. # Initialize IntCtl register
  199. ##################################################################
  200. la $t1,_vector_spacing
  201. li $t2,0 # Clear $t2 and
  202. ins $t2,$t1,5,5 # shift value to VS field
  203. mtc0 $t2,$12, 1 #_CP0_INTCTL
  204. ##################################################################
  205. # Initialize CAUSE registers
  206. # - Enable counting of Count register <DC = 0>
  207. # - Use $special exception vector <IV = 1>
  208. # - Clear pending software interrupts <IP1:IP0 = 0>
  209. ##################################################################
  210. li $t1,0x00800000
  211. mtc0 $t1,$13, 0 #_CP0_CAUSE
  212. ##################################################################
  213. # Initialize STATUS register
  214. # - Access to Coprocessor 0 not allowed in user mode <CU0 = 0>
  215. # - User mode uses configured endianness <RE = 0>
  216. # - Preserve Bootstrap Exception vectors <BEV>
  217. # - Preserve soft reset <SR> and non-maskable interrupt <NMI>
  218. # - CorExtend enabled based on whether CorExtend User Defined
  219. # Instructions have been implemented <CEE = Config<UDI>>
  220. # - Disable any pending interrups <IM7..IM2 = 0, IM1..IM0 = 0>
  221. # - Disable hardware interrupts <IPL7:IPL2 = 0>
  222. # - Base mode is Kernel mode <UM = 0>
  223. # - Error level is normal <ERL = 0>
  224. # - Exception level is normal <EXL = 0>
  225. # - Interrupts are disabled <IE = 0>
  226. ##################################################################
  227. mfc0 $t0,$16, 0 #_CP0_CONFIG
  228. ext $t1,$t0,22,1 # Extract UDI from Config register
  229. sll $t1,$t1,17 # Move UDI to Status.CEE location
  230. mfc0 $t0,$12, 0 #_CP0_STATUS
  231. and $t0,$t0,0x00580000 # Preserve SR, NMI, and BEV
  232. or $t0,$t1,$t0 # Include Status.CEE (from UDI)
  233. mtc0 $t0,$12, 0 #_CP0_STATUS
  234. ##################################################################
  235. # Call the "on bootstrap" procedure
  236. ##################################################################
  237. # la $t0,_on_bootstrap
  238. # jalr $t0
  239. # nop
  240. ##################################################################
  241. # Initialize Status<BEV> for normal exception vectors
  242. ##################################################################
  243. mfc0 $t0,$12, 0 # _CP0_STATUS
  244. and $t0,$t0,0xffbfffff # Clear BEV
  245. mtc0 $t0,$12, 0 # _CP0_STATUS
  246. ##################################################################
  247. # Call main. We do this via a thunk in the text section so that
  248. # a normal jump and link can be used, enabling the startup code
  249. # to work properly whether main is written in MIPS16 or MIPS32
  250. # code. I.e., the linker will correctly adjust the JAL to JALX if
  251. # necessary
  252. ##################################################################
  253. and $a0,$a0,0
  254. and $a1,$a1,0
  255. la $t0,_main_entry
  256. jr $t0
  257. nop
  258. .end _startup
  259. .globl _startup
  260. ##################################################################
  261. # Boot Exception Vector Handler
  262. # Jumps to _bootstrap_exception_handler
  263. ##################################################################
  264. .section .bev_handler,"ax",@progbits
  265. .align 2
  266. .set noreorder
  267. .ent _bev_exception
  268. _bev_exception:
  269. la $k0,_bootstrap_exception_handler
  270. jr $k0
  271. nop
  272. .end _bev_exception
  273. ##################################################################
  274. # General Exception Vector Handler
  275. # Jump to _general_exception_handler
  276. ##################################################################
  277. .section .gen_handler,"ax",@progbits
  278. .align 2
  279. .set noreorder
  280. .ent _gen_exception
  281. _gen_exception:
  282. #la $k0,_general_exception_context
  283. la $k0,_DefaultInterrupt
  284. jr $k0
  285. nop
  286. .end _gen_exception
  287. .text
  288. .ent _main_entry
  289. _main_entry:
  290. and $a0,$a0,0
  291. and $a1,$a1,0
  292. ##################################################################
  293. # Call main
  294. ##################################################################
  295. jal main
  296. nop
  297. ##################################################################
  298. # Just in case, go into infinite loop
  299. ##################################################################
  300. j _haltproc
  301. nop
  302. .end _main_entry
  303. ##################################################################
  304. # Haltproc
  305. ##################################################################
  306. .text
  307. .align 2
  308. .weak _haltproc
  309. .set nomips16
  310. .ent _haltproc
  311. _haltproc:
  312. b _haltproc
  313. nop
  314. sdbbp 0
  315. .set macro
  316. .set reorder
  317. .globl _haltproc
  318. .end _haltproc
  319. .size _haltproc, .-_haltproc
  320. ##################################################################
  321. # NMI Handler
  322. ##################################################################
  323. .text
  324. .align 2
  325. .weak _nmi_handler
  326. .set nomips16
  327. .ent _nmi_handler
  328. _nmi_handler:
  329. .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
  330. .mask 0x00000000,0
  331. .fmask 0x00000000,0
  332. .set noreorder
  333. mfc0 $k0, $12, 0 # _CP0_STATUS # retrieve STATUS
  334. lui $k1, ~(0x00400000 >> 16) & 0xffff # _CP0_STATUS_BEV_MASK = 0x00400000
  335. ori $k1, $k1, ~0x00400000 & 0xffff # _CP0_STATUS_BEV_MASK = 0x00400000
  336. and $k0, $k0, $k1 # Clear BEV
  337. mtc0 $k0, $12, 0 # _CP0_STATUS # store STATUS
  338. eret
  339. .set macro
  340. .set reorder
  341. .end _nmi_handler
  342. .size _nmi_handler, .-_nmi_handler
  343. ##################################################################
  344. # _bootstrap_exception_handler
  345. ##################################################################
  346. .text
  347. .align 2
  348. .weak _bootstrap_exception_handler
  349. .set nomips16
  350. .ent _bootstrap_exception_handler
  351. _bootstrap_exception_handler:
  352. sdbbp 0
  353. b _bootstrap_exception_handler
  354. .set macro
  355. .set reorder
  356. .end _bootstrap_exception_handler
  357. .size _bootstrap_exception_handler, .-_bootstrap_exception_handler
  358. ##################################################################
  359. # _DefaultInterrupt
  360. ##################################################################
  361. .text
  362. .align 2
  363. .weak _DefaultInterrupt
  364. .set nomips16
  365. .ent _DefaultInterrupt
  366. _DefaultInterrupt:
  367. sdbbp 0
  368. b _DefaultInterrupt
  369. .set macro
  370. .set reorder
  371. .end _DefaultInterrupt
  372. .size _DefaultInterrupt, .-_DefaultInterrupt