use std::collections::HashMap;
use super::memory::MemoryRegion;
use crate::{
CoreType,
serialize::{hex_option, hex_u_int},
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ScanChainElement {
pub name: Option<String>,
pub ir_len: Option<u8>,
}
impl ScanChainElement {
pub fn ir_len(&self) -> u8 {
self.ir_len.unwrap_or(4)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct RiscvJtagTunnel {
pub ir_id: u32,
pub ir_width: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Jtag {
#[serde(default)]
pub scan_chain: Option<Vec<ScanChainElement>>,
#[serde(default)]
pub force_scan_chain: bool,
#[serde(default)]
pub riscv_tunnel: Option<RiscvJtagTunnel>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Chip {
pub name: String,
pub part: Option<u16>,
pub svd: Option<String>,
#[serde(default)]
pub documentation: HashMap<String, String>,
#[serde(default)]
pub package_variants: Vec<String>,
#[serde(default)]
pub cores: Vec<Core>,
pub memory_map: Vec<MemoryRegion>,
#[serde(default)]
pub flash_algorithms: Vec<String>,
pub rtt_scan_ranges: Option<Vec<std::ops::Range<u64>>>,
#[serde(default)]
pub jtag: Option<Jtag>,
#[serde(default)]
pub default_binary_format: Option<String>,
}
impl Chip {
pub fn generic_arm(name: &str, core_type: CoreType) -> Self {
Chip {
name: name.to_string(),
part: None,
svd: None,
documentation: HashMap::new(),
package_variants: vec![],
cores: vec![Core {
name: "main".to_string(),
core_type,
core_access_options: CoreAccessOptions::Arm(ArmCoreAccessOptions::default()),
}],
memory_map: vec![],
flash_algorithms: vec![],
rtt_scan_ranges: None,
jtag: None,
default_binary_format: None,
}
}
pub fn package_variants(&self) -> impl Iterator<Item = &String> {
std::slice::from_ref(&self.name)
.iter()
.chain(self.package_variants.iter())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Core {
pub name: String,
#[serde(rename = "type")]
pub core_type: CoreType,
pub core_access_options: CoreAccessOptions,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CoreAccessOptions {
Arm(ArmCoreAccessOptions),
Riscv(RiscvCoreAccessOptions),
Xtensa(XtensaCoreAccessOptions),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ApAddress {
#[serde(rename = "v1")]
V1(u8),
#[serde(rename = "v2")]
#[serde(serialize_with = "hex_u_int")]
V2(u64),
}
impl Default for ApAddress {
fn default() -> Self {
ApAddress::V1(0)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
pub struct ArmCoreAccessOptions {
pub ap: ApAddress,
#[serde(serialize_with = "hex_option")]
pub targetsel: Option<u32>,
#[serde(serialize_with = "hex_option")]
pub debug_base: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub cti_base: Option<u64>,
pub jtag_tap: Option<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RiscvCoreAccessOptions {
pub hart_id: Option<u32>,
pub jtag_tap: Option<usize>,
#[serde(default)]
pub mem_ap: Option<ApAddress>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct XtensaCoreAccessOptions {
pub jtag_tap: Option<usize>,
}