diff --git a/cmd/flash/src/lib.rs b/cmd/flash/src/lib.rs index c0dccf156..18aff6e29 100644 --- a/cmd/flash/src/lib.rs +++ b/cmd/flash/src/lib.rs @@ -77,7 +77,7 @@ pub struct FlashArgs { /// otherwise. fn validate( hubris: &HubrisArchive, - core: &mut dyn humility::core::Core, + core: &mut humility_probes_core::ProbeCore, subargs: &FlashArgs, ) -> Result<()> { let r = get_image_state( @@ -211,12 +211,11 @@ fn flashcmd(subargs: FlashArgs, context: &mut ExecutionContext) -> Result<()> { }; humility::msg!("attaching with chip set to {chip:x?}"); - let mut c = humility_probes_core::attach_for_flashing( + let core = &mut humility_probes_core::attach_for_flashing( probe, &chip, context.cli.speed, )?; - let core = c.as_mut(); validate(hubris, core, &subargs)?; if subargs.check { diff --git a/cmd/hydrate/src/lib.rs b/cmd/hydrate/src/lib.rs index 0d3f06e8f..df7273d4c 100644 --- a/cmd/hydrate/src/lib.rs +++ b/cmd/hydrate/src/lib.rs @@ -62,7 +62,6 @@ impl humility::core::Core for DryCore { unsupported!(run()); unsupported!(halt()); unsupported!(step()); - unsupported!(load(_path: &std::path::Path)); unsupported!(reset()); unsupported!(write_8(_addr: u32, _data: &[u8])); unsupported!(op_done()); diff --git a/cmd/map/src/lib.rs b/cmd/map/src/lib.rs index ea099587b..5c13be906 100644 --- a/cmd/map/src/lib.rs +++ b/cmd/map/src/lib.rs @@ -73,7 +73,7 @@ fn mapcmd(_args: MapArgs, context: &mut ExecutionContext) -> Result<()> { let hubris = &context.cli.archive()?; // Use an archive core to easily read from flash - let core = &mut *humility::core::attach_archive(hubris)?; + let core = &mut humility::core::attach_archive(hubris)?; let regions = hubris.regions(core)?; println!( diff --git a/cmd/readvar/src/lib.rs b/cmd/readvar/src/lib.rs index ab50ee145..b11df2366 100644 --- a/cmd/readvar/src/lib.rs +++ b/cmd/readvar/src/lib.rs @@ -147,7 +147,7 @@ fn readvar(subargs: ReadvarArgs, context: &mut ExecutionContext) -> Result<()> { "attaching failed, falling back to archive: {err}" ); } - humility::core::attach_archive(hubris)? + humility::core::attach_archive(hubris).map(Box::new)? } }; let core = &mut *core; diff --git a/cmd/reset/src/lib.rs b/cmd/reset/src/lib.rs index b07319962..e4378def9 100644 --- a/cmd/reset/src/lib.rs +++ b/cmd/reset/src/lib.rs @@ -75,7 +75,7 @@ fn reset(subargs: ResetArgs, context: &mut ExecutionContext) -> Result<()> { } }; - let mut c = if subargs.soft_reset + let mut c: Box = if subargs.soft_reset || matches!(behavior, Behavior::Halt | Behavior::ResetWithHandoff(..)) { let chip = hubris.as_ref().and_then(|h| h.chip()).ok_or_else(|| { @@ -87,9 +87,11 @@ fn reset(subargs: ResetArgs, context: &mut ExecutionContext) -> Result<()> { probe, Some(&chip), context.cli.speed, - )? + ) + .map(Box::new)? } else { - humility_probes_core::attach_to_probe(probe, context.cli.speed)? + humility_probes_core::attach_to_probe(probe, context.cli.speed) + .map(Box::new)? }; let r = match behavior { diff --git a/humility-cli/src/lib.rs b/humility-cli/src/lib.rs index 49d86c469..b7fcdee4a 100644 --- a/humility-cli/src/lib.rs +++ b/humility-cli/src/lib.rs @@ -171,6 +171,7 @@ impl Cli { }; let timeout = Duration::from_millis(self.timeout as u64); humility_net_core::attach_net(ip.0.clone()?, hubris, timeout) + .map(|b| Box::new(b) as Box) } else { self.attach_probe(hubris) }?; @@ -211,7 +212,8 @@ impl Cli { let probe = match self.probe.as_deref() { Some("archive") => { if let Some(hubris) = hubris { - return humility::core::attach_archive(hubris); + return humility::core::attach_archive(hubris) + .map(|b| Box::new(b) as Box); } else { bail!("cannot specify `--probe=archive` with no archive"); } @@ -222,6 +224,7 @@ impl Cli { let chip = hubris.and_then(|h| h.chip()); humility_probes_core::attach_to_chip(probe, chip.as_deref(), self.speed) + .map(|b| Box::new(b) as Box) } #[cfg(not(feature = "probes"))] @@ -242,16 +245,18 @@ impl Cli { validate: Option, ) -> Result> { let mut core = if let Some(dump) = &self.dump { - humility::core::attach_dump(dump)? + humility::core::attach_dump(dump) + .map(|b| Box::new(b) as Box) } else if let Some(ip) = &self.ip { let Some(hubris) = hubris else { bail!("cannot connect over the network without archive"); }; let timeout = Duration::from_millis(self.timeout as u64); - humility_net_core::attach_net(ip.0.clone()?, hubris, timeout)? + humility_net_core::attach_net(ip.0.clone()?, hubris, timeout) + .map(|b| Box::new(b) as Box) } else { - self.attach_probe(hubris)? - }; + self.attach_probe(hubris) + }?; if let Some(validate) = validate { let Some(hubris) = hubris else { bail!("cannot validate without Hubris archive"); @@ -289,7 +294,7 @@ impl Cli { /// Attaches to a dump /// /// Reads from the `--dump` argument to pick a target file - pub fn attach_dump(&self) -> Result> { + pub fn attach_dump(&self) -> Result { let core = if let Some(dump) = &self.dump { humility::core::attach_dump(dump)? } else { diff --git a/humility-core/src/archive.rs b/humility-core/src/archive.rs index f4f4a4ec6..b872a01ab 100644 --- a/humility-core/src/archive.rs +++ b/humility-core/src/archive.rs @@ -7,7 +7,6 @@ use crate::hubris::HubrisArchive; use crate::hubris::HubrisFlashMap; use anyhow::{Result, anyhow, bail}; use humility_arch_arm::ARMRegister; -use std::path::Path; pub struct ArchiveCore { flash: HubrisFlashMap, @@ -70,10 +69,6 @@ impl Core for ArchiveCore { bail!("can't step an archive"); } - fn load(&mut self, _path: &Path) -> Result<()> { - bail!("cannot load flash to an archive"); - } - fn reset(&mut self) -> Result<()> { bail!("cannot reset an archive"); } diff --git a/humility-core/src/core.rs b/humility-core/src/core.rs index 883ef9b03..ca6fe4ecb 100644 --- a/humility-core/src/core.rs +++ b/humility-core/src/core.rs @@ -8,7 +8,6 @@ use crate::archive::ArchiveCore; use crate::dump::DumpCore; use crate::hubris::*; use humility_arch_arm::ARMRegister; -use std::path::Path; use std::str; use std::time::Duration; use thiserror::Error; @@ -57,11 +56,6 @@ pub trait Core { Ok(u64::from_le_bytes(buf)) } - /// - /// Called to load a flash image. - /// - fn load(&mut self, path: &Path) -> Result<()>; - /// Reset the chip fn reset(&mut self) -> Result<()>; @@ -129,16 +123,16 @@ pub enum NetAgent { Hiffy, } -pub fn attach_dump(dump: &str) -> Result> { +pub fn attach_dump(dump: &str) -> Result { let core = DumpCore::new(dump)?; crate::msg!("attached to dump"); - Ok(Box::new(core)) + Ok(core) } -pub fn attach_archive(hubris: &HubrisArchive) -> Result> { +pub fn attach_archive(hubris: &HubrisArchive) -> Result { let core = ArchiveCore::new(hubris)?; crate::msg!("attached to archive"); - Ok(Box::new(core)) + Ok(core) } pub const CORE_MAX_READSIZE: usize = 65536; // 64K ought to be enough for anyone diff --git a/humility-core/src/dump.rs b/humility-core/src/dump.rs index 261292376..061a8fecc 100644 --- a/humility-core/src/dump.rs +++ b/humility-core/src/dump.rs @@ -11,7 +11,6 @@ use num_traits::FromPrimitive; use std::collections::{BTreeMap, HashMap}; use std::fs::File; use std::io::Read; -use std::path::Path; pub struct DumpCore { contents: Vec, @@ -203,10 +202,6 @@ impl Core for DumpCore { true } - fn load(&mut self, _path: &Path) -> Result<()> { - bail!("Flash loading is not supported on a dump"); - } - fn reset(&mut self) -> Result<()> { bail!("Reset is not supported on a dump"); } diff --git a/humility-dump-agent/src/lib.rs b/humility-dump-agent/src/lib.rs index 7fe639d63..2daa0c75c 100644 --- a/humility-dump-agent/src/lib.rs +++ b/humility-dump-agent/src/lib.rs @@ -28,7 +28,6 @@ use indicatif::{HumanBytes, HumanDuration, ProgressBar, ProgressStyle}; use num_traits::FromPrimitive; use std::{ collections::{BTreeMap, HashMap}, - path::Path, time::Instant, }; use zerocopy::FromBytes; @@ -349,10 +348,6 @@ impl Core for DumpAgentCore { bail!("can't step over dump agent"); } - fn load(&mut self, _path: &Path) -> Result<()> { - bail!("cannot load flash over dump agent"); - } - fn reset(&mut self) -> Result<()> { bail!("cannot reset over dump agent"); } diff --git a/humility-net-core/src/lib.rs b/humility-net-core/src/lib.rs index fa08b8541..8021ad42b 100644 --- a/humility-net-core/src/lib.rs +++ b/humility-net-core/src/lib.rs @@ -27,7 +27,6 @@ use humility_dump_agent::{ }; use std::{ net::{ToSocketAddrs, UdpSocket}, - path::Path, time::Duration, }; @@ -369,10 +368,6 @@ impl Core for NetCore { bail!("can't step over network"); } - fn load(&mut self, _path: &Path) -> Result<()> { - bail!("cannot load flash over network"); - } - fn reset(&mut self) -> Result<()> { bail!("cannot reset over network"); } @@ -390,8 +385,8 @@ pub fn attach_net( ip: ScopedV6Addr, hubris: &HubrisArchive, timeout: Duration, -) -> Result> { +) -> Result { let core = NetCore::new(ip, hubris, timeout)?; msg!("connecting to {ip}"); - Ok(Box::new(core)) + Ok(core) } diff --git a/humility-probes-core/src/lib.rs b/humility-probes-core/src/lib.rs index 84e9fd757..c1878c23f 100644 --- a/humility-probes-core/src/lib.rs +++ b/humility-probes-core/src/lib.rs @@ -6,7 +6,7 @@ use ::probe_rs::{ DebugProbeError, DebugProbeInfo, DebugProbeSelector, Probe, ProbeCreationError, }; -use humility::core::{Core, ProbeError}; +use humility::core::ProbeError; use anyhow::{Result, anyhow, bail}; use humility::msg; @@ -14,6 +14,9 @@ use humility::msg; mod probe_rs; mod unattached; +pub use probe_rs::ProbeCore; +pub use unattached::UnattachedCore; + fn parse_probe(probe: &str) -> (&str, Option) { if probe.contains('-') { let str = probe.to_owned(); @@ -110,7 +113,7 @@ fn open_probe + Clone>( pub fn attach_to_probe( probe: &str, speed_khz: Option, -) -> Result> { +) -> Result { let (probe, index) = parse_probe(probe); match probe { @@ -120,13 +123,13 @@ pub fn attach_to_probe( let probe = open_probe(&probe_info, speed_khz)?; crate::msg!("Opened probe {}", probe_info.identifier); - Ok(Box::new(unattached::UnattachedCore::new( + Ok(UnattachedCore::new( probe, probe_info.identifier.clone(), probe_info.vendor_id, probe_info.product_id, probe_info.serial_number, - ))) + )) } "auto" => attach_to_probe("usb", speed_khz), _ => match TryInto::::try_into(probe) { @@ -139,9 +142,7 @@ pub fn attach_to_probe( let name = probe.get_name(); crate::msg!("Opened {vidpid} via {name}"); - Ok(Box::new(unattached::UnattachedCore::new( - probe, name, vid, pid, serial, - ))) + Ok(UnattachedCore::new(probe, name, vid, pid, serial)) } Err(_) => Err(anyhow!("unrecognized probe: {}", probe)), }, @@ -153,7 +154,7 @@ pub fn attach_to_chip( probe: &str, chip: Option<&str>, speed_khz: Option, -) -> Result> { +) -> Result { let (probe, index) = parse_probe(probe); match probe { @@ -178,14 +179,14 @@ pub fn attach_to_chip( crate::msg!("attached via {name}"); - Ok(Box::new(probe_rs::ProbeCore::new( + Ok(probe_rs::ProbeCore::new( session, probe_info.identifier.clone(), probe_info.vendor_id, probe_info.product_id, probe_info.serial_number, can_flash, - ))) + )) } "auto" => attach_to_chip("usb", chip, speed_khz), @@ -211,9 +212,9 @@ pub fn attach_to_chip( crate::msg!("attached to {vidpid} via {name}"); - Ok(Box::new(probe_rs::ProbeCore::new( + Ok(probe_rs::ProbeCore::new( session, name, vid, pid, serial, can_flash, - ))) + )) } Err(_) => Err(anyhow!("unrecognized probe: {probe}")), }, @@ -224,7 +225,7 @@ pub fn attach_for_flashing( probe: &str, chip: &str, speed_khz: Option, -) -> Result> { +) -> Result { attach_to_chip(probe, Some(chip), speed_khz) } @@ -237,15 +238,15 @@ pub trait HubrisAttach { /// hubris archive and that the archive matches the image /// id present on target. If no chip is is present in the archive /// this will still attach. - fn attach_probe(&self, probe: &str) -> Result>; + fn attach_probe(&self, probe: &str) -> Result; } impl HubrisAttach for humility::hubris::HubrisArchive { - fn attach_probe(&self, probe: &str) -> Result> { + fn attach_probe(&self, probe: &str) -> Result { let mut core = attach_to_chip(probe, self.chip().as_deref(), None)?; self.validate( - &mut *core, + &mut core, humility::hubris::HubrisValidate::ArchiveMatch, )?; diff --git a/humility-probes-core/src/probe_rs.rs b/humility-probes-core/src/probe_rs.rs index 3cfa9b2f7..fdd09ee4d 100644 --- a/humility-probes-core/src/probe_rs.rs +++ b/humility-probes-core/src/probe_rs.rs @@ -204,7 +204,45 @@ impl Core for ProbeCore { Ok(()) } - fn load(&mut self, path: &Path) -> Result<()> { + fn reset(&mut self) -> Result<()> { + let mut core = self.session.core(0)?; + core.reset()?; + self.halted = false; + Ok(()) + } + + fn reset_and_halt(&mut self, dur: std::time::Duration) -> Result<()> { + let mut core = self.session.core(0)?; + core.reset_and_halt(dur)?; + self.halted = true; + Ok(()) + } + + fn op_start(&mut self) -> Result<()> { + self.halt()?; + + Ok(()) + } + + fn op_done(&mut self) -> Result<()> { + self.run()?; + + Ok(()) + } + + fn wait_for_halt(&mut self, dur: std::time::Duration) -> Result<()> { + if !self.halted { + let mut core = self.session.core(0)?; + core.wait_for_core_halted(dur)?; + self.halted = true; + } + + Ok(()) + } +} + +impl ProbeCore { + pub fn load(&mut self, path: &Path) -> Result<()> { #[derive(Debug, Default)] struct LoadProgress { /// total bytes that need to be erased @@ -289,41 +327,6 @@ impl Core for ProbeCore { bail!("Flash loading failed {:?}", e); }; - Ok(()) - } - fn reset(&mut self) -> Result<()> { - let mut core = self.session.core(0)?; - core.reset()?; - self.halted = false; - Ok(()) - } - - fn reset_and_halt(&mut self, dur: std::time::Duration) -> Result<()> { - let mut core = self.session.core(0)?; - core.reset_and_halt(dur)?; - self.halted = true; - Ok(()) - } - - fn op_start(&mut self) -> Result<()> { - self.halt()?; - - Ok(()) - } - - fn op_done(&mut self) -> Result<()> { - self.run()?; - - Ok(()) - } - - fn wait_for_halt(&mut self, dur: std::time::Duration) -> Result<()> { - if !self.halted { - let mut core = self.session.core(0)?; - core.wait_for_core_halted(dur)?; - self.halted = true; - } - Ok(()) } } diff --git a/humility-probes-core/src/unattached.rs b/humility-probes-core/src/unattached.rs index 67d3d566f..4d23eb1c2 100644 --- a/humility-probes-core/src/unattached.rs +++ b/humility-probes-core/src/unattached.rs @@ -5,7 +5,6 @@ use anyhow::{Result, bail}; use humility::core::Core; use humility_arch_arm::ARMRegister; -use std::path::Path; pub struct UnattachedCore { pub probe: probe_rs::Probe, @@ -73,10 +72,6 @@ impl Core for UnattachedCore { bail!("Core::step unimplemented when unattached!"); } - fn load(&mut self, _path: &Path) -> Result<()> { - bail!("Core::load unimplemented when unattached!"); - } - fn reset(&mut self) -> Result<()> { self.probe.target_reset_assert()?;