handlers.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * -----------------------------------------------------------------------------
  19. *
  20. * Project: CMSIS-RTOS RTX
  21. * Title: Exception handlers (C functions)
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. #include "RTE_Components.h"
  26. #include CMSIS_device_header
  27. //Fault Status Register (IFSR/DFSR) definitions
  28. #define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
  29. #define FSR_INSTRUCTION_CACHE_MAINTENANCE 0x04 //DFSR only - async/external
  30. #define FSR_SYNC_EXT_TTB_WALK_FIRST 0x0c //sync/external
  31. #define FSR_SYNC_EXT_TTB_WALK_SECOND 0x0e //sync/external
  32. #define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
  33. #define FSR_SYNC_PARITY_TTB_WALK_SECOND 0x1e //sync/external
  34. #define FSR_TRANSLATION_FAULT_FIRST 0x05 //MMU Fault - internal
  35. #define FSR_TRANSLATION_FAULT_SECOND 0x07 //MMU Fault - internal
  36. #define FSR_ACCESS_FLAG_FAULT_FIRST 0x03 //MMU Fault - internal
  37. #define FSR_ACCESS_FLAG_FAULT_SECOND 0x06 //MMU Fault - internal
  38. #define FSR_DOMAIN_FAULT_FIRST 0x09 //MMU Fault - internal
  39. #define FSR_DOMAIN_FAULT_SECOND 0x0b //MMU Fault - internal
  40. #define FSR_PERMISSION_FAULT_FIRST 0x0f //MMU Fault - internal
  41. #define FSR_PERMISSION_FAULT_SECOND 0x0d //MMU Fault - internal
  42. #define FSR_DEBUG_EVENT 0x02 //internal
  43. #define FSR_SYNC_EXT_ABORT 0x08 //sync/external
  44. #define FSR_TLB_CONFLICT_ABORT 0x10 //sync/external
  45. #define FSR_LOCKDOWN 0x14 //internal
  46. #define FSR_COPROCESSOR_ABORT 0x1a //internal
  47. #define FSR_SYNC_PARITY_ERROR 0x19 //sync/external
  48. #define FSR_ASYNC_EXTERNAL_ABORT 0x16 //DFSR only - async/external
  49. #define FSR_ASYNC_PARITY_ERROR 0x18 //DFSR only - async/external
  50. void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
  51. uint32_t FS = (DFSR & (1U << 10U)) >> 6U | (DFSR & 0x0FU); //Store Fault Status
  52. (void)DFAR;
  53. (void)LR;
  54. switch(FS) {
  55. //Synchronous parity errors - retry
  56. case FSR_SYNC_PARITY_ERROR:
  57. case FSR_SYNC_PARITY_TTB_WALK_FIRST:
  58. case FSR_SYNC_PARITY_TTB_WALK_SECOND:
  59. return;
  60. //Your code here. Value in DFAR is invalid for some fault statuses.
  61. case FSR_ALIGNMENT_FAULT:
  62. case FSR_INSTRUCTION_CACHE_MAINTENANCE:
  63. case FSR_SYNC_EXT_TTB_WALK_FIRST:
  64. case FSR_SYNC_EXT_TTB_WALK_SECOND:
  65. case FSR_TRANSLATION_FAULT_FIRST:
  66. case FSR_TRANSLATION_FAULT_SECOND:
  67. case FSR_ACCESS_FLAG_FAULT_FIRST:
  68. case FSR_ACCESS_FLAG_FAULT_SECOND:
  69. case FSR_DOMAIN_FAULT_FIRST:
  70. case FSR_DOMAIN_FAULT_SECOND:
  71. case FSR_PERMISSION_FAULT_FIRST:
  72. case FSR_PERMISSION_FAULT_SECOND:
  73. case FSR_DEBUG_EVENT:
  74. case FSR_SYNC_EXT_ABORT:
  75. case FSR_TLB_CONFLICT_ABORT:
  76. case FSR_LOCKDOWN:
  77. case FSR_COPROCESSOR_ABORT:
  78. case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid
  79. case FSR_ASYNC_PARITY_ERROR: //DFAR invalid
  80. default:
  81. while(1);
  82. }
  83. }
  84. void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
  85. uint32_t FS = (IFSR & (1U << 10U)) >> 6U | (IFSR & 0x0FU); //Store Fault Status
  86. (void)IFAR;
  87. (void)LR;
  88. switch(FS) {
  89. //Synchronous parity errors - retry
  90. case FSR_SYNC_PARITY_ERROR:
  91. case FSR_SYNC_PARITY_TTB_WALK_FIRST:
  92. case FSR_SYNC_PARITY_TTB_WALK_SECOND:
  93. return;
  94. //Your code here. Value in IFAR is invalid for some fault statuses.
  95. case FSR_SYNC_EXT_TTB_WALK_FIRST:
  96. case FSR_SYNC_EXT_TTB_WALK_SECOND:
  97. case FSR_TRANSLATION_FAULT_FIRST:
  98. case FSR_TRANSLATION_FAULT_SECOND:
  99. case FSR_ACCESS_FLAG_FAULT_FIRST:
  100. case FSR_ACCESS_FLAG_FAULT_SECOND:
  101. case FSR_DOMAIN_FAULT_FIRST:
  102. case FSR_DOMAIN_FAULT_SECOND:
  103. case FSR_PERMISSION_FAULT_FIRST:
  104. case FSR_PERMISSION_FAULT_SECOND:
  105. case FSR_DEBUG_EVENT: //IFAR invalid
  106. case FSR_SYNC_EXT_ABORT:
  107. case FSR_TLB_CONFLICT_ABORT:
  108. case FSR_LOCKDOWN:
  109. case FSR_COPROCESSOR_ABORT:
  110. default:
  111. while(1);
  112. }
  113. }
  114. //returns amount to decrement lr by
  115. //this will be 0 when we have emulated the instruction and want to execute the next instruction
  116. //this will be 2 when we have performed some maintenance and want to retry the instruction in Thumb (state == 2)
  117. //this will be 4 when we have performed some maintenance and want to retry the instruction in Arm (state == 4)
  118. uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
  119. const uint32_t THUMB = 2U;
  120. const uint32_t ARM = 4U;
  121. (void)LR;
  122. //Lazy VFP/NEON initialisation and switching
  123. // (Arm Architecture Reference Manual section A7.5) VFP data processing instruction?
  124. // (Arm Architecture Reference Manual section A7.6) VFP/NEON register load/store instruction?
  125. // (Arm Architecture Reference Manual section A7.8) VFP/NEON register data transfer instruction?
  126. // (Arm Architecture Reference Manual section A7.9) VFP/NEON 64-bit register data transfer instruction?
  127. if ((state == ARM && ((opcode & 0x0C000000U) >> 26U == 0x03U)) ||
  128. (state == THUMB && ((opcode & 0xEC000000U) >> 26U == 0x3BU))) {
  129. if (((opcode & 0x00000E00U) >> 9U) == 5U) {
  130. __FPU_Enable();
  131. return state;
  132. }
  133. }
  134. // (Arm Architecture Reference Manual section A7.4) NEON data processing instruction?
  135. if ((state == ARM && ((opcode & 0xFE000000U) >> 24U == 0xF2U)) ||
  136. (state == THUMB && ((opcode & 0xEF000000U) >> 24U == 0xEFU)) ||
  137. // (Arm Architecture Reference Manual section A7.7) NEON load/store instruction?
  138. (state == ARM && ((opcode >> 24U) == 0xF4U)) ||
  139. (state == THUMB && ((opcode >> 24U) == 0xF9U))) {
  140. __FPU_Enable();
  141. return state;
  142. }
  143. //Add code here for other Undef cases
  144. while(1);
  145. }