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