use bitflags::bitflags;
use std::{fmt, ops};
bitflags! {
struct CapabilitiesBits: u128 {
const GET_HW_VERSION = (1 << 1);
const WRITE_DCC = (1 << 2);
const ADAPTIVE_CLOCKING = (1 << 3);
const READ_CONFIG = (1 << 4);
const WRITE_CONFIG = (1 << 5);
const TRACE = (1 << 6);
const WRITE_MEM = (1 << 7);
const READ_MEM = (1 << 8);
const SPEED_INFO = (1 << 9);
const EXEC_CODE = (1 << 10);
const GET_MAX_BLOCK_SIZE = (1 << 11);
const GET_HW_INFO = (1 << 12);
const SET_KS_POWER = (1 << 13);
const RESET_STOP_TIMED = (1 << 14);
const MEASURE_RTCK_REACT = (1 << 16);
const SELECT_IF = (1 << 17);
const RW_MEM_ARM79 = (1 << 18);
const GET_COUNTERS = (1 << 19);
const READ_DCC = (1 << 20);
const GET_CPU_CAPS = (1 << 21);
const EXEC_CPU_CMD = (1 << 22);
const SWO = (1 << 23);
const WRITE_DCC_EX = (1 << 24);
const UPDATE_FIRMWARE_EX = (1 << 25);
const FILE_IO = (1 << 26);
const REGISTER = (1 << 27);
const INDICATORS = (1 << 28);
const TEST_NET_SPEED = (1 << 29);
const RAWTRACE = (1 << 30);
const GET_CAPS_EX = (1 << 31);
const HW_JTAG_WRITE = (1 << 32);
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Capabilities {
inner: CapabilitiesBits,
}
macro_rules! import_capabilities {
(
$(
$name:ident,
)+
) => {
$(
pub const $name: Self = Self { inner: CapabilitiesBits::$name };
)+
};
}
impl Capabilities {
import_capabilities![
GET_HW_VERSION,
WRITE_DCC,
ADAPTIVE_CLOCKING,
READ_CONFIG,
WRITE_CONFIG,
TRACE,
WRITE_MEM,
READ_MEM,
SPEED_INFO,
EXEC_CODE,
GET_MAX_BLOCK_SIZE,
GET_HW_INFO,
SET_KS_POWER,
RESET_STOP_TIMED,
MEASURE_RTCK_REACT,
SELECT_IF,
RW_MEM_ARM79,
GET_COUNTERS,
READ_DCC,
GET_CPU_CAPS,
EXEC_CPU_CMD,
SWO,
WRITE_DCC_EX,
UPDATE_FIRMWARE_EX,
FILE_IO,
REGISTER,
INDICATORS,
TEST_NET_SPEED,
RAWTRACE,
GET_CAPS_EX,
HW_JTAG_WRITE,
];
pub(crate) fn from_raw_legacy(raw: u32) -> Self {
Self {
inner: CapabilitiesBits::from_bits_truncate(u128::from(raw)),
}
}
pub(crate) fn from_raw_ex(raw: [u8; 32]) -> Self {
let mut bits = [0; 16];
bits.copy_from_slice(&raw[..16]);
Self {
inner: CapabilitiesBits::from_bits_truncate(u128::from_le_bytes(bits)),
}
}
pub fn contains(&self, other: Self) -> bool {
self.inner.contains(other.inner)
}
}
impl fmt::Debug for Capabilities {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl ops::BitOr for Capabilities {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
Self {
inner: self.inner | rhs.inner,
}
}
}