softirq.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "softirq.h"
  2. #include <common/kprint.h>
  3. #include <process/process.h>
  4. #include <driver/video/video.h>
  5. #include <common/spinlock.h>
  6. static spinlock_t softirq_modify_lock; // 软中断状态(status)
  7. static volatile uint64_t softirq_pending = 0;
  8. static volatile uint64_t softirq_running = 0;
  9. void set_softirq_pending(uint64_t status)
  10. {
  11. softirq_pending |= status;
  12. }
  13. uint64_t get_softirq_pending()
  14. {
  15. return softirq_pending;
  16. }
  17. #define get_softirq_running() (softirq_running)
  18. /**
  19. * @brief 设置软中断运行结束
  20. *
  21. * @param softirq_num
  22. */
  23. #define clear_softirq_running(softirq_num) \
  24. do \
  25. { \
  26. softirq_running &= (~(1 << softirq_num)); \
  27. } while (0)
  28. // 设置软中断的运行状态(只应在do_softirq中调用此宏)
  29. #define set_softirq_running(softirq_num) \
  30. do \
  31. { \
  32. softirq_running |= (1 << softirq_num); \
  33. } while (0)
  34. /**
  35. * @brief 清除软中断pending标志位
  36. *
  37. */
  38. #define softirq_ack(sirq_num) \
  39. do \
  40. { \
  41. softirq_pending &= (~(1 << sirq_num)); \
  42. } while (0);
  43. /**
  44. * @brief 软中断注册函数
  45. *
  46. * @param irq_num 软中断号
  47. * @param action 响应函数
  48. * @param data 响应数据结构体
  49. */
  50. void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data)
  51. {
  52. softirq_vector[irq_num].action = action;
  53. softirq_vector[irq_num].data = data;
  54. }
  55. /**
  56. * @brief 卸载软中断
  57. *
  58. * @param irq_num 软中断号
  59. */
  60. void unregister_softirq(uint32_t irq_num)
  61. {
  62. softirq_vector[irq_num].action = NULL;
  63. softirq_vector[irq_num].data = NULL;
  64. }
  65. /**
  66. * @brief 软中断处理程序
  67. *
  68. */
  69. void do_softirq()
  70. {
  71. sti();
  72. for (uint32_t i = 0; i < MAX_SOFTIRQ_NUM && softirq_pending; ++i)
  73. {
  74. if (softirq_pending & (1 << i) && softirq_vector[i].action != NULL && (!(get_softirq_running() & (1 << i))))
  75. {
  76. if (spin_trylock(&softirq_modify_lock))
  77. {
  78. // 检测该软中断是否已经被其他进程执行
  79. if(get_softirq_running() & (1 << i))
  80. {
  81. spin_unlock(&softirq_modify_lock);
  82. continue;
  83. }
  84. softirq_ack(i);
  85. set_softirq_running(i);
  86. spin_unlock(&softirq_modify_lock);
  87. softirq_vector[i].action(softirq_vector[i].data);
  88. clear_softirq_running(i);
  89. }
  90. }
  91. }
  92. cli();
  93. }
  94. int clear_softirq_pending(uint32_t irq_num)
  95. {
  96. clear_softirq_running(irq_num);
  97. }
  98. void softirq_init()
  99. {
  100. softirq_pending = 0;
  101. memset(softirq_vector, 0, sizeof(struct softirq_t) * MAX_SOFTIRQ_NUM);
  102. spin_init(&softirq_modify_lock);
  103. }