use crate::architecture::riscv::communication_interface::RiscvError;
use crate::architecture::riscv::{Dmcontrol, Riscv32};
use crate::semihosting::{SemihostingCommand, UnknownCommandDetails};
use super::communication_interface::RiscvCommunicationInterface;
use std::fmt::Debug;
use std::sync::Arc;
use std::time::Duration;
pub trait RiscvDebugSequence: Send + Sync + Debug {
fn on_connect(&self, _interface: &mut RiscvCommunicationInterface) -> Result<(), crate::Error> {
Ok(())
}
fn on_halt(&self, _interface: &mut RiscvCommunicationInterface) -> Result<(), crate::Error> {
Ok(())
}
fn reset_catch_set(
&self,
interface: &mut RiscvCommunicationInterface,
) -> Result<(), RiscvError> {
if !interface.supports_reset_halt_req()? {
return Err(RiscvError::ResetHaltRequestNotSupported);
}
let mut dmcontrol: Dmcontrol = interface.read_dm_register()?;
dmcontrol.set_dmactive(true);
dmcontrol.set_resethaltreq(true);
interface.write_dm_register(dmcontrol)?;
Ok(())
}
fn reset_catch_clear(
&self,
interface: &mut RiscvCommunicationInterface,
) -> Result<(), RiscvError> {
if !interface.supports_reset_halt_req()? {
return Err(RiscvError::ResetHaltRequestNotSupported);
}
let mut dmcontrol: Dmcontrol = interface.read_dm_register()?;
dmcontrol.set_dmactive(true);
dmcontrol.set_clrresethaltreq(true);
interface.write_dm_register(dmcontrol)?;
Ok(())
}
fn reset_system_and_halt(
&self,
interface: &mut RiscvCommunicationInterface,
timeout: Duration,
) -> Result<(), crate::Error> {
interface.reset_hart_and_halt(timeout)?;
Ok(())
}
fn on_unknown_semihosting_command(
&self,
_interface: &mut Riscv32,
details: UnknownCommandDetails,
) -> Result<Option<SemihostingCommand>, crate::Error> {
Ok(Some(SemihostingCommand::Unknown(details)))
}
}
#[derive(Debug)]
pub struct DefaultRiscvSequence(pub(crate) ());
impl DefaultRiscvSequence {
pub fn create() -> Arc<dyn RiscvDebugSequence> {
Arc::new(Self(()))
}
}
impl RiscvDebugSequence for DefaultRiscvSequence {}