Skip to content

Commit

Permalink
Merge pull request #15 from lhw2002426/rtc
Browse files Browse the repository at this point in the history
Rtc support
  • Loading branch information
coolyjg authored Oct 9, 2023
2 parents 2608519 + 42ad759 commit c55c30c
Show file tree
Hide file tree
Showing 23 changed files with 566 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions api/arceos_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ documentation = "https://rcore-os.github.io/arceos/arceos_api/index.html"
default = []

irq = ["axfeat/irq"]
rtc = ["axfeat/rtc"]
alloc = ["dep:axalloc", "axfeat/alloc"]
multitask = ["axtask/multitask", "axfeat/multitask"]
fs = ["dep:axfs", "axfeat/fs"]
Expand Down
17 changes: 17 additions & 0 deletions api/arceos_posix_api/src/imp/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ pub unsafe fn sys_clock_gettime(_clk: ctypes::clockid_t, ts: *mut ctypes::timesp
})
}

/// Get clock time since booting
pub unsafe fn sys_clock_settime(_clk: ctypes::clockid_t, ts: *mut ctypes::timespec) -> c_int {
syscall_body!(sys_clock_setttime, {
if ts.is_null() {
return Err(LinuxError::EFAULT);
}
let new_tv = Duration::from(*ts);
debug!(
"sys_clock_setttime: {}.{:09}s",
new_tv.as_secs(),
new_tv.as_nanos()
);
axhal::time::set_current_time(new_tv);
Ok(0)
})
}

/// Sleep some nanoseconds
///
/// TODO: should be woken by signals, and set errno
Expand Down
2 changes: 1 addition & 1 deletion api/arceos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub use imp::io::{sys_read, sys_write, sys_writev};
pub use imp::resources::{sys_getrlimit, sys_setrlimit};
pub use imp::sys::sys_sysinfo;
pub use imp::task::{sys_exit, sys_getpid, sys_sched_yield};
pub use imp::time::{sys_clock_gettime, sys_nanosleep};
pub use imp::time::{sys_clock_gettime, sys_clock_settime, sys_nanosleep};

#[cfg(feature = "fd")]
pub use imp::fd_ops::{sys_close, sys_dup, sys_dup2, sys_fcntl};
Expand Down
3 changes: 3 additions & 0 deletions api/axfeat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ fp_simd = ["axhal/fp_simd"]
# Interrupts
irq = ["axhal/irq", "axruntime/irq", "axtask?/irq"]

# Real time clock
rtc = ["axhal/rtc", "axruntime/rtc"]

# Memory
alloc = ["axalloc", "axruntime/alloc"]
alloc-tlsf = ["axalloc/tlsf"]
Expand Down
1 change: 1 addition & 0 deletions apps/c/systime/features.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rtc
39 changes: 39 additions & 0 deletions apps/c/systime/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <stdio.h>
#include <sys/time.h>

int main()
{
struct timeval tv;
if (gettimeofday(&tv, NULL) != 0 ) {
perror("gettimeofday");
return -1;
}

printf("now time: %ld : %ld\n", tv.tv_sec,tv.tv_usec);

usleep(3000000);

if (gettimeofday(&tv, NULL) != 0 ) {
perror("gettimeofday");
return -1;
}

printf("now time: %ld : %ld\n", tv.tv_sec,tv.tv_usec);

struct timeval new_time;
new_time.tv_sec = 1731110400;
new_time.tv_usec = 0;

if (settimeofday(&new_time, NULL) != 0 ) {
perror("settimeofday");
return -1;
}
if (gettimeofday(&tv, NULL) != 0 ) {
perror("gettimeofday");
return -1;
}

printf("now time: %ld : %ld\n", tv.tv_sec,tv.tv_usec);
return 0;

}
2 changes: 2 additions & 0 deletions modules/axhal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ alloc = []
fp_simd = []
paging = ["axalloc", "page_table"]
irq = []
rtc = []
tls = ["alloc"]
default = []

Expand All @@ -23,6 +24,7 @@ log = "0.4"
cfg-if = "1.0"
bitflags = "2.2"
static_assertions = "1.1.0"
embedded-hal = "0.2.7"
axlog = { path = "../axlog" }
axconfig = { path = "../axconfig" }
axalloc = { path = "../axalloc", optional = true }
Expand Down
3 changes: 3 additions & 0 deletions modules/axhal/src/platform/aarch64_common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ pub mod gic;

#[cfg(not(platform_family = "aarch64-bsta1000b"))]
pub mod pl011;

#[cfg(feature = "rtc")]
pub mod pl031;
74 changes: 74 additions & 0 deletions modules/axhal/src/platform/aarch64_common/pl031.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Rukos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

//! PL031 RTC.

static RTC_DR: u32 = 0x000; //Data Register
static RTC_MR: u32 = 0x004; //Match Register
static RTC_LR: u32 = 0x008; //Load Register
static RTC_CR: u32 = 0x00c; //Control Register
static RTC_IMSC: u32 = 0x010; //Interrupt Mask Set or Clear register

const PHYS_RTC: usize = axconfig::PHYS_VIRT_OFFSET + 0x09010000;

static PL031_RTC: Pl031rtc = Pl031rtc { address: PHYS_RTC };

pub fn init() {
info!("Initialize pl031 rtc...");
PL031_RTC.init();
debug!("{}", rtc_read_time());
}

struct Pl031rtc {
address: usize,
}

impl core::fmt::Display for Pl031rtc {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"RTC DR: {}\nRTC MR: {}\nRTC LR: {}\nRTC CR: {}\nRTC_IMSC: {}",
unsafe { self.read(RTC_DR) } as u64,
unsafe { self.read(RTC_MR) } as u64,
unsafe { self.read(RTC_LR) } as u64,
unsafe { self.read(RTC_CR) } as u64,
unsafe { self.read(RTC_IMSC) } as u64
)
}
}

impl Pl031rtc {
fn init(&self) {
unsafe {
if self.read(RTC_CR) != 1 {
self.write(RTC_CR, 1);
}
}
}

pub unsafe fn read(&self, reg: u32) -> u32 {
core::ptr::read_volatile((PHYS_RTC + reg as usize) as *const u32)
}

pub unsafe fn write(&self, reg: u32, value: u32) {
core::ptr::write_volatile((PHYS_RTC + reg as usize) as *mut u32, value);
}

pub fn time(&self) -> u64 {
unsafe { self.read(RTC_DR) as u64 }
}
}

pub fn rtc_read_time() -> u64 {
PL031_RTC.time()
}

pub fn rtc_write_time(seconds: u32) {
unsafe { PL031_RTC.write(RTC_LR, seconds) };
}
4 changes: 4 additions & 0 deletions modules/axhal/src/platform/aarch64_qemu_virt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub mod console {

pub mod time {
pub use crate::platform::aarch64_common::generic_timer::*;
#[cfg(feature = "rtc")]
pub use crate::platform::aarch64_common::pl031::*;
}

pub mod misc {
Expand Down Expand Up @@ -64,6 +66,8 @@ pub fn platform_init() {
#[cfg(feature = "irq")]
super::aarch64_common::gic::init_primary();
super::aarch64_common::generic_timer::init_percpu();
#[cfg(feature = "rtc")]
super::aarch64_common::pl031::init();
super::aarch64_common::pl011::init();
}

Expand Down
4 changes: 4 additions & 0 deletions modules/axhal/src/platform/aarch64_raspi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub mod console {

pub mod time {
pub use crate::platform::aarch64_common::generic_timer::*;
#[cfg(feature = "rtc")]
pub use crate::platform::aarch64_common::pl031::*;
}

pub mod misc {
Expand Down Expand Up @@ -66,6 +68,8 @@ pub fn platform_init() {
#[cfg(feature = "irq")]
super::aarch64_common::gic::init_primary();
super::aarch64_common::generic_timer::init_percpu();
#[cfg(feature = "rtc")]
super::aarch64_common::pl031::init();
super::aarch64_common::pl011::init();
}

Expand Down
2 changes: 2 additions & 0 deletions modules/axhal/src/platform/x86_pc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ mod uart16550;

pub mod mem;
pub mod misc;
#[cfg(feature = "rtc")]
pub mod rtc;
pub mod time;

#[cfg(feature = "smp")]
Expand Down
Loading

0 comments on commit c55c30c

Please sign in to comment.