From dcb1b51a5f6221b9515df54017af0c8ac5dfed98 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Mon, 4 Mar 2019 23:52:19 +0800 Subject: [PATCH] Improve time-related syscall precision and add some comment for MSI --- kernel/src/arch/x86_64/consts.rs | 4 +++- kernel/src/drivers/bus/pci.rs | 8 ++++--- kernel/src/drivers/net/e1000.rs | 8 +++++-- kernel/src/shell.rs | 4 +++- kernel/src/syscall/mod.rs | 2 +- kernel/src/syscall/time.rs | 41 ++++++++++++++++++++++++++++---- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/kernel/src/arch/x86_64/consts.rs b/kernel/src/arch/x86_64/consts.rs index c2426c5..b7cff18 100644 --- a/kernel/src/arch/x86_64/consts.rs +++ b/kernel/src/arch/x86_64/consts.rs @@ -94,4 +94,6 @@ pub const USER_TMP_TLS_PML4: usize = (USER_TMP_TLS_OFFSET & PML4_MASK) / PML4_SI /// Offset for usage in other temporary pages pub const USER_TMP_MISC_OFFSET: usize = USER_TMP_TLS_OFFSET + PML4_SIZE; -pub const USER_TMP_MISC_PML4: usize = (USER_TMP_MISC_OFFSET & PML4_MASK) / PML4_SIZE; \ No newline at end of file +pub const USER_TMP_MISC_PML4: usize = (USER_TMP_MISC_OFFSET & PML4_MASK) / PML4_SIZE; + +pub const USEC_PER_TICK: usize = 10000; \ No newline at end of file diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 2097870..49f9ef3 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -173,10 +173,13 @@ impl PciTag { while cap_ptr > 0 { let cap_id = self.read(cap_ptr, 1); if cap_id == PCI_CAP_ID_MSI { - self.write(cap_ptr + PCI_MSI_ADDR, 0xfee << 20); - // irq 23 temporarily + self.write(cap_ptr + PCI_MSI_ADDR, 0xfee00000); + // irq 23 means no 23, should be allocated from a pool + // 23 + 32 = 55 + // 0 is (usually) the apic id of the bsp. self.write(cap_ptr + PCI_MSI_DATA, 55 | 0 << 12); + // enable MSI interrupt let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4); self.write(cap_ptr + PCI_MSI_CTRL_CAP, orig_ctrl | 0x10000); break; @@ -184,7 +187,6 @@ impl PciTag { info!("cap id {} at {:#X}", self.read(cap_ptr, 1), cap_ptr); cap_ptr = self.read(cap_ptr + 1, 1); } - } } diff --git a/kernel/src/drivers/net/e1000.rs b/kernel/src/drivers/net/e1000.rs index 25f9da9..8490b91 100644 --- a/kernel/src/drivers/net/e1000.rs +++ b/kernel/src/drivers/net/e1000.rs @@ -94,7 +94,9 @@ impl Driver for E1000Interface { }; if irq { - let timestamp = Instant::from_millis(unsafe { crate::trap::TICK as i64 }); + let timestamp = Instant::from_millis(unsafe { + (crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000) as i64 + }); let mut sockets = self.sockets.lock(); match self.iface.lock().poll(&mut sockets, timestamp) { Ok(_) => { @@ -175,7 +177,9 @@ impl NetDriver for E1000Interface { } fn poll(&mut self) { - let timestamp = Instant::from_millis(unsafe { crate::trap::TICK as i64 }); + let timestamp = Instant::from_millis(unsafe { + (crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000) as i64 + }); let mut sockets = self.sockets.lock(); match self.iface.lock().poll(&mut sockets, timestamp) { Ok(_) => { diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 4355d2c..156b7df 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -171,7 +171,9 @@ fn get_line(history: &mut Vec>) -> String { } } - history.push(line_vec.clone()); + if line_vec.len() > 0 { + history.push(line_vec.clone()); + } String::from_utf8(line_vec).unwrap_or_default() } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index e0a549c..d4caf88 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -80,7 +80,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 083 => sys_mkdir(args[0] as *const u8, args[1]), 086 => sys_link(args[0] as *const u8, args[1] as *const u8), 087 => sys_unlink(args[0] as *const u8), - 096 => sys_gettimeofday(args[0] as *mut u64, args[1] as *const u8), + 096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8), // 097 => sys_getrlimit(), // 098 => sys_getrusage(), 110 => sys_getppid(), diff --git a/kernel/src/syscall/time.rs b/kernel/src/syscall/time.rs index 2300553..2140193 100644 --- a/kernel/src/syscall/time.rs +++ b/kernel/src/syscall/time.rs @@ -1,9 +1,23 @@ //! Syscalls for time use super::*; +use crate::arch::consts::USEC_PER_TICK; use crate::arch::driver::rtc_cmos; +use lazy_static::lazy_static; -pub fn sys_gettimeofday(tv: *mut u64, tz: *const u8) -> SysResult { +lazy_static! { + pub static ref EPOCH_BASE: u64 = unsafe { rtc_cmos::read_epoch() }; + pub static ref TICK_BASE: u64 = unsafe { crate::trap::TICK as u64 }; +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct TimeVal { + sec: u64, + usec: u64, +} + +pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult { if tz as usize != 0 { return Err(SysError::EINVAL); } @@ -11,18 +25,35 @@ pub fn sys_gettimeofday(tv: *mut u64, tz: *const u8) -> SysResult { let mut proc = process(); proc.memory_set.check_mut_ptr(tv)?; - unsafe { *tv = rtc_cmos::read_epoch() }; + let tick_base = *TICK_BASE; + let epoch_base = *EPOCH_BASE; + let tick = unsafe { crate::trap::TICK as u64 }; + + let usec = (tick - tick_base) * USEC_PER_TICK as u64; + let sec = epoch_base + usec / 1_000_000; + let timeval = TimeVal { + sec, + usec: usec % 1_000_000, + }; + unsafe { + *tv = timeval; + } Ok(0) } pub fn sys_time(time: *mut u64) -> SysResult { - let t = rtc_cmos::read_epoch(); + let tick_base = *TICK_BASE; + let epoch_base = *EPOCH_BASE; + let tick = unsafe { crate::trap::TICK as u64 }; + + let usec = (tick - tick_base) * USEC_PER_TICK as u64; + let sec = epoch_base + usec / 1_000_000; if time as usize != 0 { let mut proc = process(); proc.memory_set.check_mut_ptr(time)?; unsafe { - time.write(t as u64); + time.write(sec as u64); } } - Ok(t as isize) + Ok(sec as isize) }