mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
🆕 中断上半部
This commit is contained in:
parent
c187ef152a
commit
d4c07ac4ad
@ -112,4 +112,5 @@ void acpi_init()
|
||||
kdebug("acpi_RSDT_entry_phys_base=%#018lx", acpi_RSDT_entry_phys_base);
|
||||
// 映射RSDT ENTRY的物理地址
|
||||
mm_map_phys_addr(ACPI_DESCRIPTION_HEDERS_BASE, acpi_RSDT_entry_phys_base, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
|
||||
kinfo("ACPI module initialized!")
|
||||
}
|
@ -74,7 +74,7 @@ void apic_io_apic_init()
|
||||
// 初始化RTE表项,将所有RTE表项屏蔽
|
||||
for (int i = 0x10; i < 0x40; i += 2)
|
||||
{
|
||||
// 以0x20位起始中断向量号,初始化RTE
|
||||
// 以0x20为起始中断向量号,初始化RTE
|
||||
apic_ioapic_write_rte(i, 0x10020 + ((i - 0x10) >> 1));
|
||||
}
|
||||
|
||||
@ -285,13 +285,24 @@ void apic_init()
|
||||
* @brief 中断服务程序
|
||||
*
|
||||
* @param rsp 中断栈指针
|
||||
* @param number 中断号
|
||||
* @param number 中断向量号
|
||||
*/
|
||||
void do_IRQ(struct pt_regs *rsp, ul number)
|
||||
{
|
||||
|
||||
unsigned char x = io_in8(0x60);
|
||||
printk_color(BLUE, WHITE, "(IRQ:%#04x)\tkey code:%#04x\n", number, x);
|
||||
|
||||
irq_desc_t *irq = &interrupt_desc[number - 32];
|
||||
|
||||
// 执行中断上半部处理程序
|
||||
if (irq->handler != NULL)
|
||||
irq->handler(number, irq->parameter, rsp);
|
||||
|
||||
// 向中断控制器发送应答消息
|
||||
if (irq->controller != NULL && irq->controller->ack != NULL)
|
||||
irq->controller->ack(number);
|
||||
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
io_mfence();
|
||||
uint *eoi = (uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_EOI);
|
||||
@ -348,3 +359,49 @@ void apic_ioapic_write_rte(unsigned char index, ul value)
|
||||
*apic_ioapic_map.virtual_data_addr = value & 0xffffffff;
|
||||
io_mfence();
|
||||
}
|
||||
|
||||
// =========== 中断控制操作接口 ============
|
||||
void apic_ioapic_enable(ul irq_num)
|
||||
{
|
||||
ul index = 0x10 + ((irq_num - 32) << 1);
|
||||
ul value = apic_ioapic_read_rte(index);
|
||||
value &= (~0x10000UL);
|
||||
apic_ioapic_write_rte(index, value);
|
||||
}
|
||||
|
||||
void apic_ioapic_disable(ul irq_num)
|
||||
{
|
||||
ul index = 0x10 + ((irq_num - 32) << 1);
|
||||
ul value = apic_ioapic_read_rte(index);
|
||||
value |= (0x10000UL);
|
||||
apic_ioapic_write_rte(index, value);
|
||||
}
|
||||
|
||||
ul apic_ioapic_install(ul irq_num, void *arg)
|
||||
{
|
||||
struct apic_IO_APIC_RTE_entry *entry = (struct apic_IO_APIC_RTE_entry *)arg;
|
||||
// RTE表项值写入对应的RTE寄存器
|
||||
apic_ioapic_write_rte(0x10 + ((irq_num - 32) << 1), *(ul *)entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void apic_ioapic_uninstall(ul irq_num)
|
||||
{
|
||||
// 将对应的RTE表项设置为屏蔽状态
|
||||
apic_ioapic_write_rte(0x10 + ((irq_num - 32) << 1), 0x10000UL);
|
||||
}
|
||||
|
||||
void apic_ioapic_level_ack(ul irq_num) // 电平触发
|
||||
{
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
uint *eoi = (uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_EOI);
|
||||
*eoi = 0x00;
|
||||
*apic_ioapic_map.virtual_EOI_addr = irq_num;
|
||||
}
|
||||
|
||||
void apic_ioapic_edge_ack(ul irq_num) // 边沿触发
|
||||
{
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
uint *eoi = (uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_EOI);
|
||||
*eoi = 0x00;
|
||||
}
|
@ -70,9 +70,163 @@
|
||||
// 分频配置寄存器(定时器专用)
|
||||
#define LOCAL_APIC_OFFSET_Local_APIC_CLKDIV 0x3e0
|
||||
|
||||
/*
|
||||
|
||||
1: LVT CMCI
|
||||
2: LVT Timer
|
||||
3: LVT Thermal Monitor
|
||||
4: LVT Performace Counter
|
||||
5: LVT LINT0
|
||||
6: LVT LINT1
|
||||
7: LVT Error
|
||||
|
||||
*/
|
||||
/**
|
||||
* LVT表项
|
||||
* */
|
||||
struct apic_LVT
|
||||
{
|
||||
uint vector : 8, // 0-7位全部置为1
|
||||
delivery_mode : 3, // 第[10:8]位置为100, 表示NMI
|
||||
reserved_1 : 1, // 第11位保留
|
||||
delivery_status : 1, // 第12位,投递状态 -> 发送挂起
|
||||
polarity : 1, // 第13位,电平触发极性 存在于LINT0,LINT1
|
||||
remote_IRR : 1, // 第14位,远程IRR标志位(只读) 存在于LINT0,LINT1
|
||||
trigger_mode : 1, // 第15位,触发模式(0位边沿触发,1为电平触发) 存在于LINT0,LINT1
|
||||
mask : 1, // 第16位,屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
|
||||
timer_mode : 2, // 第[18:17]位,定时模式。(00:一次性定时, 01:周期性定时, 10:指定TSC值计数), 存在于定时器寄存器
|
||||
reserved_2 : 13; // [31:19]位保留
|
||||
|
||||
} __attribute((packed)); // 取消结构体的align
|
||||
|
||||
/*
|
||||
ICR
|
||||
*/
|
||||
|
||||
struct INT_CMD_REG
|
||||
{
|
||||
unsigned int vector : 8, // 0~7
|
||||
deliver_mode : 3, // 8~10
|
||||
dest_mode : 1, // 11
|
||||
deliver_status : 1, // 12
|
||||
res_1 : 1, // 13
|
||||
level : 1, // 14
|
||||
trigger : 1, // 15
|
||||
res_2 : 2, // 16~17
|
||||
dest_shorthand : 2, // 18~19
|
||||
res_3 : 12; // 20~31
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int res_4 : 24, // 32~55
|
||||
dest_field : 8; // 56~63
|
||||
} apic_destination;
|
||||
|
||||
unsigned int x2apic_destination; // 32~63
|
||||
} destination;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* @brief I/O APIC 的中断定向寄存器的结构体
|
||||
*
|
||||
*/
|
||||
struct apic_IO_APIC_RTE_entry
|
||||
{
|
||||
unsigned int vector : 8, // 0~7
|
||||
deliver_mode : 3, // [10:8] 投递模式默认为NMI
|
||||
dest_mode : 1, // 11 目标模式(0位物理模式,1为逻辑模式)
|
||||
deliver_status : 1, // 12 投递状态
|
||||
polarity : 1, // 13 电平触发极性
|
||||
remote_IRR : 1, // 14 远程IRR标志位(只读)
|
||||
trigger_mode : 1, // 15 触发模式(0位边沿触发,1为电平触发)
|
||||
mask : 1, // 16 屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
|
||||
reserved : 19; // [31:17]位保留
|
||||
|
||||
union
|
||||
{
|
||||
// 物理模式
|
||||
struct
|
||||
{
|
||||
unsigned int reserved1 : 24, // [55:32] 保留
|
||||
phy_dest : 4, // [59:56] APIC ID
|
||||
reserved2 : 4; // [63:60] 保留
|
||||
} physical;
|
||||
|
||||
// 逻辑模式
|
||||
struct
|
||||
{
|
||||
unsigned int reserved1 : 24, // [55:32] 保留
|
||||
logical_dest : 8; // [63:56] 自定义APIC ID
|
||||
} logical;
|
||||
} destination;
|
||||
} __attribute__((packed));
|
||||
|
||||
// ========== APIC的寄存器的参数定义 ==============
|
||||
// 投递模式
|
||||
#define LOCAL_APIC_FIXED 0
|
||||
#define IO_APIC_FIXED 0
|
||||
#define ICR_APIC_FIXED 0
|
||||
|
||||
#define IO_APIC_Lowest_Priority 1
|
||||
#define ICR_Lowest_Priority 1
|
||||
|
||||
#define LOCAL_APIC_SMI 2
|
||||
#define APIC_SMI 2
|
||||
#define ICR_SMI 2
|
||||
|
||||
#define LOCAL_APIC_NMI 4
|
||||
#define APIC_NMI 4
|
||||
#define ICR_NMI 4
|
||||
|
||||
#define LOCAL_APIC_INIT 5
|
||||
#define APIC_INIT 5
|
||||
#define ICR_INIT 5
|
||||
|
||||
#define ICR_Start_up 6
|
||||
|
||||
#define IO_APIC_ExtINT 7
|
||||
|
||||
// 时钟模式
|
||||
#define APIC_LVT_Timer_One_Shot 0
|
||||
#define APIC_LVT_Timer_Periodic 1
|
||||
#define APIC_LVT_Timer_TSC_Deadline 2
|
||||
|
||||
// 屏蔽
|
||||
#define UNMASKED 0
|
||||
#define MASKED 1
|
||||
|
||||
// 触发模式
|
||||
#define EDGE_TRIGGER 0 // 边沿触发
|
||||
#define Level_TRIGGER 1 // 电平触发
|
||||
|
||||
// 投递模式
|
||||
#define IDLE 0 // 挂起
|
||||
#define SEND_PENDING 1 // 发送等待
|
||||
|
||||
// destination shorthand
|
||||
#define ICR_No_Shorthand 0
|
||||
#define ICR_Self 1
|
||||
#define ICR_ALL_INCLUDE_Self 2
|
||||
#define ICR_ALL_EXCLUDE_Self 3
|
||||
|
||||
// 目标模式
|
||||
#define DEST_PHYSICAL 0 // 物理模式
|
||||
#define DEST_LOGIC 1 // 逻辑模式
|
||||
|
||||
// level
|
||||
#define ICR_LEVEL_DE_ASSERT 0
|
||||
#define ICR_LEVEL_ASSERT 1
|
||||
|
||||
// 远程IRR
|
||||
#define IRR_RESET 0
|
||||
#define IRR_ACCEPT 1
|
||||
|
||||
// 电平触发极性
|
||||
#define POLARITY_HIGH 0
|
||||
#define POLARITY_LOW 1
|
||||
|
||||
struct apic_IO_APIC_map
|
||||
{
|
||||
@ -90,7 +244,7 @@ struct apic_IO_APIC_map
|
||||
* @brief 中断服务程序
|
||||
*
|
||||
* @param rsp 中断栈指针
|
||||
* @param number 中断号
|
||||
* @param number 中断向量号
|
||||
*/
|
||||
void do_IRQ(struct pt_regs *rsp, ul number);
|
||||
|
||||
@ -115,3 +269,11 @@ void apic_ioapic_write_rte(unsigned char index, ul value);
|
||||
*
|
||||
*/
|
||||
void apic_init();
|
||||
|
||||
// =========== 中断控制操作接口 ============
|
||||
void apic_ioapic_enable(ul irq_num);
|
||||
void apic_ioapic_disable(ul irq_num);
|
||||
ul apic_ioapic_install(ul irq_num, void *arg);
|
||||
void apic_ioapic_uninstall(ul irq_num);
|
||||
void apic_ioapic_level_ack(ul irq_num); // 电平触发
|
||||
void apic_ioapic_edge_ack(ul irq_num); // 边沿触发
|
@ -111,6 +111,55 @@ void (*interrupt_table[24])(void) =
|
||||
IRQ0x37interrupt,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 中断注册函数
|
||||
*
|
||||
* @param irq_num 中断向量号
|
||||
* @param arg 传递给中断安装接口的参数
|
||||
* @param handler 中断处理函数
|
||||
* @param paramater 中断处理函数的参数
|
||||
* @param controller 中断控制器结构
|
||||
* @param irq_name 中断名
|
||||
* @return int
|
||||
*/
|
||||
int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_int_controller *controller, char *irq_name)
|
||||
{
|
||||
// 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
|
||||
irq_desc_t *p = &interrupt_desc[irq_num - 32];
|
||||
|
||||
p->controller = controller;
|
||||
p->irq_name = irq_name;
|
||||
p->parameter = paramater;
|
||||
p->flags = 0;
|
||||
p->handler = handler;
|
||||
|
||||
p->controller->install(irq_num, arg);
|
||||
p->controller->enable(irq_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 中断注销函数
|
||||
*
|
||||
* @param irq_num 中断向量号
|
||||
* @return int
|
||||
*/
|
||||
int irq_unregister(ul irq_num)
|
||||
{
|
||||
irq_desc_t *p = &interrupt_desc[irq_num - 32];
|
||||
p->controller->disable(irq_num);
|
||||
p->controller->uninstall(irq_num);
|
||||
|
||||
p->controller = NULL;
|
||||
p->irq_name = NULL;
|
||||
p->parameter = NULL;
|
||||
p->flags = 0;
|
||||
p->handler = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化中断模块
|
||||
*/
|
||||
@ -119,6 +168,8 @@ void irq_init()
|
||||
#if _INTR_8259A_
|
||||
init_8259A();
|
||||
#else
|
||||
memset(interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM);
|
||||
|
||||
apic_init();
|
||||
#endif
|
||||
}
|
||||
|
@ -15,9 +15,134 @@
|
||||
|
||||
#include "../process/ptrace.h"
|
||||
|
||||
extern void (*interrupt_table[24])(void);
|
||||
extern void do_IRQ(struct pt_regs *regs, ul number);
|
||||
|
||||
/* ========= 中断向量分配表 ==========
|
||||
|
||||
0~255 IDT
|
||||
|
||||
0 ~ 31 trap fault abort for system
|
||||
0 devide error
|
||||
1 debug
|
||||
2 NMI
|
||||
3 breakpoint
|
||||
4 overflow
|
||||
5 bound range
|
||||
6 undefined opcode
|
||||
7 device not available
|
||||
8 double fault
|
||||
9 coprocessor segment overrun
|
||||
10 invalid TSS
|
||||
11 segment not present
|
||||
12 stack segment fault
|
||||
13 general protection
|
||||
14 page fault
|
||||
15
|
||||
16 x87 FPU error
|
||||
17 alignment check
|
||||
18 machine check
|
||||
19 SIMD exception
|
||||
20 virtualization exception
|
||||
21 ~ 31 Do not use
|
||||
|
||||
32 ~ 55 I/O APIC
|
||||
32 8259A
|
||||
33 keyboard
|
||||
34 HPET timer 0,8254 counter 0
|
||||
35 serial port A
|
||||
36 serial port B
|
||||
37 parallel port
|
||||
38 floppy
|
||||
39 parallel port
|
||||
40 RTC,HPET timer 1
|
||||
41 Generic
|
||||
42 Generic
|
||||
43 HPET timer 2
|
||||
44 HPET timer 3
|
||||
45 FERR#
|
||||
46 SATA primary
|
||||
47 SATA secondary
|
||||
48 PIRQA
|
||||
49 PIRQB
|
||||
50 PIRQC
|
||||
51 PIRQD
|
||||
52 PIRQE
|
||||
53 PIRQF
|
||||
54 PIRQG
|
||||
55 PIRQH
|
||||
|
||||
|
||||
0x80 system call
|
||||
|
||||
150 ~ 200 Local APIC
|
||||
150 CMCI
|
||||
151 Timer
|
||||
152 Thermal Monitor
|
||||
153 Performance Counter
|
||||
154 LINT0
|
||||
155 LINT1
|
||||
156 Error
|
||||
|
||||
200 ~ 255 MP IPI
|
||||
|
||||
*/
|
||||
|
||||
typedef struct hardware_int_type
|
||||
{
|
||||
// 使能中断操作接口
|
||||
void (*enable)(ul irq_num);
|
||||
// 禁止中断操作接口
|
||||
void (*disable)(ul irq_num);
|
||||
|
||||
// 安装中断操作接口
|
||||
ul (*install)(ul irq_num, void *arg);
|
||||
// 卸载中断操作接口
|
||||
void (*uninstall)(ul irq_num);
|
||||
// 应答中断操作接口
|
||||
void (*ack)(ul irq_num);
|
||||
} hardware_int_controller;
|
||||
|
||||
// 中断描述结构体
|
||||
typedef struct
|
||||
{
|
||||
hardware_int_controller *controller;
|
||||
// 中断名
|
||||
char *irq_name;
|
||||
// 中断处理函数的参数
|
||||
ul parameter;
|
||||
// 中断处理函数
|
||||
void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs);
|
||||
|
||||
// 自定义的标志位
|
||||
ul flags;
|
||||
} irq_desc_t;
|
||||
|
||||
#define IRQ_NUM 24
|
||||
irq_desc_t interrupt_desc[IRQ_NUM] = {0};
|
||||
|
||||
/**
|
||||
* @brief 中断注册函数
|
||||
*
|
||||
* @param irq_num 中断向量号
|
||||
* @param arg 传递给中断安装接口的参数
|
||||
* @param handler 中断处理函数
|
||||
* @param paramater 中断处理函数的参数
|
||||
* @param controller 中断控制器结构
|
||||
* @param irq_name 中断名
|
||||
* @return int
|
||||
*/
|
||||
int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_int_controller *controller, char *irq_name);
|
||||
|
||||
/**
|
||||
* @brief 中断注销函数
|
||||
*
|
||||
* @param irq_num 中断向量号
|
||||
* @return int
|
||||
*/
|
||||
int irq_unregister(ul irq_num);
|
||||
|
||||
/**
|
||||
* @brief 初始化中断模块
|
||||
*/
|
||||
void irq_init();
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user