Add ARM generic timer
This commit is contained in:
parent
e85116c5aa
commit
e023ef11c2
@ -4,15 +4,19 @@
|
||||
fn __aa64_bsp_main() {
|
||||
debugln!("Test");
|
||||
use crate::arch::machine;
|
||||
use crate::dev::{Device, serial::SerialDevice};
|
||||
use crate::dev::{Device, timer::TimestampSource, serial::SerialDevice};
|
||||
|
||||
unsafe {
|
||||
machine::console().lock().enable().unwrap();
|
||||
machine::local_timer().lock().enable().unwrap();
|
||||
}
|
||||
|
||||
let base = machine::local_timer().lock().timestamp().unwrap();
|
||||
|
||||
loop {
|
||||
let count = machine::local_timer().lock().timestamp().unwrap();
|
||||
let ch = machine::console().lock().recv(true).unwrap();
|
||||
debugln!("{:#04x} = '{}'!", ch, ch as char);
|
||||
debugln!("[{:?}] {:#04x} = '{}'!", count - base, ch, ch as char);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
//! QEMU virt machine
|
||||
|
||||
use crate::dev::serial::{pl011::Pl011, SerialDevice};
|
||||
use crate::dev::timer::TimestampSource;
|
||||
use crate::arch::aarch64::timer::GenericTimer;
|
||||
use crate::sync::Spin;
|
||||
|
||||
const UART0_BASE: usize = 0x09000000;
|
||||
@ -11,4 +13,11 @@ pub fn console() -> &'static Spin<impl SerialDevice> {
|
||||
&UART0
|
||||
}
|
||||
|
||||
/// Returns the timer used as CPU-local periodic IRQ source
|
||||
#[inline]
|
||||
pub fn local_timer() -> &'static Spin<impl TimestampSource> {
|
||||
&LOCAL_TIMER
|
||||
}
|
||||
|
||||
static UART0: Spin<Pl011> = Spin::new(unsafe { Pl011::new(UART0_BASE) });
|
||||
static LOCAL_TIMER: Spin<GenericTimer> = Spin::new(GenericTimer {});
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! aarch64 architecture implementation
|
||||
|
||||
pub mod boot;
|
||||
pub mod timer;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "mach_qemu")] {
|
||||
|
29
kernel/src/arch/aarch64/timer.rs
Normal file
29
kernel/src/arch/aarch64/timer.rs
Normal file
@ -0,0 +1,29 @@
|
||||
//! ARM generic timer implementation
|
||||
|
||||
use crate::dev::{timer::TimestampSource, Device};
|
||||
use core::time::Duration;
|
||||
use cortex_a::registers::{CNTFRQ_EL0, CNTPCT_EL0, CNTP_CTL_EL0};
|
||||
use error::Errno;
|
||||
use tock_registers::interfaces::{Readable, Writeable};
|
||||
|
||||
/// Generic timer struct
|
||||
pub struct GenericTimer;
|
||||
|
||||
impl Device for GenericTimer {
|
||||
fn name() -> &'static str {
|
||||
"ARM Generic Timer"
|
||||
}
|
||||
|
||||
unsafe fn enable(&mut self) -> Result<(), Errno> {
|
||||
CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::SET);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl TimestampSource for GenericTimer {
|
||||
fn timestamp(&mut self) -> Result<Duration, Errno> {
|
||||
let cnt = CNTPCT_EL0.get() * 1_000_000_000;
|
||||
let frq = CNTFRQ_EL0.get();
|
||||
Ok(Duration::from_nanos(cnt / frq))
|
||||
}
|
||||
}
|
@ -2,7 +2,9 @@
|
||||
|
||||
use error::Errno;
|
||||
|
||||
// Device classes
|
||||
pub mod serial;
|
||||
pub mod timer;
|
||||
|
||||
/// Generic device trait
|
||||
pub trait Device {
|
||||
|
11
kernel/src/dev/timer.rs
Normal file
11
kernel/src/dev/timer.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//! Timer interface
|
||||
|
||||
use crate::dev::Device;
|
||||
use core::time::Duration;
|
||||
use error::Errno;
|
||||
|
||||
/// Interface for generic timestamp source
|
||||
pub trait TimestampSource: Device {
|
||||
/// Reads current timestamp as a [Duration] from system start time
|
||||
fn timestamp(&mut self) -> Result<Duration, Errno>;
|
||||
}
|
@ -1,13 +1,16 @@
|
||||
//! osdve5 crate (lol)
|
||||
#![feature(
|
||||
global_asm,
|
||||
const_for,
|
||||
const_mut_refs,
|
||||
const_raw_ptr_deref,
|
||||
const_fn_fn_ptr_basics
|
||||
const_fn_fn_ptr_basics,
|
||||
panic_info_message
|
||||
)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
@ -17,10 +20,15 @@ pub mod debug;
|
||||
pub mod arch;
|
||||
pub mod dev;
|
||||
pub mod mem;
|
||||
#[deny(missing_docs)]
|
||||
pub mod sync;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(_pi: &core::panic::PanicInfo) -> ! {
|
||||
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
|
||||
if let Some(msg) = pi.message() {
|
||||
debugln!("Panic occurred: {:?}", msg);
|
||||
} else {
|
||||
debugln!("Panic occurred");
|
||||
}
|
||||
debugln!("Panic location: {:?}", pi.location());
|
||||
loop {}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Memory management and functions module
|
||||
|
||||
/// Implements the rust language dependency for memcpy(3p) function.
|
||||
/// See memcpy(3p).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
@ -14,3 +14,23 @@ pub unsafe extern "C" fn memcpy(dst: *mut u8, src: *mut u8, mut len: usize) -> *
|
||||
}
|
||||
dst
|
||||
}
|
||||
|
||||
/// See memcmp(3p).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: performs reads from arbitrary memory locations, performs no
|
||||
/// pointer validation.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memcmp(a: *mut u8, b: *mut u8, mut len: usize) -> isize {
|
||||
while len != 0 {
|
||||
len -= 1;
|
||||
if *a.add(len) < *b.add(len) {
|
||||
return -1;
|
||||
}
|
||||
if *a.add(len) > *b.add(len) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user