mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 00:46:31 +00:00
使用rust重构softirq机制;解决Rtc驱动的编译警告问题 (#138)
* 使用rust重构softirq机制 * 解决Rtc驱动的编译警告问题 Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
@ -1,4 +1,9 @@
|
||||
pub struct rtc_time_t {
|
||||
use crate::{
|
||||
arch::interrupt::{cli, sti},
|
||||
include::bindings::bindings::{io_in8, io_out8},
|
||||
};
|
||||
|
||||
pub struct RtcTime {
|
||||
pub second: i32,
|
||||
pub minute: i32,
|
||||
pub hour: i32,
|
||||
@ -7,10 +12,79 @@ pub struct rtc_time_t {
|
||||
pub year: i32,
|
||||
}
|
||||
|
||||
use crate::{
|
||||
arch::interrupt::{cli, sti},
|
||||
include::bindings::bindings::{io_in8, io_out8},
|
||||
};
|
||||
impl Default for RtcTime {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
second: (0),
|
||||
minute: (0),
|
||||
hour: (0),
|
||||
day: (0),
|
||||
month: (0),
|
||||
year: (0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RtcTime {
|
||||
///@brief 从主板cmos中获取时间
|
||||
///
|
||||
///@param self time结构体
|
||||
///@return int 成功则为0
|
||||
pub fn get(&mut self) -> Result<i32, i32> {
|
||||
// 为防止中断请求打断该过程,需要先关中断
|
||||
cli();
|
||||
//0x0B
|
||||
let status_register_b: u8 = read_cmos(0x0B); // 读取状态寄存器B
|
||||
let is_24h: bool = if (status_register_b & 0x02) != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}; // 判断是否启用24小时模式
|
||||
|
||||
let is_binary: bool = if (status_register_b & 0x04) != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}; // 判断是否为二进制码
|
||||
|
||||
loop {
|
||||
self.year = read_cmos(CMOSTimeSelector::Year as u8) as i32;
|
||||
self.month = read_cmos(CMOSTimeSelector::Month as u8) as i32;
|
||||
self.day = read_cmos(CMOSTimeSelector::Day as u8) as i32;
|
||||
self.hour = read_cmos(CMOSTimeSelector::Hour as u8) as i32;
|
||||
self.minute = read_cmos(CMOSTimeSelector::Minute as u8) as i32;
|
||||
self.second = read_cmos(CMOSTimeSelector::Second as u8) as i32;
|
||||
|
||||
if self.second == read_cmos(CMOSTimeSelector::Second as u8) as i32 {
|
||||
break;
|
||||
} // 若读取时间过程中时间发生跳变则重新读取
|
||||
}
|
||||
|
||||
unsafe {
|
||||
io_out8(0x70, 0x00);
|
||||
}
|
||||
|
||||
if !is_binary
|
||||
// 把BCD转为二进制
|
||||
{
|
||||
self.second = (self.second & 0xf) + (self.second >> 4) * 10;
|
||||
self.minute = (self.minute & 0xf) + (self.minute >> 4) * 10;
|
||||
self.hour = ((self.hour & 0xf) + ((self.hour & 0x70) >> 4) * 10) | (self.hour & 0x80);
|
||||
self.day = (self.day & 0xf) + ((self.day / 16) * 10);
|
||||
self.month = (self.month & 0xf) + (self.month >> 4) * 10;
|
||||
self.year = (self.year & 0xf) + (self.year >> 4) * 10;
|
||||
}
|
||||
self.year += 2000;
|
||||
|
||||
if (!is_24h) && (self.hour & 0x80) != 0 {
|
||||
self.hour = ((self.hour & 0x7f) + 12) % 24;
|
||||
} // 将十二小时制转为24小时
|
||||
|
||||
sti();
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
///置位0x70的第7位,禁止不可屏蔽中断
|
||||
#[inline]
|
||||
@ -21,69 +95,13 @@ fn read_cmos(addr: u8) -> u8 {
|
||||
}
|
||||
}
|
||||
|
||||
/// used in the form of u8
|
||||
#[repr(u8)]
|
||||
enum CMOSTimeSelector {
|
||||
T_SECOND = 0x00,
|
||||
T_MINUTE = 0x02,
|
||||
T_HOUR = 0x04,
|
||||
T_DAY = 0x07,
|
||||
T_MONTH = 0x08,
|
||||
T_YEAR = 0x09,
|
||||
}
|
||||
|
||||
///@brief 从主板cmos中获取时间
|
||||
///
|
||||
///@param t time结构体
|
||||
///@return int 成功则为0
|
||||
pub fn rtc_get_cmos_time(t: &mut rtc_time_t) -> Result<i32,i32> {
|
||||
unsafe {
|
||||
// 为防止中断请求打断该过程,需要先关中断
|
||||
cli();
|
||||
//0x0B
|
||||
let status_register_B: u8 = read_cmos(0x0B); // 读取状态寄存器B
|
||||
let is_24h: bool = if (status_register_B & 0x02) != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}; // 判断是否启用24小时模式
|
||||
|
||||
let is_binary: bool = if (status_register_B & 0x04) != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}; // 判断是否为二进制码
|
||||
|
||||
loop {
|
||||
t.year = read_cmos(CMOSTimeSelector::T_YEAR as u8) as i32;
|
||||
t.month = read_cmos(CMOSTimeSelector::T_MONTH as u8) as i32;
|
||||
t.day = read_cmos(CMOSTimeSelector::T_DAY as u8) as i32;
|
||||
t.hour = read_cmos(CMOSTimeSelector::T_HOUR as u8) as i32;
|
||||
t.minute = read_cmos(CMOSTimeSelector::T_MINUTE as u8) as i32;
|
||||
t.second = read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32;
|
||||
|
||||
if t.second == read_cmos(CMOSTimeSelector::T_SECOND as u8) as i32 {
|
||||
break;
|
||||
} // 若读取时间过程中时间发生跳变则重新读取
|
||||
}
|
||||
|
||||
io_out8(0x70, 0x00);
|
||||
|
||||
if !is_binary
|
||||
// 把BCD转为二进制
|
||||
{
|
||||
t.second = (t.second & 0xf) + (t.second >> 4) * 10;
|
||||
t.minute = (t.minute & 0xf) + (t.minute >> 4) * 10;
|
||||
t.hour = ((t.hour & 0xf) + ((t.hour & 0x70) >> 4) * 10) | (t.hour & 0x80);
|
||||
t.day = (t.day & 0xf) + ((t.day / 16) * 10);
|
||||
t.month = (t.month & 0xf) + (t.month >> 4) * 10;
|
||||
t.year = (t.year & 0xf) + (t.year >> 4) * 10;
|
||||
}
|
||||
t.year += 2000;
|
||||
|
||||
if (!is_24h) && (t.hour & 0x80) != 0 {
|
||||
t.hour = ((t.hour & 0x7f) + 12) % 24;
|
||||
} // 将十二小时制转为24小时
|
||||
|
||||
sti();
|
||||
}
|
||||
return Ok(0);
|
||||
Second = 0x00,
|
||||
Minute = 0x02,
|
||||
Hour = 0x04,
|
||||
Day = 0x07,
|
||||
Month = 0x08,
|
||||
Year = 0x09,
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
CFLAGS += -I .
|
||||
|
||||
|
||||
all: entry.o irq.o softirq.o trap.o
|
||||
all: entry.o irq.o trap.o
|
||||
|
||||
entry.o: entry.S
|
||||
$(CC) -E entry.S > _entry.s
|
||||
@ -11,8 +11,5 @@ entry.o: entry.S
|
||||
trap.o: trap.c
|
||||
$(CC) $(CFLAGS) -c trap.c -o trap.o
|
||||
|
||||
softirq.o: softirq.c
|
||||
$(CC) $(CFLAGS) -c softirq.c -o softirq.o
|
||||
|
||||
irq.o: irq.c
|
||||
$(CC) $(CFLAGS) -c irq.c -o irq.o
|
@ -175,7 +175,6 @@ int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter
|
||||
p->parameter = paramater;
|
||||
p->flags = 0;
|
||||
p->handler = handler;
|
||||
|
||||
io_mfence();
|
||||
p->controller->install(irq_num, arg);
|
||||
io_mfence();
|
||||
|
1
kernel/src/exception/mod.rs
Normal file
1
kernel/src/exception/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod softirq;
|
@ -1,120 +0,0 @@
|
||||
#include "softirq.h"
|
||||
#include <common/kprint.h>
|
||||
#include <process/process.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <common/spinlock.h>
|
||||
|
||||
static struct softirq_t softirq_vector[MAX_SOFTIRQ_NUM] = {0};
|
||||
static spinlock_t softirq_modify_lock; // 软中断状态(status)
|
||||
static volatile uint64_t softirq_pending = 0;
|
||||
static volatile uint64_t softirq_running = 0;
|
||||
|
||||
void set_softirq_pending(uint64_t status)
|
||||
{
|
||||
softirq_pending |= status;
|
||||
}
|
||||
|
||||
uint64_t get_softirq_pending()
|
||||
{
|
||||
return softirq_pending;
|
||||
}
|
||||
|
||||
#define get_softirq_running() (softirq_running)
|
||||
|
||||
/**
|
||||
* @brief 设置软中断运行结束
|
||||
*
|
||||
* @param softirq_num
|
||||
*/
|
||||
#define clear_softirq_running(softirq_num) \
|
||||
do \
|
||||
{ \
|
||||
softirq_running &= (~(1 << softirq_num)); \
|
||||
} while (0)
|
||||
|
||||
// 设置软中断的运行状态(只应在do_softirq中调用此宏)
|
||||
#define set_softirq_running(softirq_num) \
|
||||
do \
|
||||
{ \
|
||||
softirq_running |= (1 << softirq_num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief 清除软中断pending标志位
|
||||
*
|
||||
*/
|
||||
#define softirq_ack(sirq_num) \
|
||||
do \
|
||||
{ \
|
||||
softirq_pending &= (~(1 << sirq_num)); \
|
||||
} while (0);
|
||||
|
||||
/**
|
||||
* @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_pending; ++i)
|
||||
{
|
||||
if (softirq_pending & (1 << i) && softirq_vector[i].action != NULL && (!(get_softirq_running() & (1 << i))))
|
||||
{
|
||||
if (spin_trylock(&softirq_modify_lock))
|
||||
{
|
||||
// 检测该软中断是否已经被其他进程执行
|
||||
if(get_softirq_running() & (1 << i))
|
||||
{
|
||||
spin_unlock(&softirq_modify_lock);
|
||||
continue;
|
||||
}
|
||||
softirq_ack(i);
|
||||
set_softirq_running(i);
|
||||
spin_unlock(&softirq_modify_lock);
|
||||
|
||||
softirq_vector[i].action(softirq_vector[i].data);
|
||||
|
||||
clear_softirq_running(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cli();
|
||||
}
|
||||
|
||||
int clear_softirq_pending(uint32_t irq_num)
|
||||
{
|
||||
clear_softirq_running(irq_num);
|
||||
}
|
||||
|
||||
void softirq_init()
|
||||
{
|
||||
softirq_pending = 0;
|
||||
memset(softirq_vector, 0, sizeof(struct softirq_t) * MAX_SOFTIRQ_NUM);
|
||||
spin_init(&softirq_modify_lock);
|
||||
}
|
@ -12,51 +12,16 @@
|
||||
|
||||
#include <common/glib.h>
|
||||
|
||||
#define MAX_SOFTIRQ_NUM 64
|
||||
// ==================implementation with rust===================
|
||||
extern void softirq_init();
|
||||
extern void raise_softirq(uint64_t sirq_num);
|
||||
extern int register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
|
||||
extern int unregister_softirq(uint32_t irq_num);
|
||||
extern void set_softirq_pending(uint64_t status);
|
||||
extern void clear_softirq_pending(uint32_t irq_num);
|
||||
extern void do_softirq();
|
||||
|
||||
// for temporary
|
||||
#define MAX_SOFTIRQ_NUM 64
|
||||
#define TIMER_SIRQ 0 // 时钟软中断号
|
||||
#define VIDEO_REFRESH_SIRQ 1 // 帧缓冲区刷新软中断
|
||||
|
||||
/**
|
||||
* @brief 发起软中断
|
||||
*
|
||||
*/
|
||||
#define raise_softirq(sirq_num) \
|
||||
do \
|
||||
{ \
|
||||
set_softirq_pending(1 << sirq_num); \
|
||||
} while (0);
|
||||
|
||||
struct softirq_t
|
||||
{
|
||||
void (*action)(void *data); // 软中断处理函数
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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_pending(uint64_t status);
|
||||
uint64_t get_softirq_pending();
|
||||
|
||||
int clear_softirq_pending(uint32_t irq_num);
|
||||
/**
|
||||
* @brief 软中断处理程序
|
||||
*
|
||||
*/
|
||||
void do_softirq();
|
||||
|
||||
void softirq_init();
|
266
kernel/src/exception/softirq.rs
Normal file
266
kernel/src/exception/softirq.rs
Normal file
@ -0,0 +1,266 @@
|
||||
use core::{ffi::c_void, ptr::null_mut};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::{
|
||||
arch::interrupt::{cli, sti},
|
||||
include::bindings::bindings::{verify_area, EBUSY, EEXIST, EPERM},
|
||||
kBUG,
|
||||
libs::spinlock::RawSpinlock,
|
||||
};
|
||||
|
||||
const MAX_SOFTIRQ_NUM: u64 = 64;
|
||||
const MAX_LOCK_TRIAL_TIME: u64 = 50;
|
||||
pub static mut SOFTIRQ_HANDLER_PTR: *mut Softirq = null_mut();
|
||||
|
||||
/// 软中断向量号码
|
||||
#[allow(dead_code)]
|
||||
#[repr(u8)]
|
||||
pub enum SoftirqNumber {
|
||||
TIMER = 0, //时钟软中断信号
|
||||
VideoRefresh = 1, //帧缓冲区刷新软中断
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SoftirqVector {
|
||||
pub action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>, //软中断处理函数
|
||||
pub data: *mut c_void,
|
||||
}
|
||||
|
||||
impl Default for SoftirqVector {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
action: None,
|
||||
data: null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Softirq {
|
||||
modify_lock: RawSpinlock,
|
||||
pending: u64,
|
||||
running: u64,
|
||||
table: [SoftirqVector; MAX_SOFTIRQ_NUM as usize],
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
/// @brief 提供给c的接口函数,用于初始化静态指针
|
||||
pub extern "C" fn softirq_init() {
|
||||
if unsafe { SOFTIRQ_HANDLER_PTR.is_null() } {
|
||||
unsafe {
|
||||
SOFTIRQ_HANDLER_PTR = Box::leak(Box::new(Softirq::default()));
|
||||
}
|
||||
} else {
|
||||
kBUG!("Try to init SOFTIRQ_HANDLER_PTR twice.");
|
||||
panic!("Try to init SOFTIRQ_HANDLER_PTR twice.");
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 将raw pointer转换为指针,减少unsafe块
|
||||
#[inline]
|
||||
pub fn __get_softirq_handler_mut() -> &'static mut Softirq {
|
||||
return unsafe { SOFTIRQ_HANDLER_PTR.as_mut().unwrap() };
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
pub extern "C" fn raise_softirq(sirq_num: u64) {
|
||||
let softirq_handler = __get_softirq_handler_mut();
|
||||
softirq_handler.set_softirq_pending(1 << sirq_num);
|
||||
}
|
||||
|
||||
/// @brief 软中断注册函数
|
||||
///
|
||||
/// @param irq_num 软中断号
|
||||
/// @param action 响应函数
|
||||
/// @param data 响应数据结构体
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
pub extern "C" fn register_softirq(
|
||||
irq_num: u32,
|
||||
action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>,
|
||||
data: *mut c_void,
|
||||
) {
|
||||
let softirq_handler = __get_softirq_handler_mut();
|
||||
softirq_handler.register_softirq(irq_num, action, data);
|
||||
}
|
||||
|
||||
/// @brief 卸载软中断
|
||||
/// @param irq_num 软中断号
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
pub extern "C" fn unregister_softirq(irq_num: u32) {
|
||||
let softirq_handler = __get_softirq_handler_mut();
|
||||
softirq_handler.unregister_softirq(irq_num);
|
||||
}
|
||||
|
||||
/// 设置软中断的运行状态(只应在do_softirq中调用此宏)
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
pub extern "C" fn set_softirq_pending(irq_num: u32) {
|
||||
let softirq_handler = __get_softirq_handler_mut();
|
||||
softirq_handler.set_softirq_pending(irq_num);
|
||||
}
|
||||
|
||||
/// @brief 设置软中断运行结束
|
||||
///
|
||||
/// @param softirq_num
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
pub extern "C" fn clear_softirq_pending(irq_num: u32) {
|
||||
let softirq_handler = __get_softirq_handler_mut();
|
||||
softirq_handler.clear_softirq_pending(irq_num);
|
||||
}
|
||||
|
||||
/// @brief 软中断处理程序
|
||||
#[no_mangle]
|
||||
#[allow(dead_code)]
|
||||
pub extern "C" fn do_softirq() {
|
||||
let softirq_handler = __get_softirq_handler_mut();
|
||||
softirq_handler.do_softirq();
|
||||
}
|
||||
|
||||
impl Default for Softirq {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
modify_lock: RawSpinlock::INIT,
|
||||
pending: (0),
|
||||
running: (0),
|
||||
table: [Default::default(); MAX_SOFTIRQ_NUM as usize],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Softirq {
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn get_softirq_pending(&self) -> u64 {
|
||||
return self.pending;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn get_softirq_running(&self) -> u64 {
|
||||
return self.running;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_softirq_pending(&mut self, softirq_num: u32) {
|
||||
self.pending |= 1 << softirq_num;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_softirq_running(&mut self, softirq_num: u32) {
|
||||
self.running |= 1 << softirq_num;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear_softirq_running(&mut self, softirq_num: u32) {
|
||||
self.running &= !(1 << softirq_num);
|
||||
}
|
||||
|
||||
/// @brief 清除软中断pending标志位
|
||||
#[inline]
|
||||
pub fn clear_softirq_pending(&mut self, softirq_num: u32) {
|
||||
self.pending &= !(1 << softirq_num);
|
||||
}
|
||||
|
||||
/// @brief 判断对应running标志位是否为0
|
||||
/// @return true: 标志位为1; false: 标志位为0
|
||||
#[inline]
|
||||
pub fn is_running(&mut self, softirq_num: u32) -> bool {
|
||||
return (self.running & (1 << softirq_num)).ne(&0);
|
||||
}
|
||||
|
||||
/// @brief 判断对应pending标志位是否为0
|
||||
/// @return true: 标志位为1; false: 标志位为0
|
||||
#[inline]
|
||||
pub fn is_pending(&mut self, softirq_num: u32) -> bool {
|
||||
return (self.pending & (1 << softirq_num)).ne(&0);
|
||||
}
|
||||
|
||||
/// @brief 注册软中断向量
|
||||
/// @param irq_num 中断向量号码
|
||||
/// @param action 中断函数的入口地址
|
||||
/// @param data 中断函数的操作数据
|
||||
pub fn register_softirq(
|
||||
&mut self,
|
||||
irq_num: u32,
|
||||
action: Option<unsafe extern "C" fn(data: *mut ::core::ffi::c_void)>,
|
||||
data: *mut c_void,
|
||||
) -> i32 {
|
||||
if self.table[irq_num as usize].action.is_some() {
|
||||
return -(EEXIST as i32);
|
||||
}
|
||||
|
||||
if unsafe { verify_area(action.unwrap() as u64, 1) } {
|
||||
return -(EPERM as i32);
|
||||
}
|
||||
self.modify_lock.lock();
|
||||
self.table[irq_num as usize].action = action;
|
||||
self.table[irq_num as usize].data = data;
|
||||
self.modify_lock.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief 解注册软中断向量
|
||||
/// @param irq_num 中断向量号码
|
||||
pub fn unregister_softirq(&mut self, irq_num: u32) -> i32 {
|
||||
for _trial_time in 0..MAX_LOCK_TRIAL_TIME {
|
||||
if self.is_running(irq_num) {
|
||||
continue; //running标志位为1
|
||||
}
|
||||
if self.modify_lock.try_lock() {
|
||||
if self.is_running(irq_num) {
|
||||
self.modify_lock.unlock();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 存在尝试加锁规定次数后仍加锁失败的情况,报告错误并退出
|
||||
if !self.modify_lock.is_locked() {
|
||||
return -(EBUSY as i32);
|
||||
}
|
||||
self.clear_softirq_running(irq_num);
|
||||
self.clear_softirq_pending(irq_num);
|
||||
self.table[irq_num as usize].action = None;
|
||||
self.table[irq_num as usize].data = null_mut();
|
||||
self.modify_lock.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief 遍历执行软中断
|
||||
pub fn do_softirq(&mut self) {
|
||||
sti();
|
||||
let mut softirq_index: u32 = 0; //软中断向量号码
|
||||
while (softirq_index as u64) < MAX_SOFTIRQ_NUM && self.pending != 0 {
|
||||
if self.is_pending(softirq_index)
|
||||
&& self.table[softirq_index as usize].action.is_some()
|
||||
&& !self.is_running(softirq_index)
|
||||
{
|
||||
if self.modify_lock.try_lock() {
|
||||
if self.is_running(softirq_index)
|
||||
|| self.table[softirq_index as usize].action.is_none()
|
||||
{
|
||||
self.modify_lock.unlock();
|
||||
continue;
|
||||
}
|
||||
self.clear_softirq_pending(softirq_index);
|
||||
self.set_softirq_running(softirq_index);
|
||||
self.modify_lock.unlock();
|
||||
unsafe {
|
||||
(self.table[softirq_index as usize].action.unwrap())(
|
||||
self.table[softirq_index as usize].data,
|
||||
);
|
||||
}
|
||||
self.clear_softirq_running(softirq_index);
|
||||
}
|
||||
}
|
||||
softirq_index += 1;
|
||||
}
|
||||
cli();
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(panic_info_message)]
|
||||
#![feature(drain_filter)] // 允许Vec的drain_filter特性
|
||||
|
||||
#![feature(c_void_variant)] //not stable, used in /home/su/Documents/VSCode/DragonOS/kernel/src/exception/softirq.rs
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_snake_case)]
|
||||
@ -28,6 +28,7 @@ mod process;
|
||||
mod sched;
|
||||
mod smp;
|
||||
mod time;
|
||||
mod exception;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
|
@ -52,7 +52,8 @@ void reload_gdt()
|
||||
gdtp.size = bsp_gdt_size - 1;
|
||||
gdtp.gdt_vaddr = (ul)phys_2_virt((ul)&GDT_Table);
|
||||
|
||||
asm volatile("lgdt (%0) \n\t" ::"r"(&gdtp) : "memory");
|
||||
asm volatile("lgdt (%0) \n\t" ::"r"(&gdtp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
void reload_idt()
|
||||
@ -63,7 +64,8 @@ void reload_idt()
|
||||
// kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
|
||||
// kdebug("gdt size=%d", p.size);
|
||||
|
||||
asm volatile("lidt (%0) \n\t" ::"r"(&idtp) : "memory");
|
||||
asm volatile("lidt (%0) \n\t" ::"r"(&idtp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
// 初始化系统各模块
|
||||
@ -124,17 +126,18 @@ void system_initialize()
|
||||
irq_init();
|
||||
|
||||
softirq_init();
|
||||
|
||||
current_pcb->cpu_id = 0;
|
||||
current_pcb->preempt_count = 0;
|
||||
// 先初始化系统调用模块
|
||||
syscall_init();
|
||||
|
||||
io_mfence();
|
||||
// 再初始化进程模块。顺序不能调转
|
||||
// sched_init();
|
||||
io_mfence();
|
||||
|
||||
timer_init();
|
||||
|
||||
// 这里必须加内存屏障,否则会出错
|
||||
io_mfence();
|
||||
smp_init();
|
||||
@ -143,7 +146,7 @@ void system_initialize()
|
||||
vfs_init();
|
||||
devfs_init();
|
||||
procfs_init();
|
||||
|
||||
|
||||
cpu_init();
|
||||
ps2_keyboard_init();
|
||||
tty_init();
|
||||
@ -167,11 +170,12 @@ void system_initialize()
|
||||
// 启用double buffer
|
||||
// scm_enable_double_buffer(); // 因为时序问题, 该函数调用被移到 initial_kernel_thread
|
||||
io_mfence();
|
||||
// fat32_init();
|
||||
|
||||
HPET_enable();
|
||||
|
||||
io_mfence();
|
||||
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
|
||||
|
||||
apic_timer_init();
|
||||
io_mfence();
|
||||
|
||||
@ -180,7 +184,7 @@ void system_initialize()
|
||||
// pause();
|
||||
}
|
||||
|
||||
//操作系统内核从这里开始执行
|
||||
// 操作系统内核从这里开始执行
|
||||
void Start_Kernel(void)
|
||||
{
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::driver::timers::rtc::rtc::{rtc_get_cmos_time, rtc_time_t};
|
||||
use crate::driver::timers::rtc::rtc::RtcTime;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type ktime_t = i64;
|
||||
@ -15,17 +15,15 @@ fn ktime_to_ns(kt: ktime_t) -> i64 {
|
||||
/// 时间戳为从UTC+0 1970-01-01 00:00到当前UTC+0时间,所经过的纳秒数。
|
||||
/// 注意,由于当前未引入时区,因此本函数默认时区为UTC+8来计算
|
||||
fn ktime_get_real() -> ktime_t {
|
||||
let mut rtc_time: rtc_time_t = rtc_time_t {
|
||||
second: (0),
|
||||
minute: (0),
|
||||
hour: (0),
|
||||
day: (0),
|
||||
month: (0),
|
||||
year: (0),
|
||||
};
|
||||
let mut rtc_time: RtcTime = RtcTime::default();
|
||||
|
||||
//调用rtc.h里面的函数
|
||||
rtc_get_cmos_time(&mut rtc_time);
|
||||
{
|
||||
let r = rtc_time.get();
|
||||
// 返回错误码
|
||||
if r.is_err() {
|
||||
return r.unwrap_err() as ktime_t;
|
||||
}
|
||||
}
|
||||
|
||||
let mut day_count: i32 = 0;
|
||||
for year in 1970..rtc_time.year {
|
||||
|
Reference in New Issue
Block a user