exception_gcc.S 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /**
  2. * \file
  3. *
  4. * \brief Exception and interrupt vectors mapping for the INTC Software Driver.
  5. *
  6. * Copyright (c) 2009-2018 Microchip Technology Inc. and its subsidiaries.
  7. *
  8. * \asf_license_start
  9. *
  10. * \page License
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright notice,
  16. * this list of conditions and the following disclaimer.
  17. *
  18. * 2. Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. *
  22. * 3. The name of Atmel may not be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * 4. This software may only be redistributed and used in connection with an
  26. * Atmel microcontroller product.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  31. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  32. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  36. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * \asf_license_stop
  41. *
  42. */
  43. #if !__AVR32_UC__ && !__AVR32_AP__
  44. #error Implementation for the AVR32 architecture only.
  45. #endif
  46. #include <avr32/io.h>
  47. //! @{
  48. //! \verbatim
  49. .section .exception, "ax", @progbits
  50. // Start of Exception Vector Table.
  51. /*
  52. * EVBA must be aligned with a power of two strictly greater than the
  53. * EVBA-relative offset of the last vector.
  54. */
  55. .balign 0x200
  56. // Export symbol.
  57. .global _evba
  58. .type _evba, @function
  59. _evba:
  60. .org 0x000
  61. // Unrecoverable Exception.
  62. _handle_Unrecoverable_Exception:
  63. rjmp $
  64. .org 0x004
  65. // TLB Multiple Hit.
  66. _handle_TLB_Multiple_Hit:
  67. rjmp $
  68. .org 0x008
  69. // Bus Error Data Fetch.
  70. _handle_Bus_Error_Data_Fetch:
  71. rjmp $
  72. .org 0x00C
  73. // Bus Error Instruction Fetch.
  74. _handle_Bus_Error_Instruction_Fetch:
  75. rjmp $
  76. .org 0x010
  77. // NMI.
  78. _handle_NMI:
  79. rjmp $
  80. .org 0x014
  81. // Instruction Address.
  82. _handle_Instruction_Address:
  83. rjmp $
  84. .org 0x018
  85. // ITLB Protection.
  86. _handle_ITLB_Protection:
  87. rjmp $
  88. .org 0x01C
  89. // Breakpoint.
  90. _handle_Breakpoint:
  91. rjmp $
  92. .org 0x020
  93. // Illegal Opcode.
  94. _handle_Illegal_Opcode:
  95. rjmp $
  96. .org 0x024
  97. // Unimplemented Instruction.
  98. _handle_Unimplemented_Instruction:
  99. rjmp $
  100. .org 0x028
  101. // Privilege Violation.
  102. _handle_Privilege_Violation:
  103. rjmp $
  104. .org 0x02C
  105. // Floating-Point: UNUSED IN AVR32UC and AVR32AP.
  106. _handle_Floating_Point:
  107. rjmp $
  108. .org 0x030
  109. // Coprocessor Absent: UNUSED IN AVR32UC.
  110. _handle_Coprocessor_Absent:
  111. rjmp $
  112. .org 0x034
  113. // Data Address (Read).
  114. _handle_Data_Address_Read:
  115. rjmp $
  116. .org 0x038
  117. // Data Address (Write).
  118. _handle_Data_Address_Write:
  119. rjmp $
  120. .org 0x03C
  121. // DTLB Protection (Read).
  122. _handle_DTLB_Protection_Read:
  123. rjmp $
  124. .org 0x040
  125. // DTLB Protection (Write).
  126. _handle_DTLB_Protection_Write:
  127. rjmp $
  128. .org 0x044
  129. // DTLB Modified: UNUSED IN AVR32UC.
  130. _handle_DTLB_Modified:
  131. rjmp $
  132. .org 0x050
  133. // ITLB Miss.
  134. _handle_ITLB_Miss:
  135. rjmp $
  136. .org 0x060
  137. // DTLB Miss (Read).
  138. _handle_DTLB_Miss_Read:
  139. rjmp $
  140. .org 0x070
  141. // DTLB Miss (Write).
  142. _handle_DTLB_Miss_Write:
  143. rjmp $
  144. .org 0x100
  145. // Supervisor Call.
  146. _handle_Supervisor_Call:
  147. rjmp $
  148. /*
  149. * Interrupt support.
  150. * The interrupt controller must provide the offset address relative to EVBA.
  151. * Important note:
  152. * All interrupts call a C function named _get_interrupt_handler.
  153. * This function will read group and interrupt line number to then return in
  154. *R12 a pointer to a user-provided interrupt handler.
  155. */
  156. .balign 4
  157. .irp priority, 0, 1, 2, 3
  158. .global _int\priority
  159. .type _int\priority, @function
  160. _int\priority:
  161. #if __AVR32_UC__
  162. /*
  163. * R8-R12, LR, PC and SR are automatically pushed onto the system stack
  164. * by the CPU upon interrupt entry. No other register is saved by
  165. * hardware.
  166. */
  167. #elif __AVR32_AP__
  168. /*
  169. * PC and SR are automatically saved in respectively RAR_INTx and
  170. * RSR_INTx by the CPU upon interrupt entry. No other register is saved
  171. * by hardware.
  172. */
  173. pushm r8-r12, lr
  174. #endif
  175. mov r12, \priority // Pass the int_level parameter to the _get_interrupt_handler function.
  176. call _get_interrupt_handler
  177. cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
  178. breq _spint\priority // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
  179. call rt_interrupt_enter
  180. icall r12
  181. call rt_interrupt_leave
  182. ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
  183. lda.w r12, rt_interrupt_nest /* Is nested interrupt? */
  184. ld.w r11, r12[0]
  185. cp.w r11, 0
  186. brne _spint\priority
  187. lda.w r12, rt_thread_switch_interrupt_flag /* Is thread switch required? */
  188. ld.w r11, r12[0]
  189. cp.w r11, 1
  190. breq rt_hw_context_switch_interrupt_do
  191. _spint\priority:
  192. csrf AVR32_SR_GM_OFFSET /* Enable global interrupt */
  193. #if __AVR32_UC__
  194. /*
  195. * If this was not a spurious interrupt (R12 != NULL), jump to the
  196. * handler.
  197. */
  198. /* movne pc, r12 */
  199. #elif __AVR32_AP__
  200. // If this was a spurious interrupt (R12 == NULL), branch.
  201. breq spint\priority
  202. /*
  203. * Push the pointer to the interrupt handler onto the system stack since
  204. * no register may be altered.
  205. */
  206. st.w --sp, r12
  207. popm r8-r12, lr, pc // Restore registers and jump to the handler.
  208. spint\priority:
  209. popm r8-r12, lr
  210. #endif
  211. /*
  212. * If this was a spurious interrupt (R12 == NULL), return from event
  213. * handler.
  214. */
  215. rete
  216. .endr
  217. rt_hw_context_switch_interrupt_do:
  218. mov r11, 0
  219. st.w r12[0], r11 /* Clear rt_thread_switch_interrupt_flag */
  220. stm --sp, r0-r7 /* Push R0-R7 */
  221. lda.w r12, rt_interrupt_from_thread /* Get old thread SP */
  222. ld.w r12, r12[0]
  223. lda.w r11, rt_interrupt_to_thread /* Get new thread SP */
  224. ld.w r11, r11[0]
  225. st.w r12[0], sp /* Store old thread SP */
  226. ld.w sp, r11[0] /* Load new thread SP */
  227. ldm sp++, r0-r7 /* Pop R0-R7 (new thread) */
  228. rete /* RETE pops R8-R12, LR, PC, SR automatically */
  229. // Constant data area.
  230. .balign 4
  231. // Values to store in the interrupt priority registers for the various interrupt priority levels.
  232. // The interrupt priority registers contain the interrupt priority level and
  233. // the EVBA-relative interrupt vector offset.
  234. .global ipr_val
  235. .type ipr_val, @object
  236. ipr_val:
  237. .word (AVR32_INTC_INT0 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int0 - _evba),\
  238. (AVR32_INTC_INT1 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int1 - _evba),\
  239. (AVR32_INTC_INT2 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int2 - _evba),\
  240. (AVR32_INTC_INT3 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int3 - _evba)
  241. //! \endverbatim
  242. //! @}