Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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



Expand Down
16 changes: 5 additions & 11 deletions kernel/src/arch/x86_64/cpu.rs
Original file line number Diff line number Diff line change
@@ -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休息一会儿。降低空转功耗
Expand Down
13 changes: 6 additions & 7 deletions kernel/src/common/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -47,7 +46,7 @@ extern int usleep(useconds_t usec);

/**
* @brief 获取当前的CPU时间
*
*
* @return uint64_t timer_jiffies
*/
extern uint64_t clock();
extern uint64_t rs_clock();
2 changes: 1 addition & 1 deletion kernel/src/driver/interrupt/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ void do_IRQ(struct pt_regs *rsp, ul number)

// kdebug("before softirq");
// 进入软中断处理程序
do_softirq();
rs_do_softirq();

// kdebug("after softirq");
// 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度
Expand Down
1 change: 1 addition & 0 deletions kernel/src/driver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub mod pci;
pub mod timers;
pub mod tty;
pub mod uart;
pub mod video;
pub mod virtio;
16 changes: 8 additions & 8 deletions kernel/src/driver/timers/HPET/HPET.c
Original file line number Diff line number Diff line change
Expand Up @@ -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处理器
Expand All @@ -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;
Expand Down
18 changes: 9 additions & 9 deletions kernel/src/driver/usb/xhci/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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);
Expand Down
62 changes: 62 additions & 0 deletions kernel/src/driver/video/mod.rs
Original file line number Diff line number Diff line change
@@ -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();
}
25 changes: 14 additions & 11 deletions kernel/src/driver/video/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <sched/sched.h>
#include <time/timer.h>

extern void rs_register_softirq_video();

uint64_t video_refresh_expire_jiffies = 0;
uint64_t video_last_refresh_pid = -1;

Expand Down Expand Up @@ -57,7 +59,7 @@ int video_refresh_daemon(void *unused)

for (;;)
{
if (clock() >= video_refresh_expire_jiffies)
if (rs_clock() >= video_refresh_expire_jiffies)
{

if (likely(video_refresh_target != NULL))
Expand All @@ -68,7 +70,7 @@ int video_refresh_daemon(void *unused)
spin_unlock(&daemon_refresh_lock);
video_daemon_pcb->virtual_runtime = 0xfffff0000000; // 临时解决由于显示刷新进程的虚拟运行时间过大/过小,导致其不运行,或者一直运行的问题。将来应使用实时调度解决它
}
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
video_refresh_expire_jiffies = rs_timer_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
}
video_daemon_pcb->state &= ~PROC_RUNNING;
video_daemon_pcb->flags |= PF_NEED_SCHED;
Expand All @@ -85,7 +87,7 @@ void video_refresh_framebuffer(void *data)
{
if (unlikely(video_daemon_pcb == NULL))
return;
if (clock() >= video_refresh_expire_jiffies)
if (rs_clock() >= video_refresh_expire_jiffies)
{
video_daemon_pcb->virtual_runtime = 0;
process_wakeup(video_daemon_pcb);
Expand All @@ -105,18 +107,18 @@ int video_reinitialize(bool level) // 这个函数会在main.c调用, 保证 vid
init_frame_buffer();
else
{
unregister_softirq(VIDEO_REFRESH_SIRQ);
rs_unregister_softirq(VIDEO_REFRESH_SIRQ);
// 计算开始时间
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
video_refresh_expire_jiffies = rs_timer_next_n_ms_jiffies(10 * REFRESH_INTERVAL);

// 创建video守护进程
video_daemon_pcb = kthread_run(&video_refresh_daemon, NULL, "Video refresh daemon");
video_daemon_pcb->virtual_runtime = 0; // 特殊情况, 最高优先级, 以后再改

// 启用屏幕刷新软中断
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
rs_register_softirq_video();

raise_softirq(VIDEO_REFRESH_SIRQ);
rs_raise_softirq(VIDEO_REFRESH_SIRQ);
}
return 0;
}
Expand All @@ -130,20 +132,21 @@ int video_reinitialize(bool level) // 这个函数会在main.c调用, 保证 vid
int video_set_refresh_target(struct scm_buffer_info_t *buf)
{

unregister_softirq(VIDEO_REFRESH_SIRQ);
rs_unregister_softirq(VIDEO_REFRESH_SIRQ);
// todo: 在completion实现后,在这里等待其他刷新任务完成,再进行下一步。

// int counter = 100;

// while ((get_softirq_pending() & (1 << VIDEO_REFRESH_SIRQ)) && counter > 0)
// {
// --counter;
// usleep(1000);
// rs_usleep(1000);
// }
// kdebug("buf = %#018lx", buf);
video_refresh_target = buf;
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
raise_softirq(VIDEO_REFRESH_SIRQ);
rs_register_softirq_video();
kdebug("register softirq video done");
// rs_raise_softirq(VIDEO_REFRESH_SIRQ);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/driver/video/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ int video_set_refresh_target(struct scm_buffer_info_t *buf);
extern uint64_t video_refresh_expire_jiffies;
extern uint64_t video_last_refresh_pid;

extern void video_refresh_framebuffer();
void video_refresh_framebuffer(void *data);
Loading