trap_common.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (c) 2023-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-03-01 Yaochenger The first version
  9. * 2023-03-19 flyingcys Add support for rv32e
  10. * 2023-03-29 flyingcys return old handler when install new one for rt_hw_interrupt_install
  11. * 2023-06-08 Liu,Yuan remove unused variables
  12. * 2025-01-27 Chen Wang fix build warnings
  13. * 2025-12-11 HPMicro allow overriding the ISR numbers
  14. */
  15. #include <rthw.h>
  16. #include <rtthread.h>
  17. #include "riscv-ops.h"
  18. #include "rt_hw_stack_frame.h"
  19. #ifndef RT_HW_ISR_NUM
  20. #define RT_HW_ISR_NUM 32
  21. #endif
  22. static volatile rt_hw_stack_frame_t *s_stack_frame;
  23. static struct rt_irq_desc rv32irq_table[RT_HW_ISR_NUM];
  24. void rt_show_stack_frame(void);
  25. /**
  26. * Temporary interrupt entry function
  27. *
  28. * @param mcause Machine Cause Register
  29. * @return RT_NULL
  30. */
  31. rt_weak rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t mcause)
  32. {
  33. rt_kprintf("UN-handled interrupt %d occurred!!!\n", mcause);
  34. return RT_NULL;
  35. }
  36. /**
  37. * Interrupt entry function initialization
  38. */
  39. rt_weak void rt_hw_interrupt_init(void)
  40. {
  41. int idx = 0;
  42. for (idx = 0; idx < RT_HW_ISR_NUM; idx++)
  43. {
  44. rv32irq_table[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
  45. rv32irq_table[idx].param = RT_NULL;
  46. }
  47. }
  48. /**
  49. * Break Entry Function Binding
  50. *
  51. * @param vector interrupt number
  52. * @param handler Break-in function requiring binding
  53. * @param param NULL
  54. * @param name NULL
  55. * @return old handler
  56. */
  57. rt_weak rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  58. void *param, const char *name)
  59. {
  60. rt_isr_handler_t old_handler = RT_NULL;
  61. if(vector < RT_HW_ISR_NUM)
  62. {
  63. old_handler = rv32irq_table[vector].handler;
  64. if (handler != RT_NULL)
  65. {
  66. rv32irq_table[vector].handler = (rt_isr_handler_t)handler;
  67. rv32irq_table[vector].param = param;
  68. }
  69. }
  70. return old_handler;
  71. }
  72. /**
  73. * Query and Distribution Entry for Exception and Interrupt Sources
  74. *
  75. * @param mcause Machine Cause Register
  76. */
  77. rt_weak void rt_rv32_system_irq_handler(rt_uint32_t mcause)
  78. {
  79. rt_uint32_t mscratch = read_csr(0x340);
  80. rt_uint32_t irq_id = (mcause & 0x1F);
  81. rt_uint32_t exception = !(mcause & 0x80000000);
  82. if(exception)
  83. {
  84. s_stack_frame = (volatile rt_hw_stack_frame_t *)(uintptr_t)mscratch;
  85. rt_show_stack_frame();
  86. }
  87. else
  88. {
  89. rv32irq_table[irq_id].handler(irq_id, rv32irq_table[irq_id].param);
  90. }
  91. }
  92. /**
  93. * Register Print on Exception
  94. */
  95. rt_weak void rt_show_stack_frame(void)
  96. {
  97. rt_kprintf("Stack frame:\r\n----------------------------------------\r\n");
  98. rt_kprintf("ra : 0x%08x\r\n", s_stack_frame->ra);
  99. rt_kprintf("mstatus : 0x%08x\r\n", read_csr(0x300));//mstatus
  100. rt_kprintf("t0 : 0x%08x\r\n", s_stack_frame->t0);
  101. rt_kprintf("t1 : 0x%08x\r\n", s_stack_frame->t1);
  102. rt_kprintf("t2 : 0x%08x\r\n", s_stack_frame->t2);
  103. rt_kprintf("a0 : 0x%08x\r\n", s_stack_frame->a0);
  104. rt_kprintf("a1 : 0x%08x\r\n", s_stack_frame->a1);
  105. rt_kprintf("a2 : 0x%08x\r\n", s_stack_frame->a2);
  106. rt_kprintf("a3 : 0x%08x\r\n", s_stack_frame->a3);
  107. rt_kprintf("a4 : 0x%08x\r\n", s_stack_frame->a4);
  108. rt_kprintf("a5 : 0x%08x\r\n", s_stack_frame->a5);
  109. #ifndef __riscv_32e
  110. rt_kprintf("a6 : 0x%08x\r\n", s_stack_frame->a6);
  111. rt_kprintf("a7 : 0x%08x\r\n", s_stack_frame->a7);
  112. rt_kprintf("t3 : 0x%08x\r\n", s_stack_frame->t3);
  113. rt_kprintf("t4 : 0x%08x\r\n", s_stack_frame->t4);
  114. rt_kprintf("t5 : 0x%08x\r\n", s_stack_frame->t5);
  115. rt_kprintf("t6 : 0x%08x\r\n", s_stack_frame->t6);
  116. #endif
  117. }