diff --git a/.cargo/config.toml b/.cargo/config.toml index 19e61a1..3c4a4d6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,3 @@ [build] target-dir = "build" target = "riscv64gc-unknown-none-elf" - -#[target.riscv64gc-unknown-none-elf] -# rustflags = ["-Clink-arg=-Tlinker.ld","--extern", "__alloc_error_handler=build/liballoc_error_handler.rlib"] diff --git a/Cargo.lock b/Cargo.lock index 08ac976..f27a7e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,16 +111,6 @@ dependencies = [ "runikraft", ] -[[package]] -name = "rkschedpreem" -version = "0.1.0" -dependencies = [ - "rkalloc", - "rkplat", - "rksched", - "runikraft", -] - [[package]] name = "rksignal" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0f40f5d..c6d1441 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,6 @@ members = [ "lib/rkmbox", "lib/rksched", "lib/rkschedcoop", - "lib/rkschedpreem", + #"lib/rkschedpreem", "lib/rksignal", ] diff --git a/lib/rkboot/src/lib.rs b/lib/rkboot/src/lib.rs index 3b427f9..7d9a5f8 100644 --- a/lib/rkboot/src/lib.rs +++ b/lib/rkboot/src/lib.rs @@ -88,6 +88,7 @@ fn thread_main(arg: *mut u8) { bootstrap::halt(); } +#[cfg(feature="have_scheduler")] fn sched_start(arg: *mut u8) -> !{ unsafe { (**(arg as *mut *mut dyn RKsched)).start(); diff --git a/lib/rklist/tests/list.rs b/lib/rklist/tests/list.rs deleted file mode 100644 index 719b21e..0000000 --- a/lib/rklist/tests/list.rs +++ /dev/null @@ -1,3 +0,0 @@ -// test rklist - -// TODO \ No newline at end of file diff --git a/lib/rkplat/Cargo.toml b/lib/rkplat/Cargo.toml index daea18a..3555b84 100644 --- a/lib/rkplat/Cargo.toml +++ b/lib/rkplat/Cargo.toml @@ -12,7 +12,7 @@ authors = [ ] [features] - default = ["has_smp","driver_ns16550","driver_virtio_all"] + default = ["has_smp","driver_ns16550","driver_virtio_all","driver_goldfish_rtc"] has_smp = [] # 对称多处理器支持 save_fp = [] # 在线程切换时保存浮点寄存器 driver_uart = [] # 串口设备驱动 @@ -24,6 +24,8 @@ authors = [ driver_virtio_input = ["driver_virtio"] driver_virtio_net = ["driver_virtio"] driver_virtio_all = ["driver_virtio_blk","driver_virtio_console","driver_virtio_gpu","driver_virtio_input","driver_virtio_net"] + driver_rtc = [] # 真实时间时钟驱动 + driver_goldfish_rtc = ["driver_rtc"] bios_io = [] # 使用BIOS输出 [dependencies] diff --git a/lib/rkplat/src/drivers/device_tree.rs b/lib/rkplat/src/drivers/device_tree.rs index 048fbdd..20d9e5d 100644 --- a/lib/rkplat/src/drivers/device_tree.rs +++ b/lib/rkplat/src/drivers/device_tree.rs @@ -276,6 +276,13 @@ fn parse_device(a: &dyn RKalloc, name: &str, props: &[(&str,&[u8])], props_size: prop_u32(props,props_size,"interrupts").unwrap() as usize))); } }, + #[cfg(feature="driver_goldfish_rtc")] + "google,goldfish-rtc" => { + unsafe { + crate::time::RTC_DEVICE = Some(&*alloc_type(a, + super::rtc::goldfish::GoldfishRtc::new(name, prop_u64(props,props_size,"reg").unwrap() as usize))); + } + }, #[cfg(feature="driver_virtio")] "virtio,mmio" => { let header = unsafe { diff --git a/lib/rkplat/src/drivers/mod.rs b/lib/rkplat/src/drivers/mod.rs index 4b1b7f0..b9c9fa7 100644 --- a/lib/rkplat/src/drivers/mod.rs +++ b/lib/rkplat/src/drivers/mod.rs @@ -2,6 +2,8 @@ pub mod uart; #[cfg(feature="driver_virtio")] pub mod virtio; +#[cfg(feature="driver_rtc")] +pub mod rtc; pub mod device_tree; pub type DriverIntHandler = fn(); diff --git a/lib/rkplat/src/drivers/rtc/goldfish.rs b/lib/rkplat/src/drivers/rtc/goldfish.rs new file mode 100644 index 0000000..c7930f4 --- /dev/null +++ b/lib/rkplat/src/drivers/rtc/goldfish.rs @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: BSD-3-Clause +// goldfish.rs +// Authors: 张子辰 +// Copyright (C) 2022 吴骏东, 张子辰, 蓝俊玮, 郭耸霄 and 陈建绿. + +use super::{RtcDevice, super::Device}; +use core::{slice,str}; +use core::time::Duration; +use crate::device::ioreg_read32; + +const TIME_LOW: usize = 0x00; // R: Get current time, then return low-order 32-bits. +const TIME_HIGH: usize = 0x04; // R: Return high 32-bits, from previous TIME_LOW read. + +pub struct GoldfishRtc { + addr: usize, + name: [u8;32], + name_size: usize, +} + +impl GoldfishRtc { + pub fn new(name: &str, addr: usize) -> Self { + assert!(name.len()<=32); + let mut name1: [u8;32] = [0;32]; + for i in 0..name.len() { + name1[i] = name.as_bytes()[i]; + } + println_bios!("Init goldfish RTC device, name={},addr=0x{:x}.",name,addr); + + Self { + addr, + name: name1, + name_size: name.len() + } + } + + #[inline(always)] + fn reg(&self, r: usize) -> *mut u32{ + (self.addr + r) as *mut u32 + } + + #[inline(always)] + fn reg_read(&self, r: usize) -> u32 { + unsafe{ioreg_read32(self.reg(r))} + } +} + +impl Device for GoldfishRtc { + fn name<'a>(&'a self) -> &'a str { + unsafe {str::from_utf8_unchecked(slice::from_raw_parts(self.name.as_ptr(), self.name_size))} + } +} + +impl RtcDevice for GoldfishRtc { + fn time(&self) -> Duration { + let mut high = self.reg_read(TIME_HIGH); + let mut low = self.reg_read(TIME_LOW); + let high2 = self.reg_read(TIME_HIGH); + if high2 != high { + low = self.reg_read(TIME_LOW); + high = high2; + } + Duration::from_nanos(((high as u64)<<32) + (low as u64)) + } +} diff --git a/lib/rkplat/src/drivers/rtc/mod.rs b/lib/rkplat/src/drivers/rtc/mod.rs new file mode 100644 index 0000000..b33d8f7 --- /dev/null +++ b/lib/rkplat/src/drivers/rtc/mod.rs @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: BSD-3-Clause +// rtc/mod.rs +// Authors: 张子辰 +// Copyright (C) 2022 吴骏东, 张子辰, 蓝俊玮, 郭耸霄 and 陈建绿. + +use super::Device; +use core::time::Duration; + +pub trait RtcDevice: Device { + /// 获取系统时间(通常是UNIX时间) + fn time(&self) -> Duration; +} + +#[cfg(feature="driver_goldfish_rtc")] +pub mod goldfish; diff --git a/lib/rkplat/src/drivers/uart/ns16550.rs b/lib/rkplat/src/drivers/uart/ns16550.rs index acfaa5e..87b0f10 100644 --- a/lib/rkplat/src/drivers/uart/ns16550.rs +++ b/lib/rkplat/src/drivers/uart/ns16550.rs @@ -29,6 +29,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +#![allow(dead_code)] + use core::{str, slice}; use super::UartDevice; use crate::drivers::Device; @@ -38,16 +40,16 @@ use crate::lcpu::spinwait; const THR: usize = 0x00; const RBR: usize = 0x00; const IER: usize = 0x01; -// const IIR: usize = 0x02; +const IIR: usize = 0x02; const FCR: usize = 0x02; const LCR: usize = 0x03; -// const MCR: usize = 0x04; +const MCR: usize = 0x04; const LSR: usize = 0x05; -// const MSR: usize = 0x06; +const MSR: usize = 0x06; const REG_SHIFT: usize = 0x00; -// const LCR_DLAB: u8 = 0x80; +const LCR_DLAB: u8 = 0x80; const IER_INT_EN: u8 = 0x01; const FCR_FIFO_EN: u8 = 0x01; const LSR_RX_READY: u8 = 0x01; @@ -55,7 +57,7 @@ const LSR_TX_VALID: u8 = 0x40; pub struct Ns16550 { addr: usize, //地址 - //irq: usize, //中断号 + irq: usize, //中断号 name: [u8;32], name_size: usize, } @@ -70,7 +72,7 @@ impl Ns16550 { println_bios!("Init ns16550 device, name={},addr=0x{:x},irq={}.",name,addr,irq); Self { - addr,//irq, + addr,irq, name: name1, name_size: name.len() }.init() diff --git a/lib/rkplat/src/riscv64/time.rs b/lib/rkplat/src/riscv64/time.rs index 54dcfb3..d084126 100644 --- a/lib/rkplat/src/riscv64/time.rs +++ b/lib/rkplat/src/riscv64/time.rs @@ -4,8 +4,12 @@ // Copyright (C) 2022 吴骏东, 张子辰, 蓝俊玮, 郭耸霄 and 陈建绿. use super::{lcpu,sbi}; +use core::time::Duration; +#[cfg(feature="driver_rtc")] +use crate::drivers::rtc::RtcDevice; -pub type Duration = core::time::Duration; +#[cfg(feature="driver_rtc")] +pub(crate) static mut RTC_DEVICE: Option<&dyn RtcDevice> = None; /// 1秒 pub const SEC: Duration = Duration::new(1, 0); @@ -64,7 +68,14 @@ pub fn monotonic_clock() -> Duration { /// 获取UNIX时间 pub fn wall_clock() -> Duration { - todo!("用rtc实现"); + #[cfg(feature="driver_rtc")] + { + unsafe{RTC_DEVICE.unwrap().time()} + } + #[cfg(not(feature="driver_rtc"))] + { + unimplemented!("Feature `driver_rtc` is disabled."); + } } pub(crate) fn block(until: Duration) { diff --git a/makefile b/makefile index 417fc71..e2ac3f7 100644 --- a/makefile +++ b/makefile @@ -65,7 +65,7 @@ test: $(MAKE_ROOT_DIR)/test/makefile $(MAKE_ROOT_DIR)/test/makefile: makefiles/test.mk.sh makefiles/test.mk.0 makefiles/test.mk.1 -mkdir --parents $(MAKE_ROOT_DIR)/test - makefiles/test.mk.sh makefiles/test.mk $(MAKE_ROOT_DIR)/test/makefile + makefiles/test.mk.sh makefiles/test.mk $(MAKE_ROOT_DIR)/test/makefile $(TEST_ROOT_DIR) .PHONY: dev-test dev-test: $(RUST_OUTPUT_DIR)/dev-test.bin diff --git a/makefiles/test.mk.1 b/makefiles/test.mk.1 index fb3659f..7aed966 100644 --- a/makefiles/test.mk.1 +++ b/makefiles/test.mk.1 @@ -1,14 +1,14 @@ # -*- makefile -*- .PHONY: @testname@ @testname@.bin @testname@: @testname@.bin - qemu-system-riscv64 -machine virt -nographic -bios $$RISCV_BIOS -kernel alloc_buddy0.bin + qemu-system-riscv64 -machine virt -nographic -bios $$RISCV_BIOS -kernel @testname@.bin @testname@.bin: $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib $(TEST_BUILD_DIR)/deps/liballoc_error_handler.rlib ifeq ($(MAKE_BUILD_TYPE), release) - cd $(TEST_ROOT_DIR)/@testname@ && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build --release --features rkalloc/__alloc_error_handler + cd $(TEST_ROOT_DIR)/@testname@ && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build --offline --release --features rkalloc/__alloc_error_handler else ifeq ($(MAKE_BUILD_TYPE), debug) - cd $(TEST_ROOT_DIR)/@testname@ && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build --features rkalloc/__alloc_error_handler + cd $(TEST_ROOT_DIR)/@testname@ && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build --offline --features rkalloc/__alloc_error_handler else @echo "Unknown build type, expect release/debug." false diff --git a/makefiles/test.mk.sh b/makefiles/test.mk.sh index 388a664..ba52278 100755 --- a/makefiles/test.mk.sh +++ b/makefiles/test.mk.sh @@ -1,6 +1,6 @@ #!/bin/sh -TEST_LIST='alloc_buddy0' +TEST_LIST=$(ls -C $3) echo "# Generated by \`$0\` ." > $2 diff --git a/test/alloc_buddy0/.cargo/config.toml b/test/alloc_buddy0/.cargo/config.toml index ec31dc7..81efcfc 100644 --- a/test/alloc_buddy0/.cargo/config.toml +++ b/test/alloc_buddy0/.cargo/config.toml @@ -1,6 +1,3 @@ [build] target-dir = "../../build/test" target = "riscv64gc-unknown-none-elf" - -[target.riscv64gc-unknown-none-elf] - rustflags = ["-Clink-arg=-T../../linker.ld","--extern", "__alloc_error_handler=../../build/liballoc_error_handler.rlib"] diff --git a/test/rkplat_time0/.cargo/config.toml b/test/rkplat_time0/.cargo/config.toml new file mode 100644 index 0000000..81efcfc --- /dev/null +++ b/test/rkplat_time0/.cargo/config.toml @@ -0,0 +1,3 @@ +[build] + target-dir = "../../build/test" + target = "riscv64gc-unknown-none-elf" diff --git a/test/rkplat_time0/Cargo.toml b/test/rkplat_time0/Cargo.toml new file mode 100644 index 0000000..0a3b6a3 --- /dev/null +++ b/test/rkplat_time0/Cargo.toml @@ -0,0 +1,11 @@ +[package] + name = "test-rkplat_time0" + version = "0.1.0" + edition = "2021" + +[workspace] + +[dependencies] + rkplat = {path = "../../lib/rkplat", default-features = false, features=["driver_ns16550","driver_goldfish_rtc"]} + rkalloc = {path = "../../lib/rkalloc"} + rkboot = {path = "../../lib/rkboot", default-features = false, features=["alloc_buddy"]} diff --git a/test/rkplat_time0/src/main.rs b/test/rkplat_time0/src/main.rs new file mode 100644 index 0000000..ccdf3fe --- /dev/null +++ b/test/rkplat_time0/src/main.rs @@ -0,0 +1,17 @@ +#![no_std] +#![no_main] + +extern crate rkboot; +#[macro_use] +extern crate rkplat; + +use rkplat::time::{wall_clock,monotonic_clock,get_ticks}; + +#[no_mangle] +fn main(_args: &mut [&str])->i32 { + let time1 = wall_clock(); + let time2 = monotonic_clock(); + let time3 = get_ticks(); + println!("wall_clock()={:?}\nmonotonic_clock()={:?}\nget_ticks()={:?}",time1,time2,time3); + 0 +}