diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 50a3b83a..7486e5bf 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["staticlib"] # 运行时依赖项 [dependencies] +x86 = "0.52.0" x86_64 = "0.14.10" bitflags = "1.3.2" virtio-drivers = "0.3.0" diff --git a/kernel/src/Makefile b/kernel/src/Makefile index 9e222cd5..3cc55d8e 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 time 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 diff --git a/kernel/src/arch/x86_64/cpu.rs b/kernel/src/arch/x86_64/cpu.rs index b6260cca..34877720 100644 --- a/kernel/src/arch/x86_64/cpu.rs +++ b/kernel/src/arch/x86_64/cpu.rs @@ -1,18 +1,12 @@ use core::arch::asm; +use super::asm::current::current_pcb; + /// @brief 获取当前cpu的apic id #[inline] -pub fn current_cpu_id() -> u8 { - let cpuid_res: u32; - unsafe { - asm!( - "mov eax, 1", - "cpuid", - "mov r15, rbx", - lateout("r15") cpuid_res - ); - } - return ((cpuid_res >> 24) & 0xff) as u8; +pub fn current_cpu_id() -> u32 { + // TODO: apic重构后,使用apic id来设置这里 + current_pcb().cpu_id as u32 } /// @brief 通过pause指令,让cpu休息一会儿。降低空转功耗 diff --git a/kernel/src/common/time.h b/kernel/src/common/time.h index 0142c33d..92a1417d 100644 --- a/kernel/src/common/time.h +++ b/kernel/src/common/time.h @@ -21,19 +21,18 @@ struct tm const char *__tm_zone; /* Timezone abbreviation. */ }; - struct timespec { - int64_t tv_sec; // 秒 - int64_t tv_nsec; // 纳秒 + int64_t tv_sec; // 秒 + int64_t tv_nsec; // 纳秒 }; /** * @brief 休眠指定时间 - * + * * @param rqtp 指定休眠的时间 * @param rmtp 返回的剩余休眠时间 - * @return int + * @return int */ extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); @@ -47,7 +46,7 @@ extern int usleep(useconds_t usec); /** * @brief 获取当前的CPU时间 - * + * * @return uint64_t timer_jiffies */ -extern uint64_t clock(); \ No newline at end of file +extern uint64_t rs_clock(); \ No newline at end of file diff --git a/kernel/src/driver/interrupt/apic/apic.c b/kernel/src/driver/interrupt/apic/apic.c index 0b45fb5b..3db2f720 100644 --- a/kernel/src/driver/interrupt/apic/apic.c +++ b/kernel/src/driver/interrupt/apic/apic.c @@ -456,7 +456,7 @@ void do_IRQ(struct pt_regs *rsp, ul number) // kdebug("before softirq"); // 进入软中断处理程序 - do_softirq(); + rs_do_softirq(); // kdebug("after softirq"); // 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度 diff --git a/kernel/src/driver/mod.rs b/kernel/src/driver/mod.rs index 54f0b1b6..d2187aea 100644 --- a/kernel/src/driver/mod.rs +++ b/kernel/src/driver/mod.rs @@ -4,4 +4,5 @@ pub mod pci; pub mod timers; pub mod tty; pub mod uart; +pub mod video; pub mod virtio; diff --git a/kernel/src/driver/timers/HPET/HPET.c b/kernel/src/driver/timers/HPET/HPET.c index dfa000ca..b1065491 100644 --- a/kernel/src/driver/timers/HPET/HPET.c +++ b/kernel/src/driver/timers/HPET/HPET.c @@ -67,7 +67,7 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) switch (param) { case 0: // 定时器0中断 - timer_jiffies += HPET0_INTERVAL; + rs_update_timer_jiffies(HPET0_INTERVAL); /* // 将HEPT中断消息转发到ap:1处理器 @@ -76,18 +76,18 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) */ // 若当前时间比定时任务的时间间隔大,则进入中断下半部 - if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies) - raise_softirq(TIMER_SIRQ); + if (rs_timer_get_first_expire() <= rs_clock()) + rs_raise_softirq(TIMER_SIRQ); // 当时间到了,或进程发生切换时,刷新帧缓冲区 - if (timer_jiffies >= video_refresh_expire_jiffies || (video_last_refresh_pid != current_pcb->pid)) + if (rs_clock() >= video_refresh_expire_jiffies || (video_last_refresh_pid != current_pcb->pid)) { - raise_softirq(VIDEO_REFRESH_SIRQ); + rs_raise_softirq(VIDEO_REFRESH_SIRQ); // 超过130ms仍未刷新完成,则重新发起刷新(防止由于进程异常退出导致的屏幕无法刷新) - if (unlikely(timer_jiffies >= (video_refresh_expire_jiffies + (1 << 17)))) + if (unlikely(rs_clock() >= (video_refresh_expire_jiffies + (1 << 17)))) { - video_refresh_expire_jiffies = timer_jiffies + (1 << 20); - clear_softirq_pending(VIDEO_REFRESH_SIRQ); + video_refresh_expire_jiffies = rs_clock() + (1 << 20); + rs_clear_softirq_pending(VIDEO_REFRESH_SIRQ); } } break; diff --git a/kernel/src/driver/usb/xhci/xhci.c b/kernel/src/driver/usb/xhci/xhci.c index 5c970362..fca7683f 100644 --- a/kernel/src/driver/usb/xhci/xhci.c +++ b/kernel/src/driver/usb/xhci/xhci.c @@ -245,7 +245,7 @@ static int xhci_hc_stop(int id) while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0) { io_mfence(); - usleep(1000); + rs_usleep(1000); if (--timeout == 0) return -ETIMEDOUT; } @@ -285,7 +285,7 @@ static int xhci_hc_reset(int id) while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1)) { io_mfence(); - usleep(1000); + rs_usleep(1000); if (--timeout == 0) return -ETIMEDOUT; } @@ -319,7 +319,7 @@ static int xhci_hc_stop_legacy(int id) XHCI_XECP_LEGACY_OS_OWNED) { io_mfence(); - usleep(1000); + rs_usleep(1000); if (--timeout == 0) { kerror("The BIOS doesn't stop legacy support."); @@ -352,7 +352,7 @@ static int xhci_hc_start_sched(int id) io_mfence(); xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 << 2) | (1 << 3)); io_mfence(); - usleep(100 * 1000); + rs_usleep(100 * 1000); } /** @@ -793,7 +793,7 @@ static int xhci_reset_port(const int id, const int port) io_mfence(); xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9)); io_mfence(); - usleep(2000); + rs_usleep(2000); // 检测端口是否被启用, 若未启用,则报错 if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0) { @@ -833,14 +833,14 @@ static int xhci_reset_port(const int id, const int port) break; #endif --timeout; - usleep(500); + rs_usleep(500); } // kdebug("timeout= %d", timeout); if (timeout > 0) { // 等待恢复 - usleep(USB_TIME_RST_REC * 100); + rs_usleep(USB_TIME_RST_REC * 100); uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC); io_mfence(); @@ -1219,7 +1219,7 @@ static int xhci_wait_for_interrupt(const int id, uint64_t status_vaddr) } } --timer; - usleep(1000); + rs_usleep(1000); } kerror(" USB xHCI Interrupt wait timed out."); @@ -2001,7 +2001,7 @@ static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring) // We use bit 31 of the command dword since it is reserved while (timer && ((__read4b(origin_trb_vaddr + 8) & XHCI_IRQ_DONE) == 0)) { - usleep(1000); + rs_usleep(1000); --timer; } uint32_t x = xhci_read_cap_reg32(id, xhci_hc[id].rts_offset + 0x20); diff --git a/kernel/src/driver/video/mod.rs b/kernel/src/driver/video/mod.rs new file mode 100644 index 00000000..878c0a94 --- /dev/null +++ b/kernel/src/driver/video/mod.rs @@ -0,0 +1,62 @@ +use core::{ptr::null_mut, sync::atomic::{AtomicBool, Ordering}}; + +use alloc::sync::Arc; + +use crate::{ + exception::softirq::{SoftirqNumber, SoftirqVec, softirq_vectors}, + include::bindings::bindings::video_refresh_framebuffer, +}; + +#[derive(Debug)] +pub struct VideoRefreshFramebuffer{ + running: AtomicBool +} + +impl SoftirqVec for VideoRefreshFramebuffer { + fn run(&self) { + if self.set_run() == false{ + return; + } + + unsafe { + video_refresh_framebuffer(null_mut()); + } + + self.clear_run(); + } +} +impl VideoRefreshFramebuffer { + pub fn new() -> VideoRefreshFramebuffer { + VideoRefreshFramebuffer { + running: AtomicBool::new(false) + } + } + + fn set_run(&self) -> bool { + let x = self + .running + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed); + if x.is_ok() { + return true; + } else { + return false; + } + } + + fn clear_run(&self) { + self.running.store(false, Ordering::Release); + } +} + +pub fn register_softirq_video() { + // kdebug!("register_softirq_video"); + let handler = Arc::new(VideoRefreshFramebuffer::new()); + softirq_vectors() + .register_softirq(SoftirqNumber::VideoRefresh, handler) + .expect("register_softirq_video run failed"); +} +// ======= 以下为给C提供的接口,video重构完后请删除 ======= +#[no_mangle] +pub extern "C" fn rs_register_softirq_video() { + register_softirq_video(); +} diff --git a/kernel/src/driver/video/video.c b/kernel/src/driver/video/video.c index 3f05a675..9a49dd94 100644 --- a/kernel/src/driver/video/video.c +++ b/kernel/src/driver/video/video.c @@ -13,6 +13,8 @@ #include #include