1#![warn(missing_docs)]
12
13mod chip;
14pub mod chip_detection;
15mod chip_family;
16mod flash_algorithm;
17mod flash_properties;
18mod memory;
19pub(crate) mod serialize;
20
21pub use chip::{
22 ApAddress, ArmCoreAccessOptions, Chip, Core, CoreAccessOptions, Jtag, RiscvCoreAccessOptions,
23 RiscvJtagTunnel, ScanChainElement, XtensaCoreAccessOptions,
24};
25pub use chip_family::{
26 Architecture, ChipFamily, CoreType, Endian, InstructionSet, TargetDescriptionSource,
27};
28pub use flash_algorithm::{RawFlashAlgorithm, TransferEncoding};
29pub use flash_properties::FlashProperties;
30pub use memory::{
31 GenericRegion, MemoryAccess, MemoryRange, MemoryRegion, NvmRegion, PageInfo, RamRegion,
32 RegionMergeIterator, SectorDescription, SectorInfo,
33};
34
35#[cfg(feature = "bincode")]
36mod builtin_targets {
37 use std::fs::{read_dir, read_to_string};
38 use std::io;
39 use std::path::{Path, PathBuf};
40
41 use crate::ChipFamily;
42
43 pub fn process_targets(source_paths: &[PathBuf], dest_path: &Path) {
45 let mut families = Vec::new();
46 let mut process_target_yaml = |file: &Path| {
47 let string = read_to_string(file).unwrap_or_else(|error| {
48 panic!(
49 "Failed to read target file {} because:\n{error}",
50 file.display()
51 )
52 });
53
54 match yaml_serde::from_str::<ChipFamily>(&string) {
55 Ok(family) => families.push(family),
56 Err(error) => panic!(
57 "Failed to parse target file: {} because:\n{error}",
58 file.display()
59 ),
60 }
61 };
62
63 for path in source_paths {
64 visit_dirs(path, &mut process_target_yaml).unwrap();
65 }
66
67 let config = bincode::config::standard();
68 let families_bin = bincode::serde::encode_to_vec(&families, config)
69 .expect("Failed to serialize families as bincode");
70
71 std::fs::write(dest_path, &families_bin).unwrap();
72
73 if let Err(deserialize_error) =
75 bincode::serde::decode_from_slice::<Vec<ChipFamily>, _>(&families_bin, config)
76 {
77 panic!(
78 "Failed to deserialize supported target definitions from bincode: {deserialize_error:?}"
79 );
80 }
81 }
82
83 fn visit_dirs(dir: impl AsRef<Path>, process: &mut impl FnMut(&Path)) -> io::Result<()> {
85 fn visit_dirs_impl(dir: &Path, process: &mut impl FnMut(&Path)) -> io::Result<()> {
87 for entry in read_dir(dir)? {
88 let entry = entry?;
89 let path = entry.path();
90 if path.is_dir() {
91 visit_dirs_impl(&path, process)?;
92 } else {
93 process(&path);
94 }
95 }
96
97 Ok(())
98 }
99
100 let dir = dir.as_ref();
101 if !dir.is_dir() {
102 return Ok(());
103 }
104
105 visit_dirs_impl(dir, process)
106 }
107}
108
109#[cfg(feature = "bincode")]
110pub use builtin_targets::process_targets;