软中断处理机制

This commit is contained in:
fslongjin
2022-04-08 20:04:12 +08:00
parent d887f9a0f7
commit 9828aff985
12 changed files with 202 additions and 25 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}
}
@ -655,7 +652,10 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
* @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;
}

View File

@ -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();
}
/**

View File

@ -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();
}

View File

@ -17,3 +17,5 @@ struct rtc_time_t
* @return int 成功则为0
*/
int rtc_get_cmos_time(struct rtc_time_t*t);
void rtc_init();

View 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);
}

View 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);

View File

@ -50,7 +50,6 @@ Restore_all:
popq %rax
addq $0x10, %rsp // FUNCerrcode
iretq
ret_from_exception:
@ -58,6 +57,7 @@ ret_from_exception:
ENTRY(ret_from_intr)
jmp Restore_all
Err_Code:
// =====

View 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);
}

View 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();

View File

@ -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();
}