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