Skip to content

Commit

Permalink
Merge branch 'main' into xsun/flash-partition-support
Browse files Browse the repository at this point in the history
  • Loading branch information
helloxiling committed Dec 18, 2024
2 parents a514f59 + c7160df commit c0cbf07
Show file tree
Hide file tree
Showing 14 changed files with 735 additions and 42 deletions.
6 changes: 3 additions & 3 deletions emulator/cpu/src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ pub struct CoverageBitmaps<'a> {
pub iccm: &'a bit_vec::BitVec,
}

const ICCM_SIZE: usize = 128 * 1024;
const ICCM_ORG: usize = 0x40000000;
const ICCM_SIZE: usize = RAM_SIZE as usize;
const ICCM_ORG: usize = RAM_OFFSET as usize;
const ICCM_UPPER: usize = ICCM_ORG + ICCM_SIZE - 1;

const ROM_SIZE: usize = 48 * 1024;
const ROM_SIZE: usize = emulator_types::ROM_SIZE as usize;
const ROM_ORG: usize = 0x00000000;
const ROM_UPPER: usize = ROM_ORG + ROM_SIZE - 1;

Expand Down
52 changes: 43 additions & 9 deletions emulator/cpu/src/csr_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,16 @@ impl Csr {
pub const PMPCFG_START: RvAddr = 0x3A0;

/// PMP configuration register range end, inclusive
pub const PMPCFG_END: RvAddr = 0x3A3;
pub const PMPCFG_END: RvAddr = 0x3AF;

/// PMP address register range start, inclusive
pub const PMPADDR_START: RvAddr = 0x3B0;

/// PMP address register range end, inclusive
pub const PMPADDR_END: RvAddr = 0x3C0;
pub const PMPADDR_END: RvAddr = 0x3EF;

/// Number of PMP address/cfg registers
pub const PMPCOUNT: usize = 16;
pub const PMPCOUNT: usize = 64;

/// Create a new Configurations and Status register
///
Expand Down Expand Up @@ -766,8 +766,9 @@ impl CsrFile {
return Ok(false);
}

let addr = addr as u64;
let pmpaddr = self.any_read(RvPrivMode::M, Csr::PMPADDR_START + index as RvAddr)?;
let pmpaddr_shift = pmpaddr << 2;
let pmpaddr_shift = (pmpaddr as u64) << 2;
let addr_top;
let addr_bottom;

Expand All @@ -777,7 +778,9 @@ impl CsrFile {
// otherwise it's the previous one
addr_top = pmpaddr_shift;
addr_bottom = if index > 0 {
self.any_read(RvPrivMode::M, Csr::PMPADDR_START + (index - 1) as RvAddr)? << 2
(self.any_read(RvPrivMode::M, Csr::PMPADDR_START + (index - 1) as RvAddr)?
as u64)
<< 2
} else {
0
};
Expand All @@ -788,13 +791,12 @@ impl CsrFile {
addr_bottom = pmpaddr_shift;
}
RvPmpAddrMode::Napot => {
// Range from 8..32
addr_top = pmpaddr_shift + (1 << (pmpaddr.trailing_ones() + 3));
addr_bottom = pmpaddr_shift;
let (bot, top) = decode_napot_pmpaddr(pmpaddr);
addr_bottom = bot;
addr_top = top;
}
_ => unreachable!(),
}

Ok(addr >= addr_bottom && addr < addr_top)
}

Expand Down Expand Up @@ -977,12 +979,44 @@ impl CsrFile {
}
}

// Returns the base address (inclusive) and end address (exclusive) of a NAPOT PMP address
fn decode_napot_pmpaddr(addr: u32) -> (u64, u64) {
let bits = addr.trailing_ones();
let addr = addr as u64;
let base = (addr & !((1 << bits) - 1)) << 2;
(base, base + (1 << (bits + 3)))
}

#[cfg(test)]
mod tests {

use super::*;
use std::rc::Rc;

#[test]
fn test_decode_napot_pmpaddr() {
assert_eq!((0x0000_0000, 0x0000_0008), decode_napot_pmpaddr(0x00000000));
assert_eq!((0x0000_0000, 0x0000_0010), decode_napot_pmpaddr(0x00000001));
assert_eq!((0x0040_0000, 0x0040_8000), decode_napot_pmpaddr(0x00100fff));
assert_eq!((0x1000_0000, 0x2000_0000), decode_napot_pmpaddr(0x05ffffff));
assert_eq!(
(0x0000_0000, 0x1_0000_0000),
decode_napot_pmpaddr(0x1fffffff)
);
assert_eq!(
(0x0000_0000, 0x2_0000_0000),
decode_napot_pmpaddr(0x3fffffff)
);
assert_eq!(
(0x0000_0000, 0x4_0000_0000),
decode_napot_pmpaddr(0x7fffffff)
);
assert_eq!(
(0x0000_0000, 0x8_0000_0000),
decode_napot_pmpaddr(0xffffffff)
);
}

#[test]
fn test_u_mode_read_m_mode_csr() {
let clock = Rc::new(Clock::new());
Expand Down
12 changes: 6 additions & 6 deletions emulator/periph/src/root_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ pub struct CaliptraRootBus {
#[peripheral(offset = 0x0000_0000, len = 0xc000)]
pub rom: Rom,

#[peripheral(offset = 0x2000_0000, len = 0x40)]
pub spi: SpiHost,

#[peripheral(offset = 0x2000_1000, len = 0x100)]
#[peripheral(offset = 0x1000_1000, len = 0x100)]
pub uart: Uart,

#[peripheral(offset = 0x2000_f000, len = 0x4)]
#[peripheral(offset = 0x1000_2000, len = 0x4)]
pub ctrl: EmuCtrl,

#[peripheral(offset = 0x3000_4000, len = 0x1000)]
#[peripheral(offset = 0x2000_0000, len = 0x40)]
pub spi: SpiHost,

#[peripheral(offset = 0x2000_1000, len = 0x1000)]
pub otp: Otp,

#[peripheral(offset = 0x4000_0000, len = 0x60000)]
Expand Down
6 changes: 3 additions & 3 deletions rom/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn panic_fmt(_pi: &PanicInfo) -> ! {

// Cause the emulator to exit
unsafe {
write_volatile(0x200f0000 as *mut u32, 0);
write_volatile(0x1000_2000 as *mut u32, 0);
}
unreachable!()
}
Expand All @@ -33,10 +33,10 @@ fn write_byte(b: u8) {
// # Safety
// Accesses memory-mapped registers.
unsafe {
write_volatile(0x2000_1041 as *mut u8, b);
write_volatile(0x1000_1041 as *mut u8, b);
}
}

fn _read_byte() -> u8 {
unsafe { read_volatile(0x2000_1041 as *mut u8) }
unsafe { read_volatile(0x1000_1041 as *mut u8) }
}
2 changes: 1 addition & 1 deletion romtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub(crate) fn print_to_console(buf: &str) {
for b in buf.bytes() {
// Print to this address for emulator output
unsafe {
core::ptr::write_volatile(0x2000_1041 as *mut u8, b);
core::ptr::write_volatile(0x1000_1041 as *mut u8, b);
}
}
}
6 changes: 6 additions & 0 deletions runtime/kernel_layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,13 @@ SECTIONS
_eattributes = LOADADDR(.attributes) + SIZEOF(.attributes);*/
_sattributes = 0;
_eattributes = 0;
_srom = ORIGIN(rom);
_erom = ORIGIN(rom) + LENGTH(rom);
_sprog = ORIGIN(prog);
_eprog = ORIGIN(prog) + LENGTH(prog);
_ssram = ORIGIN(ram);
_esram = ORIGIN(ram) + LENGTH(ram);


/* This.. this is a dirty, not-fully-understood, hack. In some way, linking is
* a multi-pass process. i.e., if you were to ASSERT(0, "how many links")
Expand Down
50 changes: 49 additions & 1 deletion runtime/src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
use crate::chip::VeeRDefaultPeripherals;
use crate::chip::TIMERS;
use crate::components as runtime_components;
use crate::pmp::CodeRegion;
use crate::pmp::DataRegion;
use crate::pmp::KernelTextRegion;
use crate::pmp::MMIORegion;
use crate::pmp::VeeRProtectionMMLEPMP;
use crate::timers::InternalTimers;

use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
Expand All @@ -18,6 +23,7 @@ use kernel::scheduler::cooperative::CooperativeSched;
use kernel::utilities::registers::interfaces::ReadWriteable;
use kernel::{create_capability, debug, static_init};
use rv32i::csr;
use rv32i::pmp::{NAPOTRegionSpec, TORRegionSpec};

// These symbols are defined in the linker script.
extern "C" {
Expand All @@ -29,6 +35,18 @@ extern "C" {
static mut _sappmem: u8;
/// End of the RAM region for app memory.
static _eappmem: u8;
/// The start of the kernel text (Included only for kernel PMP)
static _stext: u8;
/// The end of the kernel text (Included only for kernel PMP)
static _etext: u8;
/// The start of the kernel / app / storage flash (Included only for kernel PMP)
static _srom: u8;
/// The end of the kernel / app / storage flash (Included only for kernel PMP)
static _eprog: u8;
/// The start of the kernel / app RAM (Included only for kernel PMP)
static _ssram: u8;
/// The end of the kernel / app RAM (Included only for kernel PMP)
static _esram: u8;

pub(crate) static _pic_vector_table: u8;
}
Expand Down Expand Up @@ -165,6 +183,36 @@ pub unsafe fn main() {
// only machine mode
rv32i::configure_trap_handler();

// Set up memory protection immediately after setting the trap handler, to
// ensure that much of the board initialization routine runs with ePMP
// protection.

// fixed regions to allow user mode direct access to emulator control and UART
let user_mmio = [MMIORegion(
NAPOTRegionSpec::new(0x1000_0000 as *const u8, 0x1000_0000).unwrap(),
)];
// additional MMIO for machine only peripherals
let machine_mmio = [
MMIORegion(NAPOTRegionSpec::new(0x2000_0000 as *const u8, 0x2000_0000).unwrap()),
MMIORegion(NAPOTRegionSpec::new(0x6000_0000 as *const u8, 0x1_0000).unwrap()),
];

let epmp = VeeRProtectionMMLEPMP::new(
CodeRegion(
TORRegionSpec::new(core::ptr::addr_of!(_srom), core::ptr::addr_of!(_eprog)).unwrap(),
),
DataRegion(
TORRegionSpec::new(core::ptr::addr_of!(_ssram), core::ptr::addr_of!(_esram)).unwrap(),
),
// use the MMIO for the PIC
&user_mmio[..],
&machine_mmio[..],
KernelTextRegion(
TORRegionSpec::new(core::ptr::addr_of!(_stext), core::ptr::addr_of!(_etext)).unwrap(),
),
)
.unwrap();

// initialize capabilities
let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability);
Expand Down Expand Up @@ -209,7 +257,7 @@ pub unsafe fn main() {
VeeRDefaultPeripherals::new(&*mux_alarm)
);

let chip = static_init!(VeeRChip, crate::chip::VeeR::new(peripherals));
let chip = static_init!(VeeRChip, crate::chip::VeeR::new(peripherals, epmp));
chip.init();
CHIP = Some(chip);

Expand Down
12 changes: 6 additions & 6 deletions runtime/src/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#![allow(static_mut_refs)]

use crate::io::SemihostUart;
use crate::pmp::{VeeRPMP, VeeRProtectionMMLEPMP};
use crate::timers::{InternalTimers, TimerInterrupts};
use capsules_core::virtualizers::virtual_alarm::MuxAlarm;
use core::fmt::Write;
Expand All @@ -17,7 +18,6 @@ use kernel::platform::chip::{Chip, InterruptService};
use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
use kernel::utilities::StaticRef;
use rv32i::csr::{mcause, mie::mie, CSR};
use rv32i::pmp::{simple::SimplePMP, PMPUserMPU};
use rv32i::syscall::SysCall;

use crate::pic::Pic;
Expand All @@ -39,7 +39,7 @@ pub struct VeeR<'a, I: InterruptService + 'a> {
pic: &'a Pic,
timers: &'static InternalTimers<'static>,
pub peripherals: &'a I,
pmp: PMPUserMPU<4, SimplePMP<8>>,
pmp: VeeRPMP,
}

pub struct VeeRDefaultPeripherals<'a> {
Expand Down Expand Up @@ -90,14 +90,14 @@ impl<'a> InterruptService for VeeRDefaultPeripherals<'a> {

impl<'a, I: InterruptService + 'a> VeeR<'a, I> {
/// # Safety
/// Accesses memory-mapped registers.
pub unsafe fn new(pic_interrupt_service: &'a I) -> Self {
/// Accesses memory<-mapped registers.
pub unsafe fn new(pic_interrupt_service: &'a I, epmp: VeeRProtectionMMLEPMP) -> Self {
Self {
userspace_kernel_boundary: SysCall::new(),
pic: &*addr_of!(PIC),
timers: &*addr_of!(TIMERS),
peripherals: pic_interrupt_service,
pmp: PMPUserMPU::new(SimplePMP::new().unwrap()),
pmp: rv32i::pmp::PMPUserMPU::new(epmp),
}
}

Expand Down Expand Up @@ -131,7 +131,7 @@ impl<'a, I: InterruptService + 'a> VeeR<'a, I> {
}

impl<'a, I: InterruptService + 'a> kernel::platform::chip::Chip for VeeR<'a, I> {
type MPU = PMPUserMPU<4, SimplePMP<8>>;
type MPU = VeeRPMP;
type UserspaceKernelBoundary = SysCall;

fn mpu(&self) -> &Self::MPU {
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn exit_emulator(exit_code: u32) -> ! {
// Safety: This is a safe memory address to write to for exiting the emulator.
unsafe {
// By writing to this address we can exit the emulator.
write_volatile(0x2000_f000 as *mut u32, exit_code);
write_volatile(0x1000_2000 as *mut u32, exit_code);
}
unreachable!()
}
Expand All @@ -70,15 +70,15 @@ impl IoWrite for Writer {
for b in buf {
// Print to this address for emulator output
unsafe {
write_volatile(0x2000_1041 as *mut u8, *b);
write_volatile(0x1000_1041 as *mut u8, *b);
}
}
buf.len()
}
}

fn read_byte() -> u8 {
unsafe { read_volatile(0x2000_1041 as *mut u8) }
unsafe { read_volatile(0x1000_1041 as *mut u8) }
}

pub struct SemihostUart<'a> {
Expand Down
2 changes: 2 additions & 0 deletions runtime/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub mod io;
#[cfg(target_arch = "riscv32")]
mod pic;
#[cfg(target_arch = "riscv32")]
mod pmp;
#[cfg(target_arch = "riscv32")]
#[allow(unused_imports)]
mod tests;
#[cfg(target_arch = "riscv32")]
Expand Down
Loading

0 comments on commit c0cbf07

Please sign in to comment.