use crate::rpc::client::RpcClient;
use crate::CoreOptions;
use crate::util::common_options::{ProbeOptions, ReadWriteBitWidth, ReadWriteOptions};
use crate::util::{cli, parse_u64};
#[derive(clap::Parser)]
#[clap(verbatim_doc_comment)]
pub struct Cmd {
#[clap(flatten)]
shared: CoreOptions,
#[clap(flatten)]
probe_options: ProbeOptions,
#[clap(flatten)]
read_write_options: ReadWriteOptions,
#[clap(value_parser = parse_u64)]
values: Vec<u64>,
}
fn ensure_data_in_range(data: &[u64], width: ReadWriteBitWidth) -> anyhow::Result<()> {
let max = match width {
ReadWriteBitWidth::B8 => u8::MAX as u64,
ReadWriteBitWidth::B16 => u16::MAX as u64,
ReadWriteBitWidth::B32 => u32::MAX as u64,
ReadWriteBitWidth::B64 => u64::MAX,
};
if let Some(big) = data.iter().find(|&&v| v > max) {
anyhow::bail!(
"{} in {:?} is too large for an {} bit write.",
big,
data,
width as u8,
);
}
Ok(())
}
impl Cmd {
pub async fn run(self, client: RpcClient) -> anyhow::Result<()> {
ensure_data_in_range(&self.values, self.read_write_options.width)?;
let session = cli::attach_probe(&client, self.probe_options, false).await?;
let core = session.core(self.shared.core);
match self.read_write_options.width {
ReadWriteBitWidth::B8 => {
core.write_memory_8(
self.read_write_options.address,
self.values.iter().map(|v| *v as u8).collect(),
)
.await?;
}
ReadWriteBitWidth::B16 => {
core.write_memory_16(
self.read_write_options.address,
self.values.iter().map(|v| *v as u16).collect(),
)
.await?;
}
ReadWriteBitWidth::B32 => {
core.write_memory_32(
self.read_write_options.address,
self.values.iter().map(|v| *v as u32).collect(),
)
.await?;
}
ReadWriteBitWidth::B64 => {
core.write_memory_64(self.read_write_options.address, self.values)
.await?;
}
}
Ok(())
}
}