parse_rom_table/
parse-rom-table.rs1use std::cell::RefCell;
2use std::rc::Rc;
3use std::ops::DerefMut;
4use std::num::ParseIntError;
5
6use clap::Parser;
7
8use jtag_taps::taps::Taps;
9use jtag_taps::statemachine::JtagSM;
10use jtag_taps::cable::{self, Cable};
11
12use jtag_adi::{ArmDebugInterface, MemAP};
13
14fn trace_sink_to_str(devtype: u32) -> &'static str {
15 match devtype >> 4{
16 1 => "TPIU",
17 2 => "ETB",
18 3 => "Router",
19 _ => "Other",
20 }
21}
22
23fn trace_link_to_str(devtype: u32) -> &'static str {
24 match devtype >> 4 {
25 1 => "Router",
26 2 => "Filter",
27 3 => "FIFO",
28 _ => "Other",
29 }
30}
31
32fn trace_source_to_str(devtype: u32) -> &'static str {
33 match devtype >> 4 {
34 1 => "CPU",
35 2 => "DSP",
36 3 => "Coprocessor",
37 4 => "Bus",
38 _ => "Other",
39 }
40}
41
42fn debug_control_to_str(devtype: u32) -> &'static str {
43 match devtype >> 4 {
44 1 => "Trigger Matrix",
45 2 => "Debug Authentication",
46 3 => "Power Requestor",
47 _ => "Other",
48 }
49}
50
51fn debug_logic_to_str(devtype: u32) -> &'static str {
52 match devtype >> 4 {
53 1 => "CPU",
54 2 => "DSP",
55 3 => "Coprocessor",
56 4 => "BUS",
57 5 => "Memory",
58 _ => "Other",
59 }
60}
61
62fn devtype_to_str(devtype: u32) -> String {
63 match devtype & 0xf {
64 0 => format!("Misc"),
65 1 => format!("Trace sink: {}", trace_sink_to_str(devtype)),
66 2 => format!("Trace link: {}", trace_link_to_str(devtype)),
67 3 => format!("Trace source: {}", trace_source_to_str(devtype)),
68 4 => format!("Debug control: {}", debug_control_to_str(devtype)),
69 5 => format!("Debug logic: {}", debug_logic_to_str(devtype)),
70 _ => "Other".to_string()
71 }
72}
73
74fn parse_rom_table<T,U>(mem: &mut MemAP<T>, base: u32) -> Result<(), u8>
75 where T: DerefMut<Target=U>,
76 U: Cable + ?Sized,
77{
78 let _cidr0 = mem.read(base + 0xff0)?;
79 let cidr1 = mem.read(base + 0xff4)?;
81 let _cidr2 = mem.read(base + 0xff8)?;
82 let _cidr3 = mem.read(base + 0xffc)?;
84 match cidr1 {
87 0x10 => {
88 println!("Found ROM table at {:x}", base);
89
90 for i in 0..960 {
91 let romentry = mem.read(base + i * 4)?;
92 if romentry == 0 {
93 break;
94 }
95
96 if romentry & 1 != 0 {
97 println!("Entry {} present", i);
98 if romentry & (1 << 2) != 0 {
99 println!(" PD valid");
100 }
101 let offset = romentry >> 12;
102 println!(" Offset {}", offset);
103 parse_rom_table(mem, base + (offset << 12)).expect("parse sub table");
104 }
105 }
106 }
107 0x90 => {
108 println!("Found CoreSight component at {:x}", base);
109 let auth = mem.read(base + 0xfb8)?;
110 println!(" Auth {:x}", auth);
111 let devaff0 = mem.read(base + 0xfa8)?;
112 let devaff1 = mem.read(base + 0xfac)?;
113 println!(" Device affinity {:08x} {:08x}", devaff0, devaff1);
114 let archid = mem.read(base + 0xfbc)?;
115 println!(" Arch ID {:08x}", archid);
116 let devtype = mem.read(base + 0xfcc)?;
117 println!(" Device type {:08x} {}", devtype, devtype_to_str(devtype));
118 }
119 _ => {
120 println!("Unknown entry at {:x}: {:x}", base, cidr1);
121 }
122 }
123
124 Ok(())
125}
126
127#[derive(Parser, Debug)]
128#[command(author, version, about, long_about = None)]
129struct Args {
130 #[arg(short, long)]
131 cable: String,
132 #[arg(short, long)]
133 baud: u32,
134 #[arg(short, long, default_value_t = 0)]
135 tap_index: usize,
137 #[arg(short, long, default_value_t = 0)]
138 ap_num: u32,
140 addr: Option<String>,
141}
142
143fn parse_int(x: &str) -> Result<u32, ParseIntError> {
144 if x.starts_with("0x") {
145 let len = x.len();
146 u32::from_str_radix(&x[2..len], 16)
147 } else {
148 str::parse(&x)
149 }
150}
151
152fn main() {
153 let args = Args::parse();
154 let cable = cable::new_from_string(&args.cable, args.baud).expect("cable");
155 let jtag = JtagSM::new(cable);
156 let mut taps = Taps::new(jtag);
157 taps.detect();
158
159 let ir = vec![14];
161 taps.select_tap(args.tap_index, &ir);
162 let dr = taps.read_dr(32);
163 let idcode = u32::from_le_bytes(dr.try_into().unwrap());
164 assert_eq!(idcode & 0xfff, 0x477);
165
166 let adi = Rc::new(RefCell::new(ArmDebugInterface::new(taps)));
167 let mut mem = MemAP::new(adi.clone(), args.ap_num);
168
169 let baseaddr = args.addr.map(|x| parse_int(&x)).unwrap_or(Ok(0)).expect("bad address");
170 parse_rom_table(&mut mem, baseaddr).expect("rom table");
171}