add logic to catch suspend/resume and opcode errors

also fix a bug where the engine was not being powered off
on release.

Things to note:

- in case of an opcode error, the system will enter an infinite
loop complaining about the error. Maybe i should promote that to
a panic -- it's a thing that should be fixed and should just never
happen
- in case of a suspend/resume during an operation, this is
detected by the loaded microcode length not matching what we
had written. This is a heuristic, but relies on the assumption
that the microcode length would change when the engine is put
through a clean reboot (i.e., it is unlikely that it matches
what we had previously written).
This commit is contained in:
bunnie 2024-03-28 10:18:27 +08:00
parent c1b910a779
commit c0d9b40d9d

View file

@ -39,7 +39,7 @@ pub fn free_engine() {
log::debug!("free engine");
if let Some(base) = unsafe { ENGINE_BASE.take() } {
let mut engine = utralib::CSR::new(base.as_mut_ptr() as *mut u32);
engine.rmwf(utra::engine::POWER_ON, 1);
engine.rmwf(utra::engine::POWER_ON, 0);
xous::unmap_memory(base).unwrap();
}
if let Some(mem) = unsafe { ENGINE_MEM.take() } {
@ -47,6 +47,26 @@ pub fn free_engine() {
}
}
/// Only safe to call this after ensure_engine() has been called.
pub fn was_engine_error(job_len: usize) -> bool {
let mut engine = utralib::CSR::new(unsafe { ENGINE_BASE.unwrap() }.as_mut_ptr() as *mut u32);
let reason = engine.r(utra::engine::EV_PENDING);
if reason & engine.ms(utra::engine::EV_PENDING_ILLEGAL_OPCODE, 1) != 0 {
log::warn!("Illegal opcode encountered in engine25519");
return true;
}
// if the job length isn't what we had set it to, conclude that the
// microcode engine went through a suspend/resume cycle
if engine.rf(utra::engine::MPLEN_MPLEN) != job_len as u32 {
log::warn!("Suspend during engine25519 hw acceleration");
return true;
}
engine.wo(utra::engine::EV_PENDING, reason);
false
}
/// It is safe to call this multiple times.
pub fn ensure_engine() -> Result<(), xous::Error> {
if unsafe { ENGINE_BASE.is_none() } {
@ -73,6 +93,7 @@ pub fn ensure_engine() -> Result<(), xous::Error> {
}
let mut engine = utralib::CSR::new(unsafe { ENGINE_BASE.unwrap() }.as_mut_ptr() as *mut u32);
engine.rmwf(utra::engine::POWER_ON, 1);
engine.wo(utra::engine::EV_PENDING, 0xFFFF_FFFF); // clear all pending bits
Ok(())
}