trap.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) 2021 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include "hpm_common.h"
  8. #include "hpm_soc.h"
  9. /********************** MCAUSE exception types **************************************/
  10. #define MCAUSE_INSTR_ADDR_MISALIGNED (0U) //!< Instruction Address misaligned
  11. #define MCAUSE_INSTR_ACCESS_FAULT (1U) //!< Instruction access fault
  12. #define MCAUSE_ILLEGAL_INSTR (2U) //!< Illegal instruction
  13. #define MCAUSE_BREAKPOINT (3U) //!< Breakpoint
  14. #define MCAUSE_LOAD_ADDR_MISALIGNED (4U) //!< Load address misaligned
  15. #define MCAUSE_LOAD_ACCESS_FAULT (5U) //!< Load access fault
  16. #define MCAUSE_STORE_AMO_ADDR_MISALIGNED (6U) //!< Store/AMO address misaligned
  17. #define MCAUSE_STORE_AMO_ACCESS_FAULT (7U) //!< Store/AMO access fault
  18. #define MCAUSE_ECALL_FROM_USER_MODE (8U) //!< Environment call from User mode
  19. #define MCAUSE_ECALL_FROM_SUPERVISOR_MODE (9U) //!< Environment call from Supervisor mode
  20. #define MCAUSE_ECALL_FROM_MACHINE_MODE (11U) //!< Environment call from machine mode
  21. #define MCAUSE_INSTR_PAGE_FAULT (12U) //!< Instruction page fault
  22. #define MCAUSE_LOAD_PAGE_FAULT (13) //!< Load page fault
  23. #define MCAUSE_STORE_AMO_PAGE_FAULT (15U) //!< Store/AMO page fault
  24. #define IRQ_S_SOFT 1
  25. #define IRQ_H_SOFT 2
  26. #define IRQ_M_SOFT 3
  27. #define IRQ_S_TIMER 5
  28. #define IRQ_H_TIMER 6
  29. #define IRQ_M_TIMER 7
  30. #define IRQ_S_EXT 9
  31. #define IRQ_H_EXT 10
  32. #define IRQ_M_EXT 11
  33. #define IRQ_COP 12
  34. #define IRQ_HOST 13
  35. __attribute__((weak)) void mchtmr_isr(void)
  36. {
  37. }
  38. __attribute__((weak)) void swi_isr(void)
  39. {
  40. }
  41. __attribute__((weak)) void syscall_handler(long n, long a0, long a1, long a2, long a3)
  42. {
  43. }
  44. __attribute__((weak)) long exception_handler(long cause, long epc)
  45. {
  46. switch (cause) {
  47. case MCAUSE_INSTR_ADDR_MISALIGNED:
  48. break;
  49. case MCAUSE_INSTR_ACCESS_FAULT:
  50. break;
  51. case MCAUSE_ILLEGAL_INSTR:
  52. break;
  53. case MCAUSE_BREAKPOINT:
  54. break;
  55. case MCAUSE_LOAD_ADDR_MISALIGNED:
  56. break;
  57. case MCAUSE_LOAD_ACCESS_FAULT:
  58. break;
  59. case MCAUSE_STORE_AMO_ADDR_MISALIGNED:
  60. break;
  61. case MCAUSE_STORE_AMO_ACCESS_FAULT:
  62. break;
  63. case MCAUSE_ECALL_FROM_USER_MODE:
  64. break;
  65. case MCAUSE_ECALL_FROM_SUPERVISOR_MODE:
  66. break;
  67. case MCAUSE_ECALL_FROM_MACHINE_MODE:
  68. break;
  69. case MCAUSE_INSTR_PAGE_FAULT:
  70. break;
  71. case MCAUSE_LOAD_PAGE_FAULT:
  72. break;
  73. case MCAUSE_STORE_AMO_PAGE_FAULT:
  74. break;
  75. default:
  76. break;
  77. }
  78. /* Unhandled Trap */
  79. return epc;
  80. }
  81. #if !defined(CONFIG_FREERTOS) && !defined(CONFIG_UCOS_III) && !defined(CONFIG_THREADX)
  82. void irq_handler_trap(void) __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)));
  83. #else
  84. void irq_handler_trap(void) __attribute__ ((section(".isr_vector")));
  85. #endif
  86. void irq_handler_trap(void)
  87. {
  88. long mcause = read_csr(CSR_MCAUSE);
  89. long mepc = read_csr(CSR_MEPC);
  90. long mstatus = read_csr(CSR_MSTATUS);
  91. #if defined(SUPPORT_PFT_ARCH) && SUPPORT_PFT_ARCH
  92. long mxstatus = read_csr(CSR_MXSTATUS);
  93. #endif
  94. #ifdef __riscv_dsp
  95. int ucode = read_csr(CSR_UCODE);
  96. #endif
  97. #ifdef __riscv_flen
  98. int fcsr = read_fcsr();
  99. #endif
  100. /* clobbers list for ecall */
  101. #ifdef __riscv_32e
  102. __asm volatile("" : : :"t0", "a0", "a1", "a2", "a3");
  103. #else
  104. __asm volatile("" : : :"a7", "a0", "a1", "a2", "a3");
  105. #endif
  106. /* Do your trap handling */
  107. if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_TIMER)) {
  108. /* Machine timer interrupt */
  109. mchtmr_isr();
  110. }
  111. #ifdef USE_NONVECTOR_MODE
  112. else if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_EXT)) {
  113. typedef void(*isr_func_t)(void);
  114. /* Machine-level interrupt from PLIC */
  115. uint32_t irq_index = __plic_claim_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE);
  116. if (irq_index) {
  117. /* Workaround: irq number returned by __plic_claim_irq might be 0, which is caused by plic. So skip invalid irq_index as a workaround */
  118. #if !defined(DISABLE_IRQ_PREEMPTIVE) || (DISABLE_IRQ_PREEMPTIVE == 0)
  119. enable_global_irq(CSR_MSTATUS_MIE_MASK);
  120. #endif
  121. ((isr_func_t)__vector_table[irq_index])();
  122. __plic_complete_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE, irq_index);
  123. }
  124. }
  125. #endif
  126. else if ((mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == IRQ_M_SOFT)) {
  127. /* Machine SWI interrupt */
  128. intc_m_claim_swi();
  129. swi_isr();
  130. intc_m_complete_swi();
  131. } else if (!(mcause & CSR_MCAUSE_INTERRUPT_MASK) && ((mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK) == MCAUSE_ECALL_FROM_MACHINE_MODE)) {
  132. /* Machine Syscal call */
  133. __asm volatile(
  134. "mv a4, a3\n"
  135. "mv a3, a2\n"
  136. "mv a2, a1\n"
  137. "mv a1, a0\n"
  138. #ifdef __riscv_32e
  139. "mv a0, t0\n"
  140. #else
  141. "mv a0, a7\n"
  142. #endif
  143. "jalr %0\n"
  144. : :"r"(syscall_handler) : "a4"
  145. );
  146. mepc += 4;
  147. } else {
  148. mepc = exception_handler(mcause, mepc);
  149. }
  150. /* Restore CSR */
  151. write_csr(CSR_MSTATUS, mstatus);
  152. write_csr(CSR_MEPC, mepc);
  153. #if defined(SUPPORT_PFT_ARCH) && SUPPORT_PFT_ARCH
  154. write_csr(CSR_MXSTATUS, mxstatus);
  155. #endif
  156. #ifdef __riscv_dsp
  157. write_csr(CSR_UCODE, ucode);
  158. #endif
  159. #ifdef __riscv_flen
  160. write_fcsr(fcsr);
  161. #endif
  162. }