Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SoC interface to talk to Caliptra #69

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ caliptra-api-types = { git = "https://github.com/chipsalliance/caliptra-sw.git",
caliptra-emu-bus = { git = "https://github.com/chipsalliance/caliptra-sw.git", rev = "2f6de531e321b7bb24b17b1bd02b43d2854aef3a" }
caliptra-emu-cpu = { git = "https://github.com/chipsalliance/caliptra-sw.git", rev = "2f6de531e321b7bb24b17b1bd02b43d2854aef3a" }
caliptra-emu-periph = { git = "https://github.com/chipsalliance/caliptra-sw.git", rev = "2f6de531e321b7bb24b17b1bd02b43d2854aef3a" }
caliptra-emu-types = { git = "https://github.com/chipsalliance/caliptra-sw.git", rev = "2f6de531e321b7bb24b17b1bd02b43d2854aef3a" }
caliptra-hw-model = { git = "https://github.com/chipsalliance/caliptra-sw.git", rev = "2f6de531e321b7bb24b17b1bd02b43d2854aef3a" }
caliptra-registers = { git = "https://github.com/chipsalliance/caliptra-sw.git", rev = "2f6de531e321b7bb24b17b1bd02b43d2854aef3a" }
clap_derive = "4.5.11"
Expand Down
39 changes: 26 additions & 13 deletions emulator/app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ use caliptra_emu_cpu::{Cpu as CaliptraMainCpu, StepAction as CaliptraMainStepAct
use caliptra_emu_periph::CaliptraRootBus as CaliptraMainRootBus;
use clap::{ArgAction, Parser};
use crossterm::event::{Event, KeyCode, KeyEvent};
use emulator_bus::{Clock, Timer};
use emulator_bus::{Bus, BusConverter, Clock, Timer};
use emulator_caliptra::{start_caliptra, StartCaliptraArgs};
use emulator_cpu::{Cpu, Pic, RvInstr, StepAction};
use emulator_periph::{CaliptraRootBus, CaliptraRootBusArgs, DummyFlashCtrl, I3c, I3cController};
use emulator_registers_generated::root_bus::AutoRootBus;
use emulator_registers_generated::soc::SocPeripheral;
use emulator_types::ROM_SIZE;
use gdb::gdb_state;
use gdb::gdb_target::GdbTarget;
Expand Down Expand Up @@ -268,7 +269,7 @@ fn run(cli: Emulator, capture_uart_output: bool) -> io::Result<Vec<u8>> {
exit(-1);
}

let caliptra_cpu = if cli.caliptra {
let (caliptra_cpu, soc_to_caliptra) = if cli.caliptra {
if cli.gdb_port.is_some() {
println!("Caliptra CPU cannot be started with GDB enabled");
exit(-1);
Expand All @@ -281,16 +282,15 @@ fn run(cli: Emulator, capture_uart_output: bool) -> io::Result<Vec<u8>> {
println!("Caliptra ROM File is required if Caliptra is enabled");
exit(-1);
}
Some(
start_caliptra(&StartCaliptraArgs {
rom: cli.caliptra_rom.unwrap(),
firmware: cli.caliptra_firmware,
..Default::default()
})
.expect("Failed to start Caliptra CPU"),
)
let (caliptra_cpu, soc_to_caliptra) = start_caliptra(&StartCaliptraArgs {
rom: cli.caliptra_rom.unwrap(),
firmware: cli.caliptra_firmware,
..Default::default()
})
.expect("Failed to start Caliptra CPU");
(Some(caliptra_cpu), Some(soc_to_caliptra))
} else {
None
(None, None)
};

let rom_buffer = read_binary(args_rom, 0)?;
Expand Down Expand Up @@ -397,15 +397,24 @@ fn run(cli: Emulator, capture_uart_output: bool) -> io::Result<Vec<u8>> {
)
.unwrap();

let mut delegates: Vec<Box<dyn Bus>> = vec![Box::new(root_bus)];
let soc_periph = if let Some(soc_to_caliptra) = soc_to_caliptra {
delegates.push(Box::new(BusConverter::new(Box::new(soc_to_caliptra))));
None
} else {
// pass an empty SoC interface that returns 0 for everything
Some(Box::new(FakeSoc {}) as Box<dyn SocPeripheral>)
};

let mut auto_root_bus = AutoRootBus::new(
Some(Box::new(root_bus)),
delegates,
Some(Box::new(i3c)),
Some(Box::new(flash_controller)),
None,
None,
None,
None,
None,
soc_periph,
None,
);

Expand Down Expand Up @@ -442,3 +451,7 @@ fn run(cli: Emulator, capture_uart_output: bool) -> io::Result<Vec<u8>> {

Ok(uart_output.map(|o| o.borrow().clone()).unwrap_or_default())
}

struct FakeSoc {}

impl SocPeripheral for FakeSoc {}
2 changes: 2 additions & 0 deletions emulator/bus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
caliptra-emu-bus.workspace = true
caliptra-emu-types.workspace = true
emulator-types.workspace = true
tock-registers.workspace = true
51 changes: 51 additions & 0 deletions emulator/bus/src/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ pub enum BusError {
StoreAccessFault,
}

impl From<caliptra_emu_bus::BusError> for BusError {
fn from(value: caliptra_emu_bus::BusError) -> Self {
match value {
caliptra_emu_bus::BusError::InstrAccessFault => BusError::InstrAccessFault,
caliptra_emu_bus::BusError::LoadAddrMisaligned => BusError::LoadAddrMisaligned,
caliptra_emu_bus::BusError::LoadAccessFault => BusError::LoadAccessFault,
caliptra_emu_bus::BusError::StoreAddrMisaligned => BusError::StoreAddrMisaligned,
caliptra_emu_bus::BusError::StoreAccessFault => BusError::StoreAccessFault,
}
}
}

/// Represents an abstract memory bus. Used to read and write from RAM and
/// peripheral addresses.
pub trait Bus {
Expand Down Expand Up @@ -78,3 +90,42 @@ pub trait Bus {
// By default, do nothing
}
}

pub struct BusConverter {
caliptra_bus: Box<dyn caliptra_emu_bus::Bus>,
}

impl BusConverter {
pub fn new(caliptra_bus: Box<dyn caliptra_emu_bus::Bus>) -> Self {
Self { caliptra_bus }
}
}

impl Bus for BusConverter {
fn read(&mut self, size: RvSize, addr: RvAddr) -> Result<RvData, BusError> {
self.caliptra_bus
.read((size as usize).into(), addr as caliptra_emu_types::RvAddr)
.map_err(|x| x.into())
}

fn write(&mut self, size: RvSize, addr: RvAddr, val: RvData) -> Result<(), BusError> {
self.caliptra_bus
.write(
(size as usize).into(),
addr as caliptra_emu_types::RvAddr,
val,
)
.map_err(|x| x.into())
}
fn poll(&mut self) {
self.caliptra_bus.poll();
}

fn warm_reset(&mut self) {
self.caliptra_bus.warm_reset();
}

fn update_reset(&mut self) {
self.caliptra_bus.update_reset();
}
}
2 changes: 1 addition & 1 deletion emulator/bus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod register_array;
mod rom;
pub mod testing;

pub use crate::bus::{Bus, BusError, Trap};
pub use crate::bus::{Bus, BusConverter, BusError, Trap};
pub use crate::clock::{ActionHandle, Clock, Timer, TimerAction};
pub use crate::dynamic_bus::DynamicBus;
pub use crate::ram::Ram;
Expand Down
9 changes: 6 additions & 3 deletions emulator/caliptra/src/caliptra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use caliptra_emu_cpu::Cpu;
use caliptra_emu_periph::soc_reg::DebugManufService;
use caliptra_emu_periph::{
CaliptraRootBus, CaliptraRootBusArgs, DownloadIdevidCsrCb, MailboxInternal, ReadyForFwCb,
TbServicesCb, UploadUpdateFwCb,
SocToCaliptraBus, TbServicesCb, UploadUpdateFwCb,
};
use caliptra_hw_model::BusMmio;
use std::fs::File;
Expand Down Expand Up @@ -64,7 +64,9 @@ pub struct StartCaliptraArgs {
}

/// Creates and returns an initialized a Caliptra emulator CPU.
pub fn start_caliptra(args: &StartCaliptraArgs) -> io::Result<Cpu<CaliptraRootBus>> {
pub fn start_caliptra(
args: &StartCaliptraArgs,
) -> io::Result<(Cpu<CaliptraRootBus>, SocToCaliptraBus)> {
let args_rom = &args.rom;
let args_current_fw = &args.firmware;
let args_update_fw = &args.update_firmware;
Expand Down Expand Up @@ -295,7 +297,8 @@ pub fn start_caliptra(args: &StartCaliptraArgs) -> io::Result<Cpu<CaliptraRootBu
.write(|_| (wdt_timeout >> 32) as u32);
}

Ok(Cpu::new(root_bus, clock))
let ext_soc_ifc = root_bus.soc_to_caliptra_bus();
Ok((Cpu::new(root_bus, clock), ext_soc_ifc))
}

fn change_dword_endianess(data: &mut [u8]) {
Expand Down
2 changes: 1 addition & 1 deletion emulator/periph/src/flash_ctrl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ mod test {
}

AutoRootBus::new(
None,
vec![],
None,
Some(flash_controller),
None,
Expand Down
2 changes: 1 addition & 1 deletion emulator/periph/src/i3c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ mod tests {
.tcri_send(DynamicI3cAddress::new(8).unwrap(), cmd)
.unwrap();

let mut bus = AutoRootBus::new(None, Some(i3c), None, None, None, None, None, None, None);
let mut bus = AutoRootBus::new(vec![], Some(i3c), None, None, None, None, None, None, None);
for _ in 0..10000 {
clock.increment_and_process_timer_actions(1, &mut bus);
}
Expand Down
1 change: 1 addition & 0 deletions registers/generated-emulator/src/entropy_src.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#[allow(unused_imports)]
use tock_registers::interfaces::{Readable, Writeable};
pub trait EntropySrcPeripheral {
fn set_dma_ram(&mut self, _ram: std::rc::Rc<std::cell::RefCell<emulator_bus::Ram>>) {}
fn poll(&mut self) {}
fn warm_reset(&mut self) {}
fn update_reset(&mut self) {}
Expand Down
1 change: 1 addition & 0 deletions registers/generated-emulator/src/otp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#[allow(unused_imports)]
use tock_registers::interfaces::{Readable, Writeable};
pub trait OtpPeripheral {
fn set_dma_ram(&mut self, _ram: std::rc::Rc<std::cell::RefCell<emulator_bus::Ram>>) {}
fn poll(&mut self) {}
fn warm_reset(&mut self) {}
fn update_reset(&mut self) {}
Expand Down
40 changes: 22 additions & 18 deletions registers/generated-emulator/src/root_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// generated by registers_generator with caliptra-ss repo at a621fff9df7015821eda6f7f73265fef74a01375
//
pub struct AutoRootBus {
delegate: Option<Box<dyn emulator_bus::Bus>>,
delegates: Vec<Box<dyn emulator_bus::Bus>>,
pub i3c_periph: Option<crate::i3c::I3cBus>,
pub flash_periph: Option<crate::flash::FlashBus>,
pub entropy_src_periph: Option<crate::entropy_src::EntropySrcBus>,
Expand All @@ -16,7 +16,7 @@ pub struct AutoRootBus {
impl AutoRootBus {
#[allow(clippy::too_many_arguments)]
pub fn new(
delegate: Option<Box<dyn emulator_bus::Bus>>,
delegates: Vec<Box<dyn emulator_bus::Bus>>,
i3c_periph: Option<Box<dyn crate::i3c::I3cPeripheral>>,
flash_periph: Option<Box<dyn crate::flash::FlashPeripheral>>,
entropy_src_periph: Option<Box<dyn crate::entropy_src::EntropySrcPeripheral>>,
Expand All @@ -27,7 +27,7 @@ impl AutoRootBus {
el2_pic_periph: Option<Box<dyn crate::el2_pic::El2PicPeripheral>>,
) -> Self {
Self {
delegate,
delegates,
i3c_periph: i3c_periph.map(|p| crate::i3c::I3cBus { periph: p }),
flash_periph: flash_periph.map(|p| crate::flash::FlashBus { periph: p }),
entropy_src_periph: entropy_src_periph
Expand Down Expand Up @@ -106,14 +106,16 @@ impl emulator_bus::Bus for AutoRootBus {
}
_ => Err(emulator_bus::BusError::LoadAccessFault),
};
if let Some(delegate) = self.delegate.as_mut() {
match result {
Err(emulator_bus::BusError::LoadAccessFault) => delegate.read(size, addr),
_ => result,
if !matches!(result, Err(emulator_bus::BusError::LoadAccessFault)) {
return result;
}
for delegate in self.delegates.iter_mut() {
let result = delegate.read(size, addr);
if !matches!(result, Err(emulator_bus::BusError::LoadAccessFault)) {
return result;
}
} else {
result
}
result
}
fn write(
&mut self,
Expand Down Expand Up @@ -180,14 +182,16 @@ impl emulator_bus::Bus for AutoRootBus {
}
_ => Err(emulator_bus::BusError::StoreAccessFault),
};
if let Some(delegate) = self.delegate.as_mut() {
match result {
Err(emulator_bus::BusError::StoreAccessFault) => delegate.write(size, addr, val),
_ => result,
if !matches!(result, Err(emulator_bus::BusError::StoreAccessFault)) {
return result;
}
for delegate in self.delegates.iter_mut() {
let result = delegate.write(size, addr, val);
if !matches!(result, Err(emulator_bus::BusError::StoreAccessFault)) {
return result;
}
} else {
result
}
result
}
fn poll(&mut self) {
if let Some(periph) = self.i3c_periph.as_mut() {
Expand All @@ -214,7 +218,7 @@ impl emulator_bus::Bus for AutoRootBus {
if let Some(periph) = self.el2_pic_periph.as_mut() {
periph.poll();
}
if let Some(delegate) = self.delegate.as_mut() {
for delegate in self.delegates.iter_mut() {
delegate.poll();
}
}
Expand Down Expand Up @@ -243,7 +247,7 @@ impl emulator_bus::Bus for AutoRootBus {
if let Some(periph) = self.el2_pic_periph.as_mut() {
periph.warm_reset();
}
if let Some(delegate) = self.delegate.as_mut() {
for delegate in self.delegates.iter_mut() {
delegate.warm_reset();
}
}
Expand Down Expand Up @@ -272,7 +276,7 @@ impl emulator_bus::Bus for AutoRootBus {
if let Some(periph) = self.el2_pic_periph.as_mut() {
periph.update_reset();
}
if let Some(delegate) = self.delegate.as_mut() {
for delegate in self.delegates.iter_mut() {
delegate.update_reset();
}
}
Expand Down
Loading