Skip to content

Commit

Permalink
Fix rv32i compile errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Samir-Rashid committed Sep 26, 2024
1 parent 41c39e6 commit 669b038
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 75 deletions.
18 changes: 9 additions & 9 deletions arch/cortex-m/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ use core::fmt::Write;
#[cfg(all(target_arch = "arm", target_os = "none"))]
use core::arch::global_asm;

#[flux::ignore]
#[flux_rs::ignore]
pub mod dcb;
#[flux::ignore]
#[flux_rs::ignore]
pub mod dwt;
pub mod mpu;
#[flux::ignore]
#[flux_rs::ignore]
pub mod nvic;
#[flux::ignore]
#[flux_rs::ignore]
pub mod scb;
#[flux::ignore]
#[flux_rs::ignore]
pub mod support;
#[flux::ignore]
#[flux_rs::ignore]
pub mod syscall;
#[flux::ignore]
#[flux_rs::ignore]
pub mod systick;

// These constants are defined in the linker script.
Expand Down Expand Up @@ -120,7 +120,7 @@ pub trait CortexMVariant {
/// Format and display architecture-specific state useful for debugging.
///
/// This is generally used after a `panic!()` to aid debugging.
#[flux::ignore]
#[flux_rs::ignore]
unsafe fn print_cortexm_state(writer: &mut dyn Write);
}

Expand Down Expand Up @@ -207,7 +207,7 @@ global_asm!(
etext = sym _etext,
);

#[flux::ignore]
#[flux_rs::ignore]
pub unsafe fn print_cortexm_state(writer: &mut dyn Write) {
let _ccr = syscall::SCB_REGISTERS[0];
let cfsr = syscall::SCB_REGISTERS[1];
Expand Down
3 changes: 2 additions & 1 deletion arch/rv32i/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ enabled = true

[dependencies]
kernel = { path = "../../kernel" }
flux_support = { path = "../../flux_support" }
tock-registers = { path = "../../libraries/tock-register-interface" }
riscv-csr = { path = "../../libraries/riscv-csr" }
riscv = { path = "../riscv" }

flux-rs = { git = "https://github.com/flux-rs/flux" }

[lints]
workspace = true
10 changes: 6 additions & 4 deletions arch/rv32i/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

//! Support for the 32-bit RISC-V architecture.
#![feature(proc_macro_hygiene)]
#![crate_name = "rv32i"]
#![crate_type = "rlib"]
#![no_std]
use flux_rs::*;

use core::fmt::Write;

Expand All @@ -18,9 +20,9 @@ use kernel::utilities::registers::interfaces::{Readable, Writeable};
pub mod clic;
pub mod machine_timer;
pub mod pmp;
#[flux::ignore]
#[flux_rs::ignore]
pub mod support;
#[flux::ignore]
#[flux_rs::ignore]
pub mod syscall;

// Re-export the shared CSR library so that dependent crates do not have to have
Expand Down Expand Up @@ -429,7 +431,7 @@ pub unsafe fn semihost_command(_command: usize, _arg0: usize, _arg1: usize) -> u
}

/// Print a readable string for an mcause reason.
#[flux::ignore]
#[flux_rs::ignore]
pub unsafe fn print_mcause(mcval: csr::mcause::Trap, writer: &mut dyn Write) {
match mcval {
csr::mcause::Trap::Interrupt(interrupt) => match interrupt {
Expand Down Expand Up @@ -516,7 +518,7 @@ pub unsafe fn print_mcause(mcval: csr::mcause::Trap, writer: &mut dyn Write) {

/// Prints out RISCV machine state, including basic system registers
/// (mcause, mstatus, mtvec, mepc, mtval, interrupt status).
#[flux::ignore]
#[flux_rs::ignore]
pub unsafe fn print_riscv_state(writer: &mut dyn Write) {
let mcval: csr::mcause::Trap = core::convert::From::from(csr::CSR.mcause.extract());
let _ = writer.write_fmt(format_args!("\r\n---| RISC-V Machine State |---\r\n"));
Expand Down
45 changes: 23 additions & 22 deletions arch/rv32i/src/pmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use core::num::NonZeroUsize;
use core::ops::Range;
use core::{cmp, fmt};

use crate::csr;
use flux_support::*;
use kernel::platform::mpu;
use kernel::utilities::cells::OptionalCell;
use kernel::utilities::registers::{register_bitfields, LocalRegisterCopy};

use crate::csr;

register_bitfields![u8,
/// Generic `pmpcfg` octet.
///
Expand Down Expand Up @@ -569,7 +569,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
{
type MpuConfig = PMPUserMPUConfig<MAX_REGIONS>;

fn enable_app_mpu(&self) {
fn enable_app_mpu(&mut self) {
// TODO: This operation may fail when the PMP is not exclusively used
// for userspace. Instead of panicing, we should handle this case more
// gracefully and return an error in the `MPU` trait. Process
Expand All @@ -579,7 +579,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
self.pmp.enable_user_pmp().unwrap()
}

fn disable_app_mpu(&self) {
fn disable_app_mpu(&mut self) {
self.pmp.disable_user_pmp()
}

Expand Down Expand Up @@ -617,7 +617,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla

fn allocate_region(
&self,
unallocated_memory_start: *const u8,
unallocated_memory_start: FluxPtr,
unallocated_memory_size: usize,
min_region_size: usize,
permissions: mpu::Permissions,
Expand All @@ -635,7 +635,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
// provided start address and size, transform them to meet the
// constraints, and then check that we're still within the bounds of the
// provided values:
let mut start = unallocated_memory_start as usize;
let mut start = usize::from(unallocated_memory_start);
let mut size = min_region_size;

// Region start always has to align to 4 bytes. Round up to a 4 byte
Expand All @@ -659,7 +659,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
// allocation constraints, namely ensure that
//
// start + size <= unallocated_memory_start + unallocated_memory_size
if start + size > (unallocated_memory_start as usize) + unallocated_memory_size {
if start + size > (usize::from(unallocated_memory_start)) + unallocated_memory_size {
// We're overflowing the provided memory region, can't make
// allocation. Normally, we'd abort here.
//
Expand All @@ -686,7 +686,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla

if writeable
|| (start + size
> (unallocated_memory_start as usize) + unallocated_memory_size + 3)
> (usize::from(unallocated_memory_start)) + unallocated_memory_size + 3)
{
return None;
}
Expand All @@ -708,7 +708,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
);
config.is_dirty.set(true);

Some(mpu::Region::new(start as *const u8, size))
Some(mpu::Region::new(flux_support::FluxPtr::from(start), size))
}

fn remove_memory_region(
Expand All @@ -723,8 +723,8 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
.find(|(_i, r)| {
// `start as usize + size` in lieu of a safe pointer offset method
r.0 != TORUserPMPCFG::OFF
&& r.1 == region.start_address()
&& r.2 == (region.start_address() as usize + region.size()) as *const u8
&& r.1 == u8::from(region.start_address()) as *const u8
&& r.2 == (usize::from(region.start_address()) + region.size()) as *const u8
})
.map(|(i, _)| i)
.ok_or(())?;
Expand All @@ -737,14 +737,14 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla

fn allocate_app_memory_region(
&self,
unallocated_memory_start: *const u8,
unallocated_memory_start: FluxPtr,
unallocated_memory_size: usize,
min_memory_size: usize,
initial_app_memory_size: usize,
initial_kernel_memory_size: usize,
permissions: mpu::Permissions,
config: &mut Self::MpuConfig,
) -> Option<(*const u8, usize)> {
) -> Option<(FluxPtr, usize)> {
// An app memory region can only be allocated once per `MpuConfig`.
// If we already have one, abort:
if config.app_memory_region.is_some() {
Expand All @@ -764,7 +764,7 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
// protected by the PMP). For this, start with the provided start
// address and size, transform them to meet the constraints, and then
// check that we're still within the bounds of the provided values:
let mut start = unallocated_memory_start as usize;
let mut start = usize::from(unallocated_memory_start);
let mut pmp_region_size = initial_app_memory_size;

// Region start always has to align to 4 bytes. Round up to a 4 byte
Expand Down Expand Up @@ -802,7 +802,8 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
// , which ensures the PMP constraints didn't push us over the bounds of
// the provided memory region, and we can fit the entire allocation as
// requested by the kernel:
if start + memory_block_size > (unallocated_memory_start as usize) + unallocated_memory_size
if start + memory_block_size
> (usize::from(unallocated_memory_start)) + unallocated_memory_size
{
// Overflowing the provided memory region, can't make allocation:
return None;
Expand All @@ -828,20 +829,20 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
config.is_dirty.set(true);
config.app_memory_region.replace(region_num);

Some((start as *const u8, memory_block_size))
Some((flux_support::FluxPtr::from(start), memory_block_size))
}

fn update_app_memory_region(
&self,
app_memory_break: *const u8,
kernel_memory_break: *const u8,
app_memory_break: FluxPtr,
kernel_memory_break: FluxPtr,
permissions: mpu::Permissions,
config: &mut Self::MpuConfig,
) -> Result<(), ()> {
let region_num = config.app_memory_region.get().ok_or(())?;

let mut app_memory_break = app_memory_break as usize;
let kernel_memory_break = kernel_memory_break as usize;
let mut app_memory_break = app_memory_break as FluxPtr;
let kernel_memory_break = kernel_memory_break as FluxPtr;

// Ensure that the requested app_memory_break complies with PMP
// alignment constraints, namely that the region's end address is 4 byte
Expand All @@ -858,13 +859,13 @@ impl<const MAX_REGIONS: usize, P: TORUserPMP<MAX_REGIONS> + 'static> kernel::pla
// If we're not out of memory, update the region configuration
// accordingly:
config.regions[region_num].0 = permissions.into();
config.regions[region_num].2 = app_memory_break as *const u8;
config.regions[region_num].2 = u8::from(app_memory_break) as *const u8;
config.is_dirty.set(true);

Ok(())
}

fn configure_mpu(&self, config: &Self::MpuConfig) {
fn configure_mpu(&mut self, config: &Self::MpuConfig) {
if !self.last_configured_for.contains(&config.id) || config.is_dirty.get() {
self.pmp.configure_pmp(&config.regions).unwrap();
config.is_dirty.set(false);
Expand Down
4 changes: 3 additions & 1 deletion arch/rv32i/src/support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
//! Core low-level operations.
use crate::csr::{mstatus::mstatus, CSR};
use flux_rs::*;
use flux_support::*;

#[cfg(all(target_arch = "riscv32", target_os = "none"))]
#[inline(always)]
Expand All @@ -24,7 +26,7 @@ pub unsafe fn wfi() {
asm!("wfi", options(nomem, nostack));
}

#[flux::trusted]
#[flux_rs::trusted]
pub unsafe fn atomic<F, R>(f: F) -> R
where
F: FnOnce() -> R,
Expand Down
29 changes: 15 additions & 14 deletions arch/rv32i/src/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use core::mem::size_of;
use core::ops::Range;

use crate::csr::mcause;
use flux_rs::*;
use flux_support::*;
use kernel::errorcode::ErrorCode;
use kernel::syscall::ContextSwitchReason;

/// This holds all of the state that the kernel must keep for the process when
/// the process is not executing.
#[derive(Default)]
Expand Down Expand Up @@ -128,8 +129,8 @@ impl kernel::syscall::UserspaceKernelBoundary for SysCall {

unsafe fn initialize_process(
&self,
accessible_memory_start: *const u8,
_app_brk: *const u8,
accessible_memory_start: FluxPtr,
_app_brk: FluxPtr,
state: &mut Self::StoredState,
) -> Result<(), ()> {
// Need to clear the stored state when initializing.
Expand All @@ -141,16 +142,16 @@ impl kernel::syscall::UserspaceKernelBoundary for SysCall {
// pointer in the sp register.
//
// We do not pre-allocate any stack for RV32I processes.
state.regs[R_SP] = accessible_memory_start as u32;
state.regs[R_SP] = u32::from(accessible_memory_start);

// We do not use memory for UKB, so just return ok.
Ok(())
}

unsafe fn set_syscall_return_value(
&self,
_accessible_memory_start: *const u8,
_app_brk: *const u8,
_accessible_memory_start: FluxPtr,
_app_brk: FluxPtr,
state: &mut Self::StoredState,
return_value: kernel::syscall::SyscallReturn,
) -> Result<(), ()> {
Expand Down Expand Up @@ -185,8 +186,8 @@ impl kernel::syscall::UserspaceKernelBoundary for SysCall {

unsafe fn set_process_function(
&self,
_accessible_memory_start: *const u8,
_app_brk: *const u8,
_accessible_memory_start: FluxPtr,
_app_brk: FluxPtr,
state: &mut Riscv32iStoredState,
callback: kernel::process::FunctionCall,
) -> Result<(), ()> {
Expand Down Expand Up @@ -215,10 +216,10 @@ impl kernel::syscall::UserspaceKernelBoundary for SysCall {
#[cfg(not(all(target_arch = "riscv32", target_os = "none")))]
unsafe fn switch_to_process(
&self,
_accessible_memory_start: *const u8,
_app_brk: *const u8,
_accessible_memory_start: FluxPtr,
_app_brk: FluxPtr,
_state: &mut Riscv32iStoredState,
) -> (ContextSwitchReason, Option<*const u8>) {
) -> (ContextSwitchReason, Option<FluxPtr>) {
// Convince lint that 'mcause' and 'R_A4' are used during test build
let _cause = mcause::Trap::from(_state.mcause as usize);
let _arg4 = _state.regs[R_A4];
Expand Down Expand Up @@ -651,11 +652,11 @@ impl kernel::syscall::UserspaceKernelBoundary for SysCall {
let new_stack_pointer = state.regs[R_SP];
(ret, Some(new_stack_pointer as *const u8))
}
#[flux::ignore]
#[flux_rs::ignore]
unsafe fn print_context(
&self,
_accessible_memory_start: *const u8,
_app_brk: *const u8,
_accessible_memory_start: FluxPtr,
_app_brk: FluxPtr,
state: &Riscv32iStoredState,
writer: &mut dyn Write,
) {
Expand Down
Loading

0 comments on commit 669b038

Please sign in to comment.