diff --git a/kernel/src/driver/mod.rs b/kernel/src/driver/mod.rs index 8c203607..e15146ed 100644 --- a/kernel/src/driver/mod.rs +++ b/kernel/src/driver/mod.rs @@ -1 +1,2 @@ pub mod uart; +pub mod timers; diff --git a/kernel/src/driver/timers/HPET/HPET.c b/kernel/src/driver/timers/HPET/HPET.c index 27e7f12b..dfa000ca 100644 --- a/kernel/src/driver/timers/HPET/HPET.c +++ b/kernel/src/driver/timers/HPET/HPET.c @@ -207,8 +207,6 @@ void HPET_enable() // kdebug("[HPET0] conf register after modify=%#018lx", ((*(uint64_t *)(HPET_REG_BASE + TIM0_CONF)))); // kdebug("[HPET1] conf register =%#018lx", ((*(uint64_t *)(HPET_REG_BASE + TIM1_CONF)))); - rtc_get_cmos_time(&rtc_now); - kinfo("HPET0 enabled."); __write8b(HPET_REG_BASE + GEN_CONF, 3); // 置位旧设备中断路由兼容标志位、定时器组使能标志位 diff --git a/kernel/src/driver/timers/HPET/HPET.h b/kernel/src/driver/timers/HPET/HPET.h index 4e1124b7..95005ba7 100644 --- a/kernel/src/driver/timers/HPET/HPET.h +++ b/kernel/src/driver/timers/HPET/HPET.h @@ -2,7 +2,6 @@ #include #include -#include #define E_HPET_INIT_FAILED 1 diff --git a/kernel/src/driver/timers/Makefile b/kernel/src/driver/timers/Makefile index 21650ea8..96b26813 100644 --- a/kernel/src/driver/timers/Makefile +++ b/kernel/src/driver/timers/Makefile @@ -1,10 +1,6 @@ - -all: rtc.o HPET.o +all: HPET.o CFLAGS += -I . -rtc.o: rtc/rtc.c - $(CC) $(CFLAGS) -c rtc/rtc.c -o rtc/rtc.o - HPET.o: HPET/HPET.c $(CC) $(CFLAGS) -c HPET/HPET.c -o HPET/HPET.o diff --git a/kernel/src/driver/timers/mod.rs b/kernel/src/driver/timers/mod.rs new file mode 100644 index 00000000..db221127 --- /dev/null +++ b/kernel/src/driver/timers/mod.rs @@ -0,0 +1 @@ +pub mod rtc; \ No newline at end of file diff --git a/kernel/src/driver/timers/rtc/mod.rs b/kernel/src/driver/timers/rtc/mod.rs new file mode 100644 index 00000000..db221127 --- /dev/null +++ b/kernel/src/driver/timers/rtc/mod.rs @@ -0,0 +1 @@ +pub mod rtc; \ No newline at end of file diff --git a/kernel/src/driver/timers/rtc/rtc.c b/kernel/src/driver/timers/rtc/rtc.c deleted file mode 100644 index 34ce48e7..00000000 --- a/kernel/src/driver/timers/rtc/rtc.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "rtc.h" -#include - -/*置位0x70的第7位,禁止不可屏蔽中断*/ - -#define read_cmos(addr) ({ \ - io_out8(0x70, 0x80 | addr); \ - io_in8(0x71); \ -}) - -enum CMOSTimeSelector -{ - T_SECOND = 0x0, - T_MINUTE = 0x2, - T_HOUR = 0x4, - T_DAY = 0x7, - T_MONTH = 0x8, - T_YEAR = 0x9, -}; - - -int rtc_get_cmos_time(struct rtc_time_t *t) -{ - // 为防止中断请求打断该过程,需要先关中断 - cli(); - - uint8_t status_register_B = read_cmos(0x0B); // 读取状态寄存器B - bool is_24h = ((status_register_B & 0x02) ? true : false); // 判断是否启用24小时模式 - bool is_binary = ((status_register_B & 0x04) ? true : false); // 判断是否为二进制码 - - do - { - t->year = read_cmos(0x09); - t->month = read_cmos(0x08); - t->day = read_cmos(0x07); - t->hour = read_cmos(0x04); - t->minute = read_cmos(0x02); - t->second = read_cmos(0x00); - } while (t->second != read_cmos(0x00)); // 若读取时间过程中时间发生跳变则重新读取 - // 使能NMI中断 - 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) // 将十二小时制转为24小时 - t->hour = ((t->hour & 0x7f) + 12) % 24; - sti(); - return 0; -} diff --git a/kernel/src/driver/timers/rtc/rtc.h b/kernel/src/driver/timers/rtc/rtc.h deleted file mode 100644 index 2adb1670..00000000 --- a/kernel/src/driver/timers/rtc/rtc.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include -struct rtc_time_t -{ - int second; - int minute; - int hour; - int day; - int month; - int year; -}rtc_now; // rtc_now为墙上时钟,由HPET定时器0维护 - -/** - * @brief 从主板cmos中获取时间 - * - * @param t time结构体 - * @return int 成功则为0 - */ -int rtc_get_cmos_time(struct rtc_time_t*t); - -void rtc_init(); \ No newline at end of file diff --git a/kernel/src/driver/timers/rtc/rtc.rs b/kernel/src/driver/timers/rtc/rtc.rs new file mode 100644 index 00000000..7e7a8442 --- /dev/null +++ b/kernel/src/driver/timers/rtc/rtc.rs @@ -0,0 +1,89 @@ +pub struct rtc_time_t { + pub second: i32, + pub minute: i32, + pub hour: i32, + pub day: i32, + pub month: i32, + pub year: i32, +} + +use crate::{ + arch::x86_64::interrupt::{cli, sti}, + include::bindings::bindings::{io_in8, io_out8}, +}; + +///置位0x70的第7位,禁止不可屏蔽中断 +#[inline] +fn read_cmos(addr: u8) -> u8 { + unsafe { + io_out8(0x70, 0x80 | addr); + return io_in8(0x71); + } +} + +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 { + 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); +} diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index 29c2afc6..97dcbd7e 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 180a3a84..f27c7f97 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -79,6 +79,5 @@ pub fn panic(info: &PanicInfo) -> ! { #[no_mangle] pub extern "C" fn __rust_demo_func() -> i32 { printk_color!(GREEN, BLACK, "__rust_demo_func()\n"); - return 0; } diff --git a/kernel/src/main.c b/kernel/src/main.c index 763dae39..0ada4ee9 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -33,7 +33,6 @@ #include "driver/pci/pci.h" #include "driver/tty/tty.h" #include -#include #include #include #include diff --git a/kernel/src/time/timekeep.rs b/kernel/src/time/timekeep.rs index ff1b65a4..95e53a98 100644 --- a/kernel/src/time/timekeep.rs +++ b/kernel/src/time/timekeep.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] -use crate::include::bindings::bindings::{rtc_get_cmos_time, rtc_time_t}; + +use crate::driver::timers::rtc::rtc::{rtc_get_cmos_time, rtc_time_t}; #[allow(non_camel_case_types)] pub type ktime_t = i64; @@ -23,10 +24,8 @@ fn ktime_get_real() -> ktime_t { year: (0), }; - unsafe { - //调用rtc.h里面的函数 - rtc_get_cmos_time(&mut rtc_time); - } + //调用rtc.h里面的函数 + rtc_get_cmos_time(&mut rtc_time); let mut day_count: i32 = 0; for year in 1970..rtc_time.year { @@ -36,9 +35,7 @@ fn ktime_get_real() -> ktime_t { } else { day_count += 365; } - //println!("{},{}",year,day_count); } - //println!("day count1: {}",day_count); for month in 1..rtc_time.month { match month { 1 | 3 | 5 | 7 | 8 | 10 | 12 => day_count += 31, @@ -46,16 +43,14 @@ fn ktime_get_real() -> ktime_t { 4 | 6 | 9 | 11 => day_count += 30, _ => day_count += 0, } - //println!("{}:{}",month,day_count); } day_count += rtc_time.day - 1; - //println!("day count2: {}",day_count); //转换成纳秒 let timestamp: ktime_t = day_count as i64 * 86_400_000_000_000i64 + (rtc_time.hour - 8) as i64 * 3_600_000_000_000i64 + rtc_time.minute as i64 * 60_000_000_000i64 - + rtc_time.second as i64 * 1_000_000_000i64 as ktime_t; + + rtc_time.second as i64 * 1_000_000_000u64 as ktime_t; return timestamp; } diff --git a/kernel/src/time/timer.h b/kernel/src/time/timer.h index ba2dcefe..43b7b104 100644 --- a/kernel/src/time/timer.h +++ b/kernel/src/time/timer.h @@ -2,7 +2,7 @@ #include #include -#include + // 定义LONG_MAX为最大超时时间 - 允许负数 #define MAX_TIMEOUT (int64_t)((1ul << 63) - 1)