#![warn(missing_docs)]
mod chip;
pub mod chip_detection;
mod chip_family;
mod flash_algorithm;
mod flash_properties;
mod memory;
pub(crate) mod serialize;
pub use chip::{
ApAddress, ArmCoreAccessOptions, Chip, Core, CoreAccessOptions, Jtag, RiscvCoreAccessOptions,
RiscvJtagTunnel, ScanChainElement, XtensaCoreAccessOptions,
};
pub use chip_family::{
Architecture, ChipFamily, CoreType, Endian, InstructionSet, TargetDescriptionSource,
};
pub use flash_algorithm::{RawFlashAlgorithm, TransferEncoding};
pub use flash_properties::FlashProperties;
pub use memory::{
GenericRegion, MemoryAccess, MemoryRange, MemoryRegion, NvmRegion, PageInfo, RamRegion,
RegionMergeIterator, SectorDescription, SectorInfo,
};
#[cfg(feature = "bincode")]
mod builtin_targets {
use std::fs::{read_dir, read_to_string};
use std::io;
use std::path::{Path, PathBuf};
use crate::ChipFamily;
pub fn process_targets(source_paths: &[PathBuf], dest_path: &Path) {
let mut families = Vec::new();
let mut process_target_yaml = |file: &Path| {
let string = read_to_string(file).unwrap_or_else(|error| {
panic!(
"Failed to read target file {} because:\n{error}",
file.display()
)
});
match yaml_serde::from_str::<ChipFamily>(&string) {
Ok(family) => families.push(family),
Err(error) => panic!(
"Failed to parse target file: {} because:\n{error}",
file.display()
),
}
};
for path in source_paths {
visit_dirs(path, &mut process_target_yaml).unwrap();
}
let config = bincode::config::standard();
let families_bin = bincode::serde::encode_to_vec(&families, config)
.expect("Failed to serialize families as bincode");
std::fs::write(dest_path, &families_bin).unwrap();
if let Err(deserialize_error) =
bincode::serde::decode_from_slice::<Vec<ChipFamily>, _>(&families_bin, config)
{
panic!(
"Failed to deserialize supported target definitions from bincode: {deserialize_error:?}"
);
}
}
fn visit_dirs(dir: impl AsRef<Path>, process: &mut impl FnMut(&Path)) -> io::Result<()> {
fn visit_dirs_impl(dir: &Path, process: &mut impl FnMut(&Path)) -> io::Result<()> {
for entry in read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs_impl(&path, process)?;
} else {
process(&path);
}
}
Ok(())
}
let dir = dir.as_ref();
if !dir.is_dir() {
return Ok(());
}
visit_dirs_impl(dir, process)
}
}
#[cfg(feature = "bincode")]
pub use builtin_targets::process_targets;