Skip to content
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
1,052 changes: 856 additions & 196 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,17 @@ tlvc-text = { git = "https://github.com/oxidecomputer/tlvc", version = "0.4.0" }
turin-post-decoder = { git = "https://github.com/oxidecomputer/turin-post-decoder" }
vsc7448-info = { git = "https://github.com/oxidecomputer/vsc7448.git" }
vsc7448-types = { git = "https://github.com/oxidecomputer/vsc7448.git" }
# This will ideally be merged soon
nusb = { git = "https://github.com/oxidecomputer/nusb.git", branch = "add_illumos" }

#
# We depend on the oxide-stable branch of Oxide's fork of probe-rs to assure
# that we can float necessary patches on probe-rs.
# that we can float necessary patches on probe-rs.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: linewrap this whole block?

#
probe-rs = { git = "https://github.com/oxidecomputer/probe-rs.git", branch = "oxide-v0.12.0" }
# As of this commit the patches are pretty minimal: an updated nusb branch
# with illumos support and some tweaks to avoid the need to pull in
# serialport. The dream would still be to run a regular probe-rs release.
probe-rs = { git = "https://github.com/oxidecomputer/probe-rs.git", branch = "oxide_v0.31.0", default-features = false, features = ["builtin-targets"] }

# Local `path`-based deps
humility = { path = "./humility-core", package = "humility-core" }
Expand Down Expand Up @@ -233,7 +238,6 @@ raw-cpuid = { version = "11.0.0", features = ["display"] }
rayon = "1.7"
regex = "1.5.5"
ron = "0.12"
rusb = "0.8.1"
rustc-demangle = "0.1.21"
scroll = "0.13"
serde = { version = "1.0.228", features = ["derive"] }
Expand Down Expand Up @@ -263,7 +267,3 @@ debug = true
inherits = "release"
debug = false
debug-assertions = true

[patch.crates-io]
libusb1-sys = { git = "https://github.com/oxidecomputer/rusb", branch = "probe-rs-0.12-libusb-v1.0.26" }
hidapi = { git = "https://github.com/oxidecomputer/hidapi-rs", branch = "oxide-stable" }
75 changes: 29 additions & 46 deletions cmd/debugmailbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,18 @@ use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use clap::{CommandFactory, Parser};
use humility_cli::ExecutionContext;
use humility_cmd::Command;
use probe_rs::{
DebugProbeError, DebugProbeSelector, Probe,
architecture::arm::{ApAddress, ArmProbeInterface, DapError, DpAddress},
use probe_rs::architecture::arm::{
ArmDebugInterface, ArmError, DapError, FullyQualifiedApAddress,
sequences::DefaultArmSequence,
};
use probe_rs::probe::DebugProbeSelector;

// The debug mailbox registers
// See 51.5.5.1 of Rev 2.4 of the LPC55 manual
const CSW: u8 = 0x0;
const REQUEST: u8 = 0x4;
const RETURN: u8 = 0x8;
const IDR: u8 = 0xFC;
const CSW: u64 = 0x0;
const REQUEST: u64 = 0x4;
const RETURN: u64 = 0x8;
const IDR: u64 = 0xFC;

// Are we talking to the wrong chip?
const SP_IDR: u32 = 0x54770002;
Expand Down Expand Up @@ -104,9 +105,9 @@ enum DebugMailboxCmd {
}

fn poll_raw_ap_register(
probe: &mut Box<dyn ArmProbeInterface + '_>,
ap: &ApAddress,
addr: u8,
probe: &mut Box<dyn ArmDebugInterface + '_>,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered if we could remove the Box here (in favor of a &mut dyn ArmDebugInterface), but poking at it shows that it would ripple through a bunch of places, so out of scope for this PR.

ap: &FullyQualifiedApAddress,
addr: u64,
mut f: impl FnMut(u32) -> Result<bool>,
mut timeout_ms: usize,
) -> Result<u32> {
Expand All @@ -118,30 +119,13 @@ fn poll_raw_ap_register(
// this initial delay.
std::thread::sleep(std::time::Duration::from_millis(10));

match probe.read_raw_ap_register(*ap, addr) {
match probe.read_raw_ap_register(ap, addr) {
Ok(val) => match f(val) {
Ok(true) => return Ok(val),
Ok(false) => (),
Err(e) => return Err(e),
},
Err(DebugProbeError::ArchitectureSpecific(arch_err)) => {
match arch_err.downcast::<DapError>() {
Ok(dap_err) => match *dap_err {
DapError::WaitResponse => {}
e => {
return Err(DebugProbeError::ArchitectureSpecific(
e.into(),
)
.into());
}
},
Err(e) => {
return Err(
DebugProbeError::ArchitectureSpecific(e).into()
);
}
}
}
Err(ArmError::Dap(DapError::WaitResponse)) => {}
Err(x) => return Err(x.into()),
}

Expand All @@ -155,12 +139,12 @@ fn poll_raw_ap_register(
}

fn alive<'a>(
probe: &mut Box<dyn ArmProbeInterface + 'a>,
addr: &ApAddress,
probe: &mut Box<dyn ArmDebugInterface + 'a>,
addr: &FullyQualifiedApAddress,
reset: bool,
) -> Result<()> {
if reset {
probe.write_raw_ap_register(*addr, CSW, 0x21)?;
probe.write_raw_ap_register(addr, CSW, 0x21)?;
println!("Resetting chip via SYSREQRESET!");
}

Expand All @@ -171,11 +155,11 @@ fn alive<'a>(
}

fn write_request_reg<'a>(
probe: &mut Box<dyn ArmProbeInterface + 'a>,
addr: &ApAddress,
probe: &mut Box<dyn ArmDebugInterface + 'a>,
addr: &FullyQualifiedApAddress,
val: u32,
) -> Result<()> {
probe.write_raw_ap_register(*addr, REQUEST, val)?;
probe.write_raw_ap_register(addr, REQUEST, val)?;

let _ = poll_raw_ap_register(
probe,
Expand All @@ -198,8 +182,8 @@ fn write_request_reg<'a>(
}

fn write_req<'a>(
probe: &mut Box<dyn ArmProbeInterface + 'a>,
addr: &ApAddress,
probe: &mut Box<dyn ArmDebugInterface + 'a>,
addr: &FullyQualifiedApAddress,
command: DMCommand,
args: &[u32],
) -> Result<Vec<u32>> {
Expand Down Expand Up @@ -258,8 +242,8 @@ fn write_req<'a>(
}

fn read_return<'a>(
probe: &mut Box<dyn ArmProbeInterface + 'a>,
addr: &ApAddress,
probe: &mut Box<dyn ArmDebugInterface + 'a>,
addr: &FullyQualifiedApAddress,
) -> Result<u32> {
poll_raw_ap_register(probe, addr, RETURN, |_| Ok(true), 1000)
.context("Reading debugmailbox RETURN register")
Expand All @@ -269,14 +253,15 @@ fn debugmailboxcmd(context: &mut ExecutionContext) -> Result<()> {
let subargs = DebugMailboxArgs::try_parse_from(&context.cli.cmd)?;

// Get a list of all available debug probes.
let probes = Probe::list_all();
let list = probe_rs::probe::list::Lister::new();
let probes = list.list_all();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I love the smell of fresh API design in the morning


if probes.is_empty() {
bail!("No probes found!");
}

let mut probe = match &context.cli.probe {
Some(p) => match TryInto::<DebugProbeSelector>::try_into(p.clone()) {
Some(p) => match p.parse::<DebugProbeSelector>() {
Ok(selector) => {
let vid = selector.vendor_id;
let pid = selector.product_id;
Expand All @@ -301,12 +286,10 @@ fn debugmailboxcmd(context: &mut ExecutionContext) -> Result<()> {

probe.attach_to_unspecified()?;
let mut iface = probe
.try_into_arm_interface()
.unwrap()
.initialize_unspecified()
.try_into_arm_debug_interface(DefaultArmSequence::create())
.unwrap();

let dm_port = ApAddress { dp: DpAddress::Default, ap: 2 };
let dm_port = FullyQualifiedApAddress::v1_with_default_dp(2);

// Check if this is a debug mailbox. This is based on the sequence from
// the LPC55 Debug Mailbox user manual
Expand All @@ -315,7 +298,7 @@ fn debugmailboxcmd(context: &mut ExecutionContext) -> Result<()> {
// handles this for us

// Check the IDR
let val = iface.read_raw_ap_register(dm_port, IDR)?;
let val = iface.read_raw_ap_register(&dm_port, IDR)?;

if val != DM_ID {
if val == SP_IDR {
Expand Down
2 changes: 1 addition & 1 deletion cmd/lsusb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ humility-cmd = { workspace = true }
humility-cli = { workspace = true }
clap = { workspace = true }
anyhow = { workspace = true }
rusb = {workspace = true}
nusb = {workspace = true}
82 changes: 49 additions & 33 deletions cmd/lsusb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use clap::{CommandFactory, Parser};
use humility_cli::ExecutionContext;
use humility_cmd::Command;
use nusb::{MaybeFuture, descriptors::language_id::US_ENGLISH};
use std::collections::HashMap;
use std::time::Duration;

Expand All @@ -34,17 +35,17 @@
HashMap::new()
};

let devices = rusb::devices()?;
let devices = nusb::list_devices().wait()?;
let mut successes = vec![];
let mut failures = vec![];
for dev in devices.iter() {
for dev in devices {
match list1(&dev) {
Ok(summary) => successes.push(summary),
Err(e) => {
failures.push((
dev.bus_number(),
dev.address(),
dev.port_number(),
dev.busnum(),

Check failure on line 46 in cmd/lsusb/src/lib.rs

View workflow job for this annotation

GitHub Actions / Check (MSRV) (windows-latest)

no method named `busnum` found for struct `DeviceInfo` in the current scope

Check failure on line 46 in cmd/lsusb/src/lib.rs

View workflow job for this annotation

GitHub Actions / Check (windows-latest)

no method named `busnum` found for struct `DeviceInfo` in the current scope

Check failure on line 46 in cmd/lsusb/src/lib.rs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

no method named `busnum` found for struct `DeviceInfo` in the current scope
dev.device_address(),
dev.port_chain()[0],
e,
));
}
Expand Down Expand Up @@ -106,36 +107,51 @@
Ok(())
}

fn list1(
dev: &rusb::Device<impl rusb::UsbContext>,
) -> Result<(String, String)> {
const TIMEOUT: Duration = Duration::from_secs(1);

let desc = dev.device_descriptor()?;
let vid = desc.vendor_id();
let pid = desc.product_id();
fn list1(dev: &nusb::DeviceInfo) -> Result<(String, String)> {
let timeout = Duration::from_millis(100);
let vid = dev.vendor_id();
let pid = dev.product_id();

let dev = dev
.open()
.wait()
.map_err(|e| anyhow!("{vid:04x}:{pid:04x}:???\topen failed: {e}"))?;
let dev_descriptor = dev.device_descriptor();

let languages: Vec<u16> = dev
.get_string_descriptor_supported_languages(timeout)
.wait()
.map(|i| i.collect())
.unwrap_or_default();

let language = languages.first().copied().unwrap_or(US_ENGLISH);

let man = if let Some(i_manufacturer) =
dev_descriptor.manufacturer_string_index()
{
dev.get_string_descriptor(i_manufacturer, language, timeout)
.wait()
.unwrap_or("(manufacturer unknown)".to_string())
} else {
"(manufacturer unknown)".to_string()
};

let handle = match dev.open() {
Ok(handle) => handle,
Err(e) => {
return Err(anyhow!("{vid:04x}:{pid:04x}:???\topen failed: {e}"));
}
let prod = if let Some(i_product) = dev_descriptor.product_string_index() {
dev.get_string_descriptor(i_product, language, timeout)
.wait()
.unwrap_or("(product unknown)".to_string())
} else {
"(product unknown)".to_string()
};
let lang = *handle
.read_languages(TIMEOUT)?
.iter()
.find(|lang| lang.primary_language() == rusb::PrimaryLanguage::English)
.ok_or_else(|| anyhow!("can't find English strings"))?;

let man = handle
.read_manufacturer_string(lang, &desc, TIMEOUT)
.unwrap_or_else(|_| "(manufacturer unknown)".to_string());
let prod = handle
.read_product_string(lang, &desc, TIMEOUT)
.unwrap_or_else(|_| "(product unknown)".to_string());
let serial = handle
.read_serial_number_string(lang, &desc, TIMEOUT)
.unwrap_or_else(|_| "(serial unknown)".to_string());

let serial =
if let Some(i_serial) = dev_descriptor.serial_number_string_index() {
dev.get_string_descriptor(i_serial, language, timeout)
.wait()
.unwrap_or("(serial unknown)".to_string())
} else {
"(serial unknown)".to_string()
};

Ok((format!("{vid:04x}:{pid:04x}:{serial}"), format!("{man}\t{prod}")))
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/rendmp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ use std::io::Write;
use std::io::prelude::*;
use std::thread;
use std::time::{Duration, Instant};
use strum::VariantNames;
use strum::VariantNames as _;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spooky

use strum_macros::VariantNames;
use zerocopy::{FromBytes, IntoBytes};

Expand Down
2 changes: 1 addition & 1 deletion humility-probes-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ num-traits.workspace = true
parse_int.workspace = true
probe-rs.workspace = true
thiserror.workspace = true
rusb.workspace = true
nusb.workspace = true
Loading
Loading