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