Skip to content
This repository has been archived by the owner on Jul 22, 2022. It is now read-only.

Commit

Permalink
real time (usually UNIX time) clock support
Browse files Browse the repository at this point in the history
  • Loading branch information
u8cat committed Jun 27, 2022
1 parent bd99a9c commit 9cda632
Show file tree
Hide file tree
Showing 19 changed files with 150 additions and 34 deletions.
3 changes: 0 additions & 3 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -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"]
10 changes: 0 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ members = [
"lib/rkmbox",
"lib/rksched",
"lib/rkschedcoop",
"lib/rkschedpreem",
#"lib/rkschedpreem",
"lib/rksignal",
]
1 change: 1 addition & 0 deletions lib/rkboot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 0 additions & 3 deletions lib/rklist/tests/list.rs

This file was deleted.

4 changes: 3 additions & 1 deletion lib/rkplat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [] # 串口设备驱动
Expand All @@ -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]
Expand Down
7 changes: 7 additions & 0 deletions lib/rkplat/src/drivers/device_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions lib/rkplat/src/drivers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
64 changes: 64 additions & 0 deletions lib/rkplat/src/drivers/rtc/goldfish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: BSD-3-Clause
// goldfish.rs
// Authors: 张子辰 <[email protected]>
// 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))
}
}
15 changes: 15 additions & 0 deletions lib/rkplat/src/drivers/rtc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: BSD-3-Clause
// rtc/mod.rs
// Authors: 张子辰 <[email protected]>
// 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;
14 changes: 8 additions & 6 deletions lib/rkplat/src/drivers/uart/ns16550.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,24 +40,24 @@ 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;
const LSR_TX_VALID: u8 = 0x40;

pub struct Ns16550 {
addr: usize, //地址
//irq: usize, //中断号
irq: usize, //中断号
name: [u8;32],
name_size: usize,
}
Expand All @@ -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()
Expand Down
15 changes: 13 additions & 2 deletions lib/rkplat/src/riscv64/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions makefiles/test.mk.1
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# -*- makefile -*-
.PHONY: @testname@ @[email protected]
@testname@: @[email protected]
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

@[email protected]: $(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
Expand Down
2 changes: 1 addition & 1 deletion makefiles/test.mk.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

TEST_LIST='alloc_buddy0'
TEST_LIST=$(ls -C $3)

echo "# Generated by \`$0\` ." > $2

Expand Down
3 changes: 0 additions & 3 deletions test/alloc_buddy0/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -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"]
3 changes: 3 additions & 0 deletions test/rkplat_time0/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
target-dir = "../../build/test"
target = "riscv64gc-unknown-none-elf"
11 changes: 11 additions & 0 deletions test/rkplat_time0/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"]}
17 changes: 17 additions & 0 deletions test/rkplat_time0/src/main.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 9cda632

Please sign in to comment.