mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 12:16:31 +00:00
软中断处理机制
This commit is contained in:
@ -69,6 +69,9 @@ apu_boot.o: smp/apu_boot.S
|
||||
cpu.o: common/cpu.c
|
||||
gcc $(CFLAGS) -c common/cpu.c -o common/cpu.o
|
||||
|
||||
softirq.o: exception/softirq.c
|
||||
gcc $(CFLAGS) -c exception/softirq.c -o exception/softirq.o
|
||||
|
||||
# IPI的代码
|
||||
ifeq ($(ARCH), x86_64)
|
||||
OBJ_LIST += ipi.o
|
||||
@ -115,16 +118,19 @@ rtc.o: driver/timers/rtc/rtc.c
|
||||
HPET.o: driver/timers/HPET/HPET.c
|
||||
gcc $(CFLAGS) -c driver/timers/HPET/HPET.c -o driver/timers/HPET/HPET.o
|
||||
|
||||
timer.o: driver/timers/timer.c
|
||||
gcc $(CFLAGS) -c driver/timers/timer.c -o driver/timers/timer.o
|
||||
|
||||
|
||||
|
||||
all: kernel
|
||||
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
|
||||
#
|
||||
|
||||
kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o $(OBJ_LIST)
|
||||
kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o $(OBJ_LIST)
|
||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \
|
||||
common/cpu.o smp/smp.o smp/apu_boot.o \
|
||||
driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o \
|
||||
common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o \
|
||||
driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \
|
||||
$(LD_LIST) \
|
||||
-T link.lds
|
||||
|
||||
|
@ -393,3 +393,14 @@ ul rdmsr(ul address)
|
||||
: "memory");
|
||||
return ((ul)tmp0 << 32) | tmp1;
|
||||
}
|
||||
|
||||
|
||||
uint64_t get_rflags()
|
||||
{
|
||||
unsigned long tmp = 0;
|
||||
__asm__ __volatile__ ("pushfq \n\t"
|
||||
"movq (%%rsp), %0 \n\t"
|
||||
"popfq \n\t"
|
||||
:"=r"(tmp)::"memory");
|
||||
return tmp;
|
||||
}
|
@ -36,10 +36,9 @@ int printk_init(const int char_size_x, const int char_size_y)
|
||||
pos.max_x = calculate_max_charNum(pos.width, char_size_x);
|
||||
pos.max_y = calculate_max_charNum(pos.height, char_size_y);
|
||||
|
||||
|
||||
VBE_FB_phys_addr = (ul)info.framebuffer_addr;
|
||||
pos.FB_address = (uint *)0x0000000003000000;
|
||||
pos.FB_length = 1UL*pos.width * pos.height;
|
||||
pos.FB_length = 1UL * pos.width * pos.height;
|
||||
|
||||
// 初始化自旋锁
|
||||
spin_init(&printk_lock);
|
||||
@ -75,9 +74,7 @@ int printk_init(const int char_size_x, const int char_size_y)
|
||||
|
||||
kdebug("width=%d\theight=%d", pos.width, pos.height);
|
||||
|
||||
while (1)
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_printk_pos(const int x, const int y)
|
||||
@ -120,7 +117,7 @@ void auto_newline()
|
||||
pos.y = pos.max_y;
|
||||
int lines_to_scroll = 1;
|
||||
scroll(true, lines_to_scroll * pos.char_size_y, false);
|
||||
pos.y -= (lines_to_scroll-1);
|
||||
pos.y -= (lines_to_scroll - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -654,8 +651,11 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
|
||||
* @param BKcolor 背景色
|
||||
* @param ... 格式化字符串
|
||||
*/
|
||||
|
||||
spin_lock(&printk_lock);
|
||||
|
||||
/*
|
||||
if (get_rflags() & 0x200UL)
|
||||
spin_lock(&printk_lock); // 不是中断处理程序调用printk,加锁
|
||||
*/
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@ -712,8 +712,10 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
|
||||
}
|
||||
}
|
||||
|
||||
for(int j=0;j<1e5;++j);
|
||||
spin_unlock(&printk_lock);
|
||||
/*
|
||||
if (get_rflags() & 0x200UL)
|
||||
spin_unlock(&printk_lock);
|
||||
*/
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "../../../exception/gate.h"
|
||||
#include "../../acpi/acpi.h"
|
||||
|
||||
#include <exception/softirq.h>
|
||||
|
||||
// 导出定义在irq.c中的中段门表
|
||||
extern void (*interrupt_table[24])(void);
|
||||
|
||||
@ -389,9 +391,9 @@ void apic_local_apic_init()
|
||||
*/
|
||||
void apic_init()
|
||||
{
|
||||
// 初始化中断门, 中断使用第二个ist
|
||||
// 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
|
||||
for (int i = 32; i <= 55; ++i)
|
||||
set_intr_gate(i, 2, interrupt_table[i - 32]);
|
||||
set_intr_gate(i, 0, interrupt_table[i - 32]);
|
||||
// 初始化主芯片
|
||||
io_out8(0x20, 0x11); // 初始化主芯片的icw1
|
||||
io_out8(0x21, 0x20); // 设置主芯片的中断向量号为0x20(0x20-0x27)
|
||||
@ -466,6 +468,10 @@ void do_IRQ(struct pt_regs *rsp, ul number)
|
||||
kwarn("do IRQ receive: %d", number);
|
||||
break;
|
||||
}
|
||||
|
||||
// 检测是否有未处理的软中断
|
||||
if (softirq_status != 0)
|
||||
do_softirq();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <common/kprint.h>
|
||||
#include <mm/mm.h>
|
||||
#include <driver/interrupt/apic/apic.h>
|
||||
#include <exception/softirq.h>
|
||||
#include <driver/timers/timer.h>
|
||||
|
||||
static struct acpi_HPET_description_table_t *hpet_table;
|
||||
static uint64_t HPET_REG_BASE = 0;
|
||||
@ -46,14 +48,15 @@ hardware_intr_controller HPET_intr_controller =
|
||||
|
||||
void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
||||
{
|
||||
//printk_color(ORANGE, BLACK, "(HPET)");
|
||||
switch (param)
|
||||
{
|
||||
case 0:
|
||||
rtc_get_cmos_time(&rtc_now);
|
||||
case 0: // 定时器0中断
|
||||
++timer_jiffies;
|
||||
set_softirq_status(TIMER_SIRQ);
|
||||
break;
|
||||
|
||||
default:
|
||||
kwarn("Unsupported HPET irq: %d.", number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -97,6 +100,4 @@ int HPET_init()
|
||||
rtc_get_cmos_time(&rtc_now);
|
||||
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
||||
io_mfence();
|
||||
|
||||
|
||||
}
|
@ -16,4 +16,6 @@ struct rtc_time_t
|
||||
* @param t time结构体
|
||||
* @return int 成功则为0
|
||||
*/
|
||||
int rtc_get_cmos_time(struct rtc_time_t*t);
|
||||
int rtc_get_cmos_time(struct rtc_time_t*t);
|
||||
|
||||
void rtc_init();
|
14
kernel/driver/timers/timer.c
Normal file
14
kernel/driver/timers/timer.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "timer.h"
|
||||
#include<common/kprint.h>
|
||||
#include <exception/softirq.h>
|
||||
|
||||
void timer_init()
|
||||
{
|
||||
timer_jiffies = 0;
|
||||
register_softirq(0, &do_timer_softirq, NULL);
|
||||
}
|
||||
|
||||
void do_timer_softirq(void* data)
|
||||
{
|
||||
printk_color(ORANGE, BLACK, "(HPET%ld)", timer_jiffies);
|
||||
}
|
11
kernel/driver/timers/timer.h
Normal file
11
kernel/driver/timers/timer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/glib.h>
|
||||
#include "HPET/HPET.h"
|
||||
#include "rtc/rtc.h"
|
||||
|
||||
uint64_t volatile timer_jiffies = 0; // 系统时钟计数
|
||||
|
||||
void timer_init();
|
||||
|
||||
void do_timer_softirq(void* data);
|
@ -50,7 +50,6 @@ Restore_all:
|
||||
|
||||
popq %rax
|
||||
addq $0x10, %rsp // 弹出变量FUNC和errcode
|
||||
|
||||
iretq
|
||||
|
||||
ret_from_exception:
|
||||
@ -58,6 +57,7 @@ ret_from_exception:
|
||||
ENTRY(ret_from_intr)
|
||||
jmp Restore_all
|
||||
|
||||
|
||||
Err_Code:
|
||||
// ===== 有错误码的情况下,保存寄存器并跳转服务程序
|
||||
|
||||
|
65
kernel/exception/softirq.c
Normal file
65
kernel/exception/softirq.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include "softirq.h"
|
||||
#include <common/kprint.h>
|
||||
|
||||
void set_softirq_status(uint64_t status)
|
||||
{
|
||||
softirq_status |= status;
|
||||
}
|
||||
|
||||
uint64_t get_softirq_status()
|
||||
{
|
||||
return softirq_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 软中断注册函数
|
||||
*
|
||||
* @param irq_num 软中断号
|
||||
* @param action 响应函数
|
||||
* @param data 响应数据结构体
|
||||
*/
|
||||
void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data)
|
||||
{
|
||||
softirq_vector[irq_num].action = action;
|
||||
softirq_vector[irq_num].data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 卸载软中断
|
||||
*
|
||||
* @param irq_num 软中断号
|
||||
*/
|
||||
void unregister_softirq(uint32_t irq_num)
|
||||
{
|
||||
softirq_vector[irq_num].action = NULL;
|
||||
softirq_vector[irq_num].data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 软中断处理程序
|
||||
*
|
||||
*/
|
||||
void do_softirq()
|
||||
{
|
||||
|
||||
sti();
|
||||
for(uint32_t i=0;i<MAX_SOFTIRQ_NUM&&softirq_status;++i)
|
||||
{
|
||||
if(softirq_status&(1<<i))
|
||||
{
|
||||
softirq_vector[i].action(softirq_vector[i].data);
|
||||
softirq_status &= (~(1<<i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cli();
|
||||
}
|
||||
|
||||
void softirq_init()
|
||||
{
|
||||
softirq_status = 0;
|
||||
memset(softirq_vector, 0, sizeof(struct softirq_t) * MAX_SOFTIRQ_NUM);
|
||||
}
|
||||
|
||||
|
56
kernel/exception/softirq.h
Normal file
56
kernel/exception/softirq.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file softirq.h
|
||||
* @author fslongjin (longjin@RinGoTek.cn)
|
||||
* @brief 软中断
|
||||
* @version 0.1
|
||||
* @date 2022-04-08
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include<common/glib.h>
|
||||
|
||||
#define MAX_SOFTIRQ_NUM 64
|
||||
|
||||
#define TIMER_SIRQ (1<<0) // 时钟软中断号
|
||||
|
||||
uint64_t softirq_status = 0;
|
||||
|
||||
struct softirq_t
|
||||
{
|
||||
void (*action)(void* data); // 软中断处理函数
|
||||
void* data;
|
||||
};
|
||||
|
||||
struct softirq_t softirq_vector[MAX_SOFTIRQ_NUM] = {0};
|
||||
|
||||
|
||||
/**
|
||||
* @brief 软中断注册函数
|
||||
*
|
||||
* @param irq_num 软中断号
|
||||
* @param action 响应函数
|
||||
* @param data 响应数据结构体
|
||||
*/
|
||||
void register_softirq(uint32_t irq_num, void (*action)(void * data), void* data);
|
||||
|
||||
/**
|
||||
* @brief 卸载软中断
|
||||
*
|
||||
* @param irq_num 软中断号
|
||||
*/
|
||||
void unregister_softirq(uint32_t irq_num);
|
||||
|
||||
void set_softirq_status(uint64_t status);
|
||||
uint64_t get_softirq_status();
|
||||
|
||||
/**
|
||||
* @brief 软中断处理程序
|
||||
*
|
||||
*/
|
||||
void do_softirq();
|
||||
|
||||
|
||||
void softirq_init();
|
@ -8,6 +8,7 @@
|
||||
#include "exception/gate.h"
|
||||
#include "exception/trap.h"
|
||||
#include "exception/irq.h"
|
||||
#include <exception/softirq.h>
|
||||
#include "mm/mm.h"
|
||||
#include "mm/slab.h"
|
||||
#include "process/process.h"
|
||||
@ -24,6 +25,7 @@
|
||||
#include "driver/disk/ahci/ahci.h"
|
||||
#include <driver/timers/rtc/rtc.h>
|
||||
#include <driver/timers/HPET/HPET.h>
|
||||
#include <driver/timers/timer.h>
|
||||
|
||||
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
|
||||
|
||||
@ -167,9 +169,9 @@ void system_initialize()
|
||||
acpi_init();
|
||||
// 初始化中断模块
|
||||
irq_init();
|
||||
|
||||
softirq_init();
|
||||
timer_init();
|
||||
HPET_init();
|
||||
|
||||
smp_init();
|
||||
|
||||
// 先初始化系统调用模块
|
||||
@ -181,7 +183,6 @@ void system_initialize()
|
||||
// ata_init();
|
||||
pci_init();
|
||||
ahci_init();
|
||||
|
||||
// test_slab();
|
||||
// test_mm();
|
||||
|
||||
@ -233,6 +234,7 @@ void Start_Kernel(void)
|
||||
// ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0xc8, ICR_APIC_FIXED, ICR_No_Shorthand, true, 1); // 测试ipi
|
||||
|
||||
int last_sec = rtc_now.second;
|
||||
/*
|
||||
while (1)
|
||||
{
|
||||
if (last_sec != rtc_now.second)
|
||||
@ -241,6 +243,7 @@ void Start_Kernel(void)
|
||||
kinfo("Current Time: %04d/%02d/%02d %02d:%02d:%02d", rtc_now.year, rtc_now.month, rtc_now.day, rtc_now.hour, rtc_now.minute, rtc_now.second);
|
||||
}
|
||||
}
|
||||
*/
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
|
Reference in New Issue
Block a user