#![allow(non_upper_case_globals)]
use std::fmt;
enum_and_set!(
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Capability {
Reserved0 = 0, GetHwVersion = 1,
WriteDcc = 2,
AdaptiveClocking = 3,
ReadConfig = 4,
WriteConfig = 5,
Trace = 6,
WriteMem = 7,
ReadMem = 8,
SpeedInfo = 9,
ExecCode = 10,
GetMaxBlockSize = 11,
GetHwInfo = 12,
SetKsPower = 13,
ResetStopTimed = 14,
MeasureRtckReact = 16,
SelectIf = 17,
RwMemArm79 = 18,
GetCounters = 19,
ReadDcc = 20,
GetCpuCaps = 21,
ExecCpuCmd = 22,
Swo = 23,
WriteDccEx = 24,
UpdateFirmwareEx = 25,
FileIo = 26,
Register = 27,
Indicators = 28,
TestNetSpeed = 29,
RawTrace = 30,
GetCapsEx = 31,
HwJtagWrite = 32,
Com = 33,
}
flags CapabilityFlags: u128;
);
impl CapabilityFlags {
fn from_capability(cap: Capability) -> Self {
Self::from_bits(1 << cap as u32).unwrap()
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Capabilities(CapabilityFlags);
impl Capabilities {
pub(crate) fn from_raw_legacy(raw: u32) -> Self {
let mut capabilities = CapabilityFlags::from_bits_truncate(u128::from(raw));
if capabilities.bits() != u128::from(raw) {
log::debug!(
"unknown capability bits: 0x{:08X} truncated to 0x{:08X} ({:?})",
raw,
capabilities.bits(),
capabilities,
);
}
capabilities.remove(CapabilityFlags::Reserved0);
Self(capabilities)
}
pub(crate) fn from_raw_ex(raw: [u8; 32]) -> Self {
if raw[16..] != [0; 16] {
log::debug!(
"unknown ext. capability bits: dropping high 16 bytes {:02X?}",
&raw[16..],
);
}
let mut bytes = [0; 16];
bytes.copy_from_slice(&raw[..16]);
let raw = u128::from_le_bytes(bytes);
let mut capabilities = CapabilityFlags::from_bits_truncate(raw);
if capabilities.bits() != raw {
log::debug!(
"unknown ext. capability bits: 0x{:08X} truncated to 0x{:08X} ({:?})",
raw,
capabilities.bits(),
capabilities,
);
}
capabilities.remove(CapabilityFlags::Reserved0);
Self(capabilities)
}
pub fn contains(&self, cap: Capability) -> bool {
self.0.contains(CapabilityFlags::from_capability(cap))
}
pub fn contains_all(&self, caps: Capabilities) -> bool {
self.0.contains(caps.0)
}
}
impl fmt::Debug for Capabilities {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}