Skip to content

Commit d597fab

Browse files
Integrate 64-bit RISC-V support
Co-authored-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de> Signed-off-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de>
1 parent 7e77799 commit d597fab

File tree

10 files changed

+93
-6
lines changed

10 files changed

+93
-6
lines changed

src/drivers/net/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,14 @@ pub(crate) extern "x86-interrupt" fn network_irqhandler(_stack_frame: ExceptionS
7878

7979
core_scheduler().reschedule();
8080
}
81+
82+
#[cfg(target_arch = "riscv64")]
83+
pub fn network_irqhandler() {
84+
debug!("Receive network interrupt");
85+
86+
// PLIC end of interrupt
87+
crate::arch::kernel::interrupts::external_eoi();
88+
let _ = _irqhandler();
89+
90+
core_scheduler().reschedule();
91+
}

src/drivers/net/virtio_net.rs

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use zerocopy::AsBytes;
1818

1919
use self::constants::{FeatureSet, Features, NetHdrFlag, NetHdrGSO, Status, MAX_NUM_VQ};
2020
use self::error::VirtioNetError;
21+
#[cfg(not(target_arch = "riscv64"))]
2122
use crate::arch::kernel::core_local::increment_irq_counter;
2223
use crate::config::VIRTIO_MAX_QUEUE_SIZE;
2324
#[cfg(not(feature = "pci"))]
@@ -648,6 +649,7 @@ impl NetworkDriver for VirtioNetDriver {
648649
}
649650

650651
fn handle_interrupt(&mut self) -> bool {
652+
#[cfg(not(target_arch = "riscv64"))]
651653
increment_irq_counter(32 + self.irq);
652654

653655
let result = if self.isr_stat.is_interrupt() {

src/drivers/virtio/transport/mmio.rs

+1
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ pub(crate) fn init_device(
394394
info!("Virtio network driver initialized.");
395395
// Install interrupt handler
396396
irq_install_handler(irq_no, network_irqhandler);
397+
#[cfg(not(target_arch = "riscv64"))]
397398
add_irq_name(irq_no, "virtio_net");
398399

399400
Ok(VirtioDriver::Network(virt_net_drv))

src/executor/network.rs

+7
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ fn start_endpoint() -> u16 {
7878
(value % (u16::MAX as u64)).try_into().unwrap()
7979
}
8080

81+
#[cfg(target_arch = "riscv64")]
82+
fn start_endpoint() -> u16 {
83+
(riscv::register::time::read64() % (u16::MAX as u64))
84+
.try_into()
85+
.unwrap()
86+
}
87+
8188
#[inline]
8289
pub(crate) fn now() -> Instant {
8390
let microseconds = arch::processor::get_timer_ticks() + arch::get_boot_time();

src/fd/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ fn uhyve_send<T>(port: u16, data: &mut T) {
163163
}
164164
}
165165

166+
/// forward a request to the hypervisor uhyve
167+
#[inline]
168+
#[cfg(target_arch = "riscv64")]
169+
fn uhyve_send<T>(port: u16, data: &mut T) {
170+
todo!()
171+
}
172+
166173
fn open_flags_to_perm(flags: i32, mode: u32) -> FilePerms {
167174
let mut perms = FilePerms {
168175
raw: flags as u32,

src/lib.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99
#![allow(clippy::missing_safety_doc)]
1010
#![cfg_attr(target_arch = "aarch64", allow(incomplete_features))]
1111
#![cfg_attr(target_arch = "x86_64", feature(abi_x86_interrupt))]
12+
#![cfg_attr(target_arch = "riscv64", feature(offset_of))]
1213
#![feature(allocator_api)]
1314
#![feature(asm_const)]
1415
#![feature(core_intrinsics)]
1516
#![feature(linked_list_cursors)]
1617
#![feature(maybe_uninit_slice)]
1718
#![feature(naked_functions)]
1819
#![feature(noop_waker)]
19-
#![cfg_attr(target_arch = "aarch64", feature(specialization))]
20+
#![cfg_attr(
21+
any(target_arch = "aarch64", target_arch = "riscv64"),
22+
feature(specialization)
23+
)]
2024
#![feature(strict_provenance)]
2125
#![cfg_attr(target_os = "none", no_std)]
2226
#![cfg_attr(target_os = "none", feature(custom_test_frameworks))]
@@ -264,6 +268,10 @@ extern "C" fn initd(_arg: usize) {
264268
arch::init_drivers();
265269
crate::executor::init();
266270

271+
// Initialize MMIO Drivers if on riscv64
272+
#[cfg(target_arch = "riscv64")]
273+
riscv64::kernel::init_drivers();
274+
267275
syscalls::init();
268276
fd::init();
269277
#[cfg(feature = "fs")]
@@ -320,6 +328,8 @@ fn boot_processor_main() -> ! {
320328
env::get_tls_memsz()
321329
);
322330
arch::boot_processor_init();
331+
332+
#[cfg(not(target_arch = "riscv64"))]
323333
scheduler::add_current_core();
324334

325335
if !env::is_uhyve() {
@@ -355,6 +365,7 @@ fn boot_processor_main() -> ! {
355365
#[cfg(all(target_os = "none", feature = "smp"))]
356366
fn application_processor_main() -> ! {
357367
arch::application_processor_init();
368+
#[cfg(not(target_arch = "riscv64"))]
358369
scheduler::add_current_core();
359370

360371
info!("Entering idle loop for application processor");

src/macros.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ macro_rules! kernel_function {
105105

106106
// TODO: Properly switch kernel stack with newlib
107107
// https://github.com/hermitcore/hermit-kernel/issues/471
108-
#[cfg(all(target_arch = "x86_64", feature = "newlib"))]
108+
#[cfg(any(
109+
target_arch = "riscv64",
110+
all(target_arch = "x86_64", feature = "newlib")
111+
))]
109112
macro_rules! kernel_function {
110113
($f:ident($($x:tt)*)) => {{
111114
$f($($x)*)

src/scheduler/mod.rs

+41-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ use core::sync::atomic::{AtomicU32, Ordering};
88

99
use crossbeam_utils::Backoff;
1010
use hermit_sync::{without_interrupts, *};
11+
#[cfg(target_arch = "riscv64")]
12+
use riscv::register::sstatus;
1113

1214
use crate::arch;
1315
use crate::arch::core_local::*;
1416
use crate::arch::interrupts;
17+
#[cfg(target_arch = "riscv64")]
18+
use crate::arch::switch::switch_to_task;
1519
#[cfg(target_arch = "x86_64")]
1620
use crate::arch::switch::{switch_to_fpu_owner, switch_to_task};
1721
use crate::kernel::scheduler::TaskStacks;
@@ -289,7 +293,7 @@ impl PerCoreScheduler {
289293

290294
/// Returns `true` if a reschedule is required
291295
#[inline]
292-
#[cfg(all(target_arch = "x86_64", feature = "smp"))]
296+
#[cfg(all(any(target_arch = "x86_64", target_arch = "riscv64"), feature = "smp"))]
293297
pub fn is_scheduling(&self) -> bool {
294298
self.current_task.borrow().prio < self.ready_queue.get_highest_priority()
295299
}
@@ -422,6 +426,18 @@ impl PerCoreScheduler {
422426
})
423427
}
424428

429+
#[cfg(target_arch = "riscv64")]
430+
pub fn set_current_kernel_stack(&self) {
431+
let current_task_borrowed = self.current_task.borrow();
432+
433+
set_kernel_stack(
434+
(current_task_borrowed.stacks.get_kernel_stack()
435+
+ current_task_borrowed.stacks.get_kernel_stack_size()
436+
- TaskStacks::MARKER_SIZE)
437+
.as_u64(),
438+
);
439+
}
440+
425441
/// Save the FPU context for the current FPU owner and restore it for the current task,
426442
/// which wants to use the FPU now.
427443
#[cfg(target_arch = "x86_64")]
@@ -447,7 +463,7 @@ impl PerCoreScheduler {
447463
}
448464
}
449465

450-
#[cfg(all(target_arch = "x86_64", feature = "smp"))]
466+
#[cfg(all(any(target_arch = "x86_64", target_arch = "riscv64"), feature = "smp"))]
451467
pub fn check_input(&mut self) {
452468
let mut input_locked = self.input.lock();
453469

@@ -488,6 +504,12 @@ impl PerCoreScheduler {
488504
})
489505
}
490506

507+
#[cfg(target_arch = "riscv64")]
508+
pub fn reschedule(&mut self) {
509+
// TODO: Align with others
510+
without_interrupts(|| self.scheduler());
511+
}
512+
491513
/// Trigger an interrupt to reschedule the system
492514
#[cfg(target_arch = "aarch64")]
493515
pub fn reschedule(&self) {
@@ -630,10 +652,26 @@ impl PerCoreScheduler {
630652
unsafe { *last_stack_pointer },
631653
new_stack_pointer
632654
);
633-
self.current_task = task;
655+
#[cfg(not(target_arch = "riscv64"))]
656+
{
657+
self.current_task = task;
658+
}
634659

635660
// Finally return the context of the new task.
661+
#[cfg(not(target_arch = "riscv64"))]
636662
return Some(last_stack_pointer);
663+
664+
#[cfg(target_arch = "riscv64")]
665+
{
666+
if sstatus::read().fs() == sstatus::FS::Dirty {
667+
self.current_task.borrow_mut().last_fpu_state.save();
668+
}
669+
task.borrow().last_fpu_state.restore();
670+
self.current_task = task;
671+
unsafe {
672+
switch_to_task(last_stack_pointer, new_stack_pointer.as_usize());
673+
}
674+
}
637675
}
638676
}
639677

src/scheduler/task.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl PriorityTaskQueue {
323323
}
324324

325325
/// Returns the highest priority of all available task
326-
#[cfg(all(target_arch = "x86_64", feature = "smp"))]
326+
#[cfg(all(any(target_arch = "x86_64", target_arch = "riscv64"), feature = "smp"))]
327327
pub fn get_highest_priority(&self) -> Priority {
328328
if let Some(i) = msb(self.prio_bitmap) {
329329
Priority::from(i.try_into().unwrap())

src/syscalls/interfaces/uhyve.rs

+7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ pub(crate) fn uhyve_send<T>(port: u16, data: &mut T) {
5656
}
5757
}
5858

59+
/// forward a request to the hypervisor uhyve
60+
#[inline]
61+
#[cfg(target_arch = "riscv64")]
62+
fn uhyve_send<T>(port: u16, data: &mut T) {
63+
todo!()
64+
}
65+
5966
const MAX_ARGC_ENVC: usize = 128;
6067

6168
#[repr(C, packed)]

0 commit comments

Comments
 (0)