Skip to content

Commit

Permalink
Split ServerImpl versus FlashDriver, add FailServer
Browse files Browse the repository at this point in the history
  • Loading branch information
mkeeter committed Aug 20, 2024
1 parent b67466d commit e99cc3e
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 22 deletions.
167 changes: 151 additions & 16 deletions drv/cosmo-hf/src/hf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,35 @@ use idol_runtime::{
use ringbuf::ringbuf_entry_root as ringbuf_entry;
use userlib::{task_slot, RecvMessage};

use crate::{ServerImpl, Trace, PAGE_SIZE_BYTES, SECTOR_SIZE_BYTES};
use crate::{FlashDriver, Trace, PAGE_SIZE_BYTES, SECTOR_SIZE_BYTES};

task_slot!(HASH, hash_driver);

pub struct ServerImpl {
pub drv: FlashDriver,
}

impl idl::InOrderHostFlashImpl for ServerImpl {
fn read_id(
&mut self,
_: &RecvMessage,
) -> Result<[u8; 20], RequestError<HfError>> {
Ok(self.flash_read_id())
Ok(self.drv.flash_read_id())
}

fn capacity(
&mut self,
_: &RecvMessage,
) -> Result<usize, RequestError<HfError>> {
todo!()
Ok(0x8000000) // 1 GBit = 128 MiB
}

/// Reads the STATUS_1 register from the SPI flash
fn read_status(
&mut self,
_: &RecvMessage,
) -> Result<u8, RequestError<HfError>> {
Ok(self.read_flash_status())
Ok(self.drv.read_flash_status())
}

fn bulk_erase(
Expand All @@ -63,11 +67,12 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
{
return Err(HfError::Sector0IsReserved.into());
}
self.flash_page_program(
addr,
LeaseBufReader::<_, 32>::from(data.into_inner()),
)
.map_err(|()| RequestError::went_away())
self.drv
.flash_page_program(
addr,
LeaseBufReader::<_, 32>::from(data.into_inner()),
)
.map_err(|()| RequestError::went_away())
}

fn read(
Expand All @@ -76,11 +81,12 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
offset: u32,
dest: LenLimit<Leased<W, [u8]>, PAGE_SIZE_BYTES>,
) -> Result<(), RequestError<HfError>> {
self.flash_read(
offset,
LeaseBufWriter::<_, 32>::from(dest.into_inner()),
)
.map_err(|_| RequestError::went_away())
self.drv
.flash_read(
offset,
LeaseBufWriter::<_, 32>::from(dest.into_inner()),
)
.map_err(|_| RequestError::went_away())
}

fn sector_erase(
Expand All @@ -94,7 +100,7 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
{
return Err(HfError::Sector0IsReserved.into());
}
self.flash_sector_erase(addr);
self.drv.flash_sector_erase(addr);
Ok(())
}

Expand Down Expand Up @@ -160,7 +166,7 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
let mut buf = [0u8; PAGE_SIZE_BYTES];
for addr in (begin..end).step_by(buf.len()) {
let size = (end - addr).min(buf.len());
self.flash_read(addr as u32, &mut buf[..size]).unwrap();
self.drv.flash_read(addr as u32, &mut buf[..size]).unwrap();
if let Err(e) = hash_driver.update(size as u32, &buf[..size]) {
ringbuf_entry!(Trace::HashUpdateError(e));
return Err(HfError::HashError.into());
Expand Down Expand Up @@ -201,6 +207,135 @@ impl NotificationHandler for ServerImpl {
}
}

/// Dummy server which returns an error for every operation
pub struct FailServer {
pub err: HfError,
}

impl idl::InOrderHostFlashImpl for FailServer {
fn read_id(
&mut self,
_: &RecvMessage,
) -> Result<[u8; 20], RequestError<HfError>> {
Err(self.err.into())
}

fn capacity(
&mut self,
_: &RecvMessage,
) -> Result<usize, RequestError<HfError>> {
Err(self.err.into())
}

/// Reads the STATUS_1 register from the SPI flash
fn read_status(
&mut self,
_: &RecvMessage,
) -> Result<u8, RequestError<HfError>> {
Err(self.err.into())
}

fn bulk_erase(
&mut self,
_: &RecvMessage,
_protect: HfProtectMode,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}

fn page_program(
&mut self,
_: &RecvMessage,
_addr: u32,
_protect: HfProtectMode,
_data: LenLimit<Leased<R, [u8]>, PAGE_SIZE_BYTES>,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}

fn read(
&mut self,
_: &RecvMessage,
_offset: u32,
_dest: LenLimit<Leased<W, [u8]>, PAGE_SIZE_BYTES>,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}

fn sector_erase(
&mut self,
_: &RecvMessage,
_addr: u32,
_protect: HfProtectMode,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}

fn get_mux(
&mut self,
_: &RecvMessage,
) -> Result<HfMuxState, RequestError<HfError>> {
Err(self.err.into())
}

fn set_mux(
&mut self,
_: &RecvMessage,
_state: HfMuxState,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}

fn get_dev(
&mut self,
_: &RecvMessage,
) -> Result<HfDevSelect, RequestError<HfError>> {
Err(self.err.into())
}

fn set_dev(
&mut self,
_: &RecvMessage,
_state: HfDevSelect,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}

fn hash(
&mut self,
_: &RecvMessage,
_addr: u32,
_len: u32,
) -> Result<[u8; SHA256_SZ], RequestError<HfError>> {
Err(self.err.into())
}

fn get_persistent_data(
&mut self,
_: &RecvMessage,
) -> Result<HfPersistentData, RequestError<HfError>> {
Err(self.err.into())
}

fn write_persistent_data(
&mut self,
_: &RecvMessage,
_dev_select: HfDevSelect,
) -> Result<(), RequestError<HfError>> {
Err(self.err.into())
}
}

impl NotificationHandler for FailServer {
fn current_notification_mask(&self) -> u32 {
0
}

fn handle_notification(&mut self, _bits: u32) {
unreachable!()
}
}

pub mod idl {
use drv_hf_api::{
HfDevSelect, HfError, HfMuxState, HfPersistentData, HfProtectMode,
Expand Down
32 changes: 26 additions & 6 deletions drv/cosmo-hf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,29 @@ fn main() -> ! {
userlib::hl::sleep_for(1000);

let id = unsafe { reg::BASE.read_volatile() };
assert_eq!(id, 0x1de);
if id != 0x1de {
fail(drv_hf_api::HfError::FpgaNotConfigured);
}

let drv = FlashDriver;
drv.flash_set_quad_enable();

// Check the flash chip's ID against Table 7.3.1 in the datasheet
let id = drv.flash_read_id();
if &id[0..3] != [0xef, 0x40, 0x21] {
fail(drv_hf_api::HfError::BadChipId);
}

let mut server = hf::ServerImpl { drv };

// Fire up a server.
let mut server = ServerImpl;
server.flash_set_quad_enable();
let mut buffer = [0; hf::idl::INCOMING_SIZE];
loop {
idol_runtime::dispatch(&mut buffer, &mut server);
}
}

struct ServerImpl;
/// Driver for a QSPI NOR flash controlled by an FPGA over FMC
struct FlashDriver;

#[allow(unused)]
mod reg {
Expand Down Expand Up @@ -107,7 +118,7 @@ mod instr {
pub const QUAD_INPUT_PAGE_PROGRAM_4B: u32 = 0x34;
}

impl ServerImpl {
impl FlashDriver {
fn flash_read_id(&self) -> [u8; 20] {
self.clear_fifos();
self.write_reg(reg::DATA_BYTES, 20);
Expand Down Expand Up @@ -291,4 +302,13 @@ impl ServerImpl {
}
}

/// Failure function, running an Idol response loop that always returns an error
fn fail(err: drv_hf_api::HfError) {
let mut buffer = [0; hf::idl::INCOMING_SIZE];
let mut server = hf::FailServer { err };
loop {
idol_runtime::dispatch(&mut buffer, &mut server);
}
}

include!(concat!(env!("OUT_DIR"), "/notifications.rs"));
2 changes: 2 additions & 0 deletions drv/hf-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub enum HfError {
Sector0IsReserved,
NoPersistentData,
MonotonicCounterOverflow,
FpgaNotConfigured,
BadChipId,

#[idol(server_death)]
ServerRestarted,
Expand Down

0 comments on commit e99cc3e

Please sign in to comment.