Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,20 @@ jobs:
if: matrix.arch == 'x86_64' || matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package httpd --features ci,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.qemu_flags }} --devices rtl8139
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp,hermit/gem-net qemu ${{ matrix.qemu_flags }} --devices cadence-gem
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package httpd --no-default-features --features ci,hermit/dhcpv4,hermit/tcp,hermit/gem-net,hermit/riscv-legacy-timer qemu ${{ matrix.qemu_flags }} --devices cadence-gem
if: matrix.arch == 'riscv64'
- run: cargo clean
working-directory: .
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package testudp --features hermit/udp,hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.qemu_flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package testudp --features hermit/udp,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.qemu_flags }} --devices rtl8139
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package testudp --no-default-features --features hermit/udp,hermit/dhcpv4,hermit/gem-net qemu ${{ matrix.qemu_flags }} --devices cadence-gem
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package testudp --no-default-features --features hermit/udp,hermit/dhcpv4,hermit/gem-net,hermit/riscv-legacy-timer qemu ${{ matrix.qemu_flags }} --devices cadence-gem
if: matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package miotcp --features hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.qemu_flags }} --devices virtio-net-pci
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package miotcp --features hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.qemu_flags }} --devices rtl8139
if: matrix.arch != 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package miotcp --no-default-features --features hermit/dhcpv4,hermit/tcp,hermit/gem-net qemu ${{ matrix.qemu_flags }} --devices cadence-gem
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package miotcp --no-default-features --features hermit/dhcpv4,hermit/tcp,hermit/gem-net,hermit/riscv-legacy-timer qemu ${{ matrix.qemu_flags }} --devices cadence-gem
if: matrix.arch == 'riscv64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package poll --features hermit/dhcpv4,hermit/virtio-net qemu ${{ matrix.qemu_flags }} --devices virtio-net-pci
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package poll --features hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.qemu_flags }} --devices rtl8139
Expand Down
9 changes: 3 additions & 6 deletions Cargo.lock

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

12 changes: 11 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ semihosting = ["dep:semihosting"]
## _application processor_s (AP) from the _boot-strap processor_ (BSP).
smp = ["acpi"]

## Enables timer management via SBI.
##
## This allows hardware without Sstc support to manage timers.
## E.g. SiFive Freedom U740
## If this flag is not set, timers will be managed using the Sstc extension.
##
## This flag is only evaluated for riscv64.
riscv-legacy-timer = []

#! ### Network Features

## Enables TCP support.
Expand Down Expand Up @@ -418,7 +427,8 @@ semihosting = { version = "0.1", optional = true }
[target.'cfg(target_arch = "riscv64")'.dependencies]
fdt = { version = "0.1", features = ["pretty-printing"] }
memory_addresses = { version = "0.4", default-features = false, features = ["riscv64"] }
riscv = "0.16"
#TODO: use upstream version once changes merged and published
riscv = { version = "0.16", git = "https://github.com/rust-embedded/riscv", branch = "master" }
sbi-rt = "0.0.4"
semihosting = { version = "0.1", optional = true }
tock-registers = { version = "0.10", optional = true }
Expand Down
13 changes: 13 additions & 0 deletions src/arch/riscv64/kernel/devicetree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ enum Model {
Unknown,
}

pub fn detect_timebase_frequency() -> u64 {
let fdt = env::start_info().fdt().unwrap();

let cpus_node = fdt
.find_node("/cpus")
.expect("cpus node missing or invalid");
cpus_node
.property("timebase-frequency")
.expect("timebase-frequency node not found in /cpus")
.as_usize()
.unwrap() as u64
}

/// Inits variables based on the device tree
/// This function should only be called once
pub fn init() {
Expand Down
18 changes: 2 additions & 16 deletions src/arch/riscv64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ use riscv::register::sstatus;

pub(crate) use self::processor::{set_oneshot_timer, wakeup_core};
use crate::arch::kernel::core_local::core_id;
pub use crate::arch::kernel::devicetree::init_drivers;
pub use crate::arch::kernel::devicetree::{detect_timebase_frequency, init_drivers};
use crate::arch::kernel::processor::lsb;
use crate::config::KERNEL_STACK_SIZE;
use crate::env::{self, FdtStartInfo};
use crate::env;
use crate::init_cell::InitCell;
use crate::mm::{FrameAlloc, PageRangeAllocator};

Expand Down Expand Up @@ -59,20 +59,6 @@ pub fn get_hart_mask() -> u64 {
HART_MASK.load(Ordering::Relaxed)
}

pub fn get_timebase_freq() -> u64 {
let fdt = env::start_info().fdt().unwrap();

// Get timebase-freq
let cpus_node = fdt
.find_node("/cpus")
.expect("cpus node missing or invalid");
cpus_node
.property("timebase-frequency")
.expect("timebase-frequency node not found in /cpus")
.as_usize()
.unwrap() as u64
}

pub fn get_current_boot_id() -> u32 {
CURRENT_BOOT_ID.load(Ordering::Relaxed)
}
Expand Down
28 changes: 23 additions & 5 deletions src/arch/riscv64/kernel/processor.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use core::arch::asm;
use core::num::NonZeroU64;

use hermit_sync::{Lazy, without_interrupts};
#[cfg(not(feature = "riscv-legacy-timer"))]
use riscv::register::stimecmp;
use riscv::register::{sie, sstatus, time};

use crate::arch::kernel::{HARTS_AVAILABLE, get_timebase_freq};
use crate::arch::kernel::{HARTS_AVAILABLE, detect_timebase_frequency};
use crate::scheduler::CoreId;

static TIMEBASE_FREQUENCY: Lazy<u64> = Lazy::new(detect_timebase_frequency);

/// Current FPU state. Saved at context switch when changed
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -254,7 +259,7 @@ pub fn get_timer_ticks() -> u64 {

/// Returns the timer frequency in MHz
pub fn get_frequency() -> u16 {
(get_timebase_freq() / 1_000_000).try_into().unwrap()
(*TIMEBASE_FREQUENCY / 1_000_000).try_into().unwrap()
}

#[inline]
Expand All @@ -270,23 +275,36 @@ pub fn supports_2mib_pages() -> bool {
true
}

pub fn set_oneshot_timer(wakeup_time: Option<u64>) {
#[inline]
pub fn __set_oneshot_timer(wakeup_time: Option<u64>) {
let Some(wt) = wakeup_time else {
// Disable the Timer (and clear a pending interrupt)
debug!("Stopping Timer");
#[cfg(not(feature = "riscv-legacy-timer"))]
unsafe {
stimecmp::write(usize::MAX);
}
#[cfg(feature = "riscv-legacy-timer")]
sbi_rt::set_timer(u64::MAX);
return;
};

debug!("Starting Timer: {:x}", get_timestamp());
unsafe {
sie::set_stimer();
}
let next_time = wt * u64::from(get_frequency());

#[cfg(not(feature = "riscv-legacy-timer"))]
unsafe {
stimecmp::write(next_time.try_into().unwrap());
}
#[cfg(feature = "riscv-legacy-timer")]
sbi_rt::set_timer(next_time);
}

pub fn set_oneshot_timer(wakeup_time: Option<u64>) {
without_interrupts(|| __set_oneshot_timer(wakeup_time));
}

pub fn wakeup_core(core_to_wakeup: CoreId) {
let hart_id = HARTS_AVAILABLE.finalize()[core_to_wakeup as usize];
debug!("Wakeup core: {core_to_wakeup} , hart_id: {hart_id}");
Expand Down
Loading