forked from arceos-org/arceos
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a664211
commit 2702ffa
Showing
14 changed files
with
250 additions
and
31 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "ratio" | ||
version = "0.1.0" | ||
edition = "2021" | ||
authors = ["Yuekai Jia <[email protected]>"] | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#![cfg_attr(not(test), no_std)] | ||
#![feature(const_trait_impl)] | ||
|
||
use core::{cmp::PartialEq, fmt}; | ||
|
||
/// Convert `numerator / denominator` to `mult / (1 << shift)` to avoid `u128` division. | ||
pub struct Ratio { | ||
numerator: u32, | ||
denominator: u32, | ||
mult: u32, | ||
shift: u32, | ||
} | ||
|
||
impl Ratio { | ||
pub const fn zero() -> Self { | ||
Self { | ||
numerator: 0, | ||
denominator: 0, | ||
mult: 0, | ||
shift: 0, | ||
} | ||
} | ||
|
||
pub const fn new(numerator: u32, denominator: u32) -> Self { | ||
assert!(!(denominator == 0 && numerator != 0)); | ||
if numerator == 0 { | ||
return Self { | ||
numerator, | ||
denominator, | ||
mult: 0, | ||
shift: 0, | ||
}; | ||
} | ||
|
||
// numerator / denominator == (numerator * (1 << shift) / denominator) / (1 << shift) | ||
let mut shift = 32; | ||
let mut mult; | ||
loop { | ||
mult = (((numerator as u64) << shift) + denominator as u64 / 2) / denominator as u64; | ||
if mult <= u32::MAX as u64 || shift == 0 { | ||
break; | ||
} | ||
shift -= 1; | ||
} | ||
|
||
while mult % 2 == 0 && shift > 0 { | ||
mult /= 2; | ||
shift -= 1; | ||
} | ||
|
||
Self { | ||
numerator, | ||
denominator, | ||
mult: mult as u32, | ||
shift, | ||
} | ||
} | ||
|
||
pub const fn inverse(&self) -> Self { | ||
Self::new(self.denominator, self.numerator) | ||
} | ||
|
||
pub const fn mul_trunc(&self, value: u64) -> u64 { | ||
((value as u128 * self.mult as u128) >> self.shift) as u64 | ||
} | ||
|
||
pub const fn mul_round(&self, value: u64) -> u64 { | ||
((value as u128 * self.mult as u128 + (1 << self.shift >> 1)) >> self.shift) as u64 | ||
} | ||
} | ||
|
||
impl fmt::Debug for Ratio { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!( | ||
f, | ||
"Ratio({}/{} ~= {}/{})", | ||
self.numerator, | ||
self.denominator, | ||
self.mult, | ||
1u64 << self.shift | ||
) | ||
} | ||
} | ||
|
||
impl const PartialEq<Ratio> for Ratio { | ||
fn eq(&self, other: &Ratio) -> bool { | ||
self.mult == other.mult && self.shift == other.shift | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_ratio() { | ||
let a = Ratio::new(625_000, 1_000_000); | ||
let b = Ratio::new(1, u32::MAX); | ||
let c = Ratio::new(u32::MAX, u32::MAX); | ||
let d = Ratio::new(u32::MAX, 1); | ||
|
||
assert_eq!(a.mult, 5); | ||
assert_eq!(a.shift, 3); | ||
assert_eq!(a.mul_trunc(800), 500); | ||
|
||
assert_eq!(b.mult, 1); | ||
assert_eq!(b.shift, 32); | ||
assert_eq!(b.mul_trunc(u32::MAX as _), 0); | ||
assert_eq!(b.mul_round(u32::MAX as _), 1); | ||
|
||
assert_eq!(c.mult, 1); | ||
assert_eq!(c.shift, 0); | ||
assert_eq!(c.mul_trunc(u32::MAX as _), u32::MAX as _); | ||
|
||
println!("{:?}", a); | ||
println!("{:?}", b); | ||
println!("{:?}", c); | ||
println!("{:?}", d); | ||
} | ||
|
||
#[test] | ||
fn test_zero() { | ||
let z1 = Ratio::new(0, 100); | ||
let z2 = Ratio::zero(); | ||
let z3 = Ratio::new(0, 0); | ||
assert_eq!(z1.mul_trunc(233), 0); | ||
assert_eq!(z2.mul_trunc(0), 0); | ||
assert_eq!(z3.mul_round(456), 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ authors = ["Yuekai Jia <[email protected]>"] | |
[features] | ||
bus-mmio = ["driver_virtio?/bus-mmio"] | ||
bus-pci = ["driver_virtio?/bus-pci"] | ||
virtio = ["driver_virtio", "dep:axalloc", "dep:axhal"] | ||
virtio = ["driver_virtio", "dep:axalloc", "dep:axhal", "dep:axconfig"] | ||
|
||
# various types of drivers | ||
virtio-blk = ["virtio", "dep:driver_block", "driver_virtio/block"] | ||
|
@@ -29,3 +29,4 @@ driver_net = { path = "../../crates/driver_net", optional = true } | |
driver_virtio = { path = "../../crates/driver_virtio", optional = true } | ||
axalloc = { path = "../axalloc", optional = true } | ||
axhal = { path = "../axhal", optional = true } | ||
axconfig = { path = "../axconfig", optional = true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,10 @@ authors = ["Yuekai Jia <[email protected]>"] | |
|
||
[features] | ||
platform-qemu-virt-riscv = ["axconfig/platform-qemu-virt-riscv"] | ||
platform-qemu-virt-aarch64 = ["axconfig/platform-qemu-virt-aarch64", "dep:page_table_entry"] | ||
platform-qemu-virt-aarch64 = [ | ||
"axconfig/platform-qemu-virt-aarch64", | ||
"dep:page_table_entry", "dep:lazy_init", "dep:ratio", | ||
] | ||
paging = ["axalloc", "page_table"] | ||
default = [] | ||
|
||
|
@@ -21,6 +24,8 @@ static_assertions = "1.1.0" | |
axconfig = { path = "../axconfig" } | ||
axalloc = { path = "../axalloc", optional = true } | ||
axerror = { path = "../axerror" } | ||
ratio = { path = "../../crates/ratio", optional = true } | ||
lazy_init = { path = "../../crates/lazy_init", optional = true } | ||
page_table = { path = "../../crates/page_table", optional = true } | ||
page_table_entry = { path = "../../crates/page_table_entry", optional = true } | ||
memory_addr = { path = "../../crates/memory_addr" } | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
modules/axhal/src/platform/qemu_virt_aarch64/generic_timer.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use aarch64_cpu::registers::{CNTFRQ_EL0, CNTPCT_EL0}; | ||
use lazy_init::LazyInit; | ||
use ratio::Ratio; | ||
use tock_registers::interfaces::Readable; | ||
|
||
use crate::time::NANOS_PER_SEC; | ||
|
||
#[allow(unused)] | ||
const PHYS_TIMER_IRQ_NUM: usize = 30; | ||
|
||
static CNTPCT_TO_NANOS_RATIO: LazyInit<Ratio> = LazyInit::new(); | ||
|
||
pub fn current_ticks() -> u64 { | ||
CNTPCT_EL0.get() | ||
} | ||
|
||
#[inline(never)] | ||
pub fn ticks_to_nanos(ticks: u64) -> u64 { | ||
CNTPCT_TO_NANOS_RATIO.mul_trunc(ticks) | ||
} | ||
|
||
pub(crate) fn init() { | ||
CNTPCT_TO_NANOS_RATIO.init_by(Ratio::new(NANOS_PER_SEC as u32, CNTFRQ_EL0.get() as u32)); | ||
} |
Oops, something went wrong.