From 36fd013004ee0bd5fc7cfb452ba22531a83a859c Mon Sep 17 00:00:00 2001 From: houmkh <1119644616@qq.com> Date: Sat, 17 Jun 2023 22:48:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0gettimeofday()=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E8=B0=83=E7=94=A8=E5=92=8Cclocksource+timekeeping?= =?UTF-8?q?=E5=AD=90=E6=A8=A1=E5=9D=97=20(#278)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现gettimeofday()系统调用 - 实现clocksource+timekeeping子模块部分功能 - 实现了timespec转换成日期时间 --- kernel/src/Makefile | 2 +- kernel/src/arch/x86_64/asm/irqflags.rs | 16 +- kernel/src/arch/x86_64/fpu.rs | 10 +- kernel/src/arch/x86_64/interrupt/mod.rs | 5 +- kernel/src/common/cpu.h | 9 +- kernel/src/driver/timers/HPET/HPET.c | 9 +- kernel/src/driver/timers/rtc/rtc.rs | 7 +- kernel/src/exception/softirq.rs | 5 +- kernel/src/include/bindings/wrapper.h | 1 + kernel/src/libs/cpu.c | 9 + kernel/src/libs/spinlock.rs | 12 +- kernel/src/main.c | 24 +- kernel/src/net/net_core.rs | 11 +- kernel/src/process/process.c | 3 +- kernel/src/syscall/mod.rs | 43 +- kernel/src/syscall/syscall_num.h | 3 + kernel/src/time/Makefile | 8 + kernel/src/time/clocksource.c | 8 + kernel/src/time/clocksource.h | 8 + kernel/src/time/clocksource.rs | 850 ++++++++++++++++++ kernel/src/time/jiffies.h | 3 + kernel/src/time/jiffies.rs | 100 +++ kernel/src/time/mod.rs | 19 +- kernel/src/time/syscall.rs | 52 +- kernel/src/time/timeconv.rs | 143 +++ kernel/src/time/timekeeping.h | 3 + kernel/src/time/timekeeping.rs | 312 +++++++ kernel/src/time/timer.h | 1 + kernel/src/time/timer.rs | 71 +- user/apps/test_gettimeofday/Makefile | 25 + user/apps/test_gettimeofday/link.lds | 239 +++++ user/apps/test_gettimeofday/main.c | 25 + user/dadk/config/relibc-0.1.0.dadk | 2 +- user/dadk/config/test_gettimeofday-0.1.0.dadk | 28 + 34 files changed, 1988 insertions(+), 78 deletions(-) create mode 100644 kernel/src/time/Makefile create mode 100644 kernel/src/time/clocksource.c create mode 100644 kernel/src/time/clocksource.h create mode 100644 kernel/src/time/clocksource.rs create mode 100644 kernel/src/time/jiffies.h create mode 100644 kernel/src/time/jiffies.rs create mode 100644 kernel/src/time/timeconv.rs create mode 100644 kernel/src/time/timekeeping.h create mode 100644 kernel/src/time/timekeeping.rs create mode 100644 user/apps/test_gettimeofday/Makefile create mode 100644 user/apps/test_gettimeofday/link.lds create mode 100644 user/apps/test_gettimeofday/main.c create mode 100644 user/dadk/config/test_gettimeofday-0.1.0.dadk diff --git a/kernel/src/Makefile b/kernel/src/Makefile index 3cc55d8e..e82886fc 100644 --- a/kernel/src/Makefile +++ b/kernel/src/Makefile @@ -17,7 +17,7 @@ export ASFLAGS := --64 LD_LIST := head.o -kernel_subdirs := common driver process debug arch exception mm smp sched syscall ktest libs ipc io +kernel_subdirs := common driver process debug arch exception mm smp sched syscall ktest libs ipc io time diff --git a/kernel/src/arch/x86_64/asm/irqflags.rs b/kernel/src/arch/x86_64/asm/irqflags.rs index 00b4eb31..667c8c8c 100644 --- a/kernel/src/arch/x86_64/asm/irqflags.rs +++ b/kernel/src/arch/x86_64/asm/irqflags.rs @@ -1,18 +1,18 @@ -use core::{arch::asm, ptr::read_volatile}; +use core::arch::asm; #[inline] -pub fn local_irq_save(flags: &mut u64) { +pub fn local_irq_save() -> usize { + let x: usize; unsafe { - asm!("pushfq", "pop rax", "mov rax, {0}", "cli", out(reg)(*flags),); + asm!("pushfq ; pop {} ; cli", out(reg) x, options(nostack)); } + x } #[inline] -pub fn local_irq_restore(flags: &u64) { - let x = unsafe { read_volatile(flags) }; - +// 恢复先前保存的rflags的值x +pub fn local_irq_restore(x: usize) { unsafe { - asm!("push r15", - "popfq", in("r15")(x)); + asm!("push {} ; popfq", in(reg) x, options(nostack)); } } diff --git a/kernel/src/arch/x86_64/fpu.rs b/kernel/src/arch/x86_64/fpu.rs index 654cf391..32c31127 100644 --- a/kernel/src/arch/x86_64/fpu.rs +++ b/kernel/src/arch/x86_64/fpu.rs @@ -79,8 +79,7 @@ impl FpState { /// @brief 从用户态进入内核时,保存浮点寄存器,并关闭浮点功能 pub fn fp_state_save(pcb: &mut process_control_block) { // 该过程中不允许中断 - let mut rflags: u64 = 0; - local_irq_save(&mut rflags); + let rflags = local_irq_save(); let fp: &mut FpState = if pcb.fp_state == null_mut() { let f = Box::leak(Box::new(FpState::default())); @@ -112,14 +111,13 @@ pub fn fp_state_save(pcb: &mut process_control_block) { "mov cr4, rax" */ ) } - local_irq_restore(&rflags); + local_irq_restore(rflags); } /// @brief 从内核态返回用户态时,恢复浮点寄存器,并开启浮点功能 pub fn fp_state_restore(pcb: &mut process_control_block) { // 该过程中不允许中断 - let mut rflags: u64 = 0; - local_irq_save(&mut rflags); + let rflags = local_irq_save(); if pcb.fp_state == null_mut() { panic!("fp_state_restore: fp_state is null. pid={}", pcb.pid); @@ -143,5 +141,5 @@ pub fn fp_state_restore(pcb: &mut process_control_block) { fp.restore(); fp.clear(); - local_irq_restore(&rflags); + local_irq_restore(rflags); } diff --git a/kernel/src/arch/x86_64/interrupt/mod.rs b/kernel/src/arch/x86_64/interrupt/mod.rs index 7e2143ab..6a12c1d0 100644 --- a/kernel/src/arch/x86_64/interrupt/mod.rs +++ b/kernel/src/arch/x86_64/interrupt/mod.rs @@ -48,8 +48,7 @@ impl InterruptArch for X86_64InterruptArch { unsafe fn save_and_disable_irq() -> IrqFlagsGuard { compiler_fence(Ordering::SeqCst); - let mut rflags: u64 = 0; - local_irq_save(&mut rflags); + let rflags = local_irq_save() as u64; let flags = IrqFlags::new(rflags); let guard = IrqFlagsGuard::new(flags); compiler_fence(Ordering::SeqCst); @@ -58,7 +57,7 @@ impl InterruptArch for X86_64InterruptArch { unsafe fn restore_irq(flags: IrqFlags) { compiler_fence(Ordering::SeqCst); - local_irq_restore(&flags.flags()); + local_irq_restore(flags.flags() as usize); compiler_fence(Ordering::SeqCst); } } diff --git a/kernel/src/common/cpu.h b/kernel/src/common/cpu.h index f034a2c7..c318ea05 100644 --- a/kernel/src/common/cpu.h +++ b/kernel/src/common/cpu.h @@ -66,4 +66,11 @@ extern struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM]; * * @return uint32_t 当前cpu核心晶振频率 */ -uint32_t cpu_get_core_crysral_freq(); \ No newline at end of file +uint32_t cpu_get_core_crysral_freq(); + +/** + * @brief 获取处理器的tsc频率(单位:hz) + * + * @return uint64_t + */ +uint64_t cpu_get_tsc_freq(); \ No newline at end of file diff --git a/kernel/src/driver/timers/HPET/HPET.c b/kernel/src/driver/timers/HPET/HPET.c index b1065491..7cb090f4 100644 --- a/kernel/src/driver/timers/HPET/HPET.c +++ b/kernel/src/driver/timers/HPET/HPET.c @@ -207,12 +207,13 @@ 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)))); - kinfo("HPET0 enabled."); - - __write8b(HPET_REG_BASE + GEN_CONF, 3); // 置位旧设备中断路由兼容标志位、定时器组使能标志位 - io_mfence(); // 注册中断 irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0"); + io_mfence(); + __write8b(HPET_REG_BASE + GEN_CONF, 3); // 置位旧设备中断路由兼容标志位、定时器组使能标志位 + kinfo("HPET0 enabled."); + + io_mfence(); } int HPET_init() diff --git a/kernel/src/driver/timers/rtc/rtc.rs b/kernel/src/driver/timers/rtc/rtc.rs index 4dd659df..e7e154e4 100644 --- a/kernel/src/driver/timers/rtc/rtc.rs +++ b/kernel/src/driver/timers/rtc/rtc.rs @@ -1,5 +1,6 @@ use crate::{ - arch::interrupt::{cli, sti}, + arch::CurrentIrqArch, + exception::InterruptArch, include::bindings::bindings::{io_in8, io_out8}, syscall::SystemError, }; @@ -33,7 +34,7 @@ impl RtcTime { ///@return int 成功则为0 pub fn get(&mut self) -> Result { // 为防止中断请求打断该过程,需要先关中断 - cli(); + let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; //0x0B let status_register_b: u8 = read_cmos(0x0B); // 读取状态寄存器B let is_24h: bool = if (status_register_b & 0x02) != 0 { @@ -81,7 +82,7 @@ impl RtcTime { self.hour = ((self.hour & 0x7f) + 12) % 24; } // 将十二小时制转为24小时 - sti(); + drop(irq_guard); return Ok(0); } diff --git a/kernel/src/exception/softirq.rs b/kernel/src/exception/softirq.rs index 0538677e..3cc6eff9 100644 --- a/kernel/src/exception/softirq.rs +++ b/kernel/src/exception/softirq.rs @@ -225,15 +225,14 @@ impl Softirq { } pub fn raise_softirq(&self, softirq_num: SoftirqNumber) { - let mut flags = 0; - local_irq_save(&mut flags); + let flags = local_irq_save(); let processor_id = smp_get_processor_id() as usize; cpu_pending(processor_id).insert(VecStatus::from(softirq_num)); compiler_fence(Ordering::SeqCst); - local_irq_restore(&flags); + local_irq_restore(flags); // kdebug!("raise_softirq exited"); } pub unsafe fn clear_softirq_pending(&self, softirq_num: SoftirqNumber) { diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index c7f8e730..8b64c995 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -46,4 +46,5 @@ #include #include #include +#include