apic.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. #pragma once
  2. #include <common/asm.h>
  3. #include <process/ptrace.h>
  4. #include <exception/irq.h>
  5. #include <mm/mm.h>
  6. #pragma GCC push_options
  7. #pragma GCC optimize("O0")
  8. #define APIC_SUCCESS 0
  9. #define APIC_E_NOTFOUND 1
  10. #define APIC_IO_APIC_VIRT_BASE_ADDR SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + IO_APIC_MAPPING_OFFSET
  11. #define APIC_LOCAL_APIC_VIRT_BASE_ADDR SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + LOCAL_APIC_MAPPING_OFFSET
  12. // 当前apic启用状态标志
  13. extern uint8_t __apic_enable_state;
  14. #define APIC_XAPIC_ENABLED 0
  15. #define APIC_X2APIC_ENABLED 1
  16. #define CURRENT_APIC_STATE (__apic_enable_state )
  17. // ======== local apic 寄存器虚拟地址偏移量表 =======
  18. // 0x00~0x10 Reserved.
  19. #define LOCAL_APIC_OFFSET_Local_APIC_ID 0x20
  20. #define LOCAL_APIC_OFFSET_Local_APIC_Version 0x30
  21. // 0x40~0x70 Reserved.
  22. #define LOCAL_APIC_OFFSET_Local_APIC_TPR 0x80
  23. #define LOCAL_APIC_OFFSET_Local_APIC_APR 0x90
  24. #define LOCAL_APIC_OFFSET_Local_APIC_PPR 0xa0
  25. #define LOCAL_APIC_OFFSET_Local_APIC_EOI 0xb0
  26. #define LOCAL_APIC_OFFSET_Local_APIC_RRD 0xc0
  27. #define LOCAL_APIC_OFFSET_Local_APIC_LDR 0xd0
  28. #define LOCAL_APIC_OFFSET_Local_APIC_DFR 0xe0
  29. #define LOCAL_APIC_OFFSET_Local_APIC_SVR 0xf0
  30. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_31_0 0x100
  31. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_63_32 0x110
  32. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_95_64 0x120
  33. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_127_96 0x130
  34. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_159_128 0x140
  35. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_191_160 0x150
  36. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_223_192 0x160
  37. #define LOCAL_APIC_OFFSET_Local_APIC_ISR_255_224 0x170
  38. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_31_0 0x180
  39. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_63_32 0x190
  40. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_95_64 0x1a0
  41. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_127_96 0x1b0
  42. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_159_128 0x1c0
  43. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_191_160 0x1d0
  44. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_223_192 0x1e0
  45. #define LOCAL_APIC_OFFSET_Local_APIC_TMR_255_224 0x1f0
  46. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_31_0 0x200
  47. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_63_32 0x210
  48. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_95_64 0x220
  49. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_127_96 0x230
  50. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_159_128 0x240
  51. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_191_160 0x250
  52. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_223_192 0x260
  53. #define LOCAL_APIC_OFFSET_Local_APIC_IRR_255_224 0x270
  54. #define LOCAL_APIC_OFFSET_Local_APIC_ESR 0x280
  55. // 0x290~0x2e0 Reserved.
  56. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI 0x2f0
  57. #define LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0 0x300
  58. #define LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32 0x310
  59. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER 0x320
  60. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL 0x330
  61. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR 0x340
  62. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0 0x350
  63. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1 0x360
  64. #define LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR 0x370
  65. // 初始计数寄存器(定时器专用)
  66. #define LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG 0x380
  67. // 当前计数寄存器(定时器专用)
  68. #define LOCAL_APIC_OFFSET_Local_APIC_CURRENT_COUNT_REG 0x390
  69. // 0x3A0~0x3D0 Reserved.
  70. // 分频配置寄存器(定时器专用)
  71. #define LOCAL_APIC_OFFSET_Local_APIC_CLKDIV 0x3e0
  72. uint32_t RCBA_vaddr = 0; // RCBA寄存器的虚拟地址
  73. /*
  74. 1: LVT CMCI
  75. 2: LVT Timer
  76. 3: LVT Thermal Monitor
  77. 4: LVT Performace Counter
  78. 5: LVT LINT0
  79. 6: LVT LINT1
  80. 7: LVT Error
  81. */
  82. /**
  83. * LVT表项
  84. * */
  85. struct apic_LVT
  86. {
  87. uint vector : 8, // 0-7位全部置为1
  88. delivery_mode : 3, // 第[10:8]位置为100, 表示NMI
  89. reserved_1 : 1, // 第11位保留
  90. delivery_status : 1, // 第12位,投递状态 -> 发送挂起
  91. polarity : 1, // 第13位,电平触发极性 存在于LINT0,LINT1
  92. remote_IRR : 1, // 第14位,远程IRR标志位(只读) 存在于LINT0,LINT1
  93. trigger_mode : 1, // 第15位,触发模式(0位边沿触发,1为电平触发) 存在于LINT0,LINT1
  94. mask : 1, // 第16位,屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
  95. timer_mode : 2, // 第[18:17]位,定时模式。(00:一次性定时, 01:周期性定时, 10:指定TSC值计数), 存在于定时器寄存器
  96. reserved_2 : 13; // [31:19]位保留
  97. } __attribute((packed)); // 取消结构体的align
  98. /*
  99. ICR
  100. */
  101. struct INT_CMD_REG
  102. {
  103. unsigned int vector : 8, // 0~7
  104. deliver_mode : 3, // 8~10
  105. dest_mode : 1, // 11
  106. deliver_status : 1, // 12
  107. res_1 : 1, // 13
  108. level : 1, // 14
  109. trigger : 1, // 15
  110. res_2 : 2, // 16~17
  111. dest_shorthand : 2, // 18~19
  112. res_3 : 12; // 20~31
  113. union
  114. {
  115. struct
  116. {
  117. unsigned int res_4 : 24, // 32~55
  118. dest_field : 8; // 56~63
  119. } apic_destination;
  120. unsigned int x2apic_destination; // 32~63
  121. } destination;
  122. } __attribute__((packed));
  123. /**
  124. * @brief I/O APIC 的中断定向寄存器的结构体
  125. *
  126. */
  127. struct apic_IO_APIC_RTE_entry
  128. {
  129. unsigned int vector : 8, // 0~7
  130. deliver_mode : 3, // [10:8] 投递模式默认为NMI
  131. dest_mode : 1, // 11 目标模式(0位物理模式,1为逻辑模式)
  132. deliver_status : 1, // 12 投递状态
  133. polarity : 1, // 13 电平触发极性
  134. remote_IRR : 1, // 14 远程IRR标志位(只读)
  135. trigger_mode : 1, // 15 触发模式(0位边沿触发,1为电平触发)
  136. mask : 1, // 16 屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
  137. reserved : 15; // [31:17]位保留
  138. union
  139. {
  140. // 物理模式
  141. struct
  142. {
  143. unsigned int reserved1 : 24, // [55:32] 保留
  144. phy_dest : 4, // [59:56] APIC ID
  145. reserved2 : 4; // [63:60] 保留
  146. } physical;
  147. // 逻辑模式
  148. struct
  149. {
  150. unsigned int reserved1 : 24, // [55:32] 保留
  151. logical_dest : 8; // [63:56] 自定义APIC ID
  152. } logical;
  153. } destination;
  154. } __attribute__((packed));
  155. // ========== APIC的寄存器的参数定义 ==============
  156. // 投递模式
  157. #define LOCAL_APIC_FIXED 0
  158. #define IO_APIC_FIXED 0
  159. #define ICR_APIC_FIXED 0
  160. #define IO_APIC_Lowest_Priority 1
  161. #define ICR_Lowest_Priority 1
  162. #define LOCAL_APIC_SMI 2
  163. #define APIC_SMI 2
  164. #define ICR_SMI 2
  165. #define LOCAL_APIC_NMI 4
  166. #define APIC_NMI 4
  167. #define ICR_NMI 4
  168. #define LOCAL_APIC_INIT 5
  169. #define APIC_INIT 5
  170. #define ICR_INIT 5
  171. #define ICR_Start_up 6
  172. #define IO_APIC_ExtINT 7
  173. // 时钟模式
  174. #define APIC_LVT_Timer_One_Shot 0
  175. #define APIC_LVT_Timer_Periodic 1
  176. #define APIC_LVT_Timer_TSC_Deadline 2
  177. // 屏蔽
  178. #define UNMASKED 0
  179. #define MASKED 1
  180. #define APIC_LVT_INT_MASKED 0x10000UL
  181. // 触发模式
  182. #define EDGE_TRIGGER 0 // 边沿触发
  183. #define Level_TRIGGER 1 // 电平触发
  184. // 投递模式
  185. #define IDLE 0 // 挂起
  186. #define SEND_PENDING 1 // 发送等待
  187. // destination shorthand
  188. #define ICR_No_Shorthand 0
  189. #define ICR_Self 1
  190. #define ICR_ALL_INCLUDE_Self 2
  191. #define ICR_ALL_EXCLUDE_Self 3
  192. // 投递目标模式
  193. #define DEST_PHYSICAL 0 // 物理模式
  194. #define DEST_LOGIC 1 // 逻辑模式
  195. // level
  196. #define ICR_LEVEL_DE_ASSERT 0
  197. #define ICR_LEVEL_ASSERT 1
  198. // 远程IRR标志位, 在处理Local APIC标志位时置位,在收到处理器发来的EOI命令时复位
  199. #define IRR_RESET 0
  200. #define IRR_ACCEPT 1
  201. // 电平触发极性
  202. #define POLARITY_HIGH 0
  203. #define POLARITY_LOW 1
  204. struct apic_IO_APIC_map
  205. {
  206. // 间接访问寄存器的物理基地址
  207. uint addr_phys;
  208. // 索引寄存器虚拟地址
  209. unsigned char *virtual_index_addr;
  210. // 数据寄存器虚拟地址
  211. uint *virtual_data_addr;
  212. // EOI寄存器虚拟地址
  213. uint *virtual_EOI_addr;
  214. } apic_ioapic_map;
  215. /**
  216. * @brief 中断服务程序
  217. *
  218. * @param rsp 中断栈指针
  219. * @param number 中断向量号
  220. */
  221. void do_IRQ(struct pt_regs *rsp, ul number);
  222. /**
  223. * @brief 读取RTE寄存器
  224. *
  225. * @param index 索引值
  226. * @return ul
  227. */
  228. ul apic_ioapic_read_rte(unsigned char index);
  229. /**
  230. * @brief 写入RTE寄存器
  231. *
  232. * @param index 索引值
  233. * @param value 要写入的值
  234. */
  235. void apic_ioapic_write_rte(unsigned char index, ul value);
  236. /**
  237. * @brief 初始化AP处理器的Local apic
  238. *
  239. */
  240. void apic_init_ap_core_local_apic();
  241. /**
  242. * @brief 初始化apic控制器
  243. *
  244. */
  245. void apic_init();
  246. /**
  247. * @brief 读取指定类型的 Interrupt Control Structure
  248. *
  249. * @param type ics的类型
  250. * @param ret_vaddr 对应的ICS的虚拟地址数组
  251. * @param total 返回数组的元素总个数
  252. * @return uint
  253. */
  254. uint apic_get_ics(const uint type, ul ret_vaddr[], uint *total);
  255. // =========== 中断控制操作接口 ============
  256. void apic_ioapic_enable(ul irq_num);
  257. void apic_ioapic_disable(ul irq_num);
  258. ul apic_ioapic_install(ul irq_num, void *arg);
  259. void apic_ioapic_uninstall(ul irq_num);
  260. void apic_ioapic_level_ack(ul irq_num); // ioapic电平触发 应答
  261. void apic_ioapic_edge_ack(ul irq_num); // ioapic边沿触发 应答
  262. // void apic_local_apic_level_ack(ul irq_num);// local apic电平触发 应答
  263. void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答
  264. /**
  265. * @brief 构造RTE Entry结构体
  266. *
  267. * @param entry 返回的结构体
  268. * @param vector 中断向量
  269. * @param deliver_mode 投递模式
  270. * @param dest_mode 目标模式
  271. * @param deliver_status 投递状态
  272. * @param polarity 电平触发极性
  273. * @param irr 远程IRR标志位(只读)
  274. * @param trigger 触发模式
  275. * @param mask 屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
  276. * @param dest_apicID 目标apicID
  277. */
  278. void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, uint8_t deliver_mode, uint8_t dest_mode,
  279. uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
  280. #pragma GCC pop_options