1use std::sync::Arc;
7
8use crate::architecture::arm::{
9 ArmCommunicationInterface, ArmDebugInterface, ArmError, DapError, RawDapAccess,
10 RegisterAddress,
11 communication_interface::DapProbe,
12 dp::{DpRegister, RdBuff},
13 sequences::ArmDebugSequence,
14};
15
16use super::{
17 DebugProbe, DebugProbeError, DebugProbeInfo, DebugProbeSelector, ProbeFactory, WireProtocol,
18 list::ProbeListItem,
19};
20
21mod mux;
22mod net;
23mod proto;
24mod usb;
25
26use mux::GlasgowDevice;
27use proto::Target;
28
29#[derive(Debug)]
31pub struct GlasgowFactory;
32
33impl std::fmt::Display for GlasgowFactory {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 f.write_str("Glasgow")
36 }
37}
38
39impl ProbeFactory for GlasgowFactory {
40 fn open(&self, selector: &DebugProbeSelector) -> Result<Box<dyn DebugProbe>, DebugProbeError> {
41 tracing::debug!("open({selector:?}");
42 Glasgow::new_from_device(GlasgowDevice::new_from_selector(selector)?)
43 .map(Box::new)
44 .map(DebugProbe::into_probe)
45 }
46
47 fn list_probes(&self) -> Vec<ProbeListItem> {
48 Vec::new()
52 }
53
54 fn list_probes_filtered(&self, selector: Option<&DebugProbeSelector>) -> Vec<ProbeListItem> {
55 if let Some(DebugProbeSelector {
58 vendor_id,
59 product_id,
60 serial_number: serial_number @ Some(_),
61 interface,
62 }) = selector
63 && *vendor_id == usb::VID_QIHW
64 && *product_id == usb::PID_GLASGOW
65 {
66 return vec![ProbeListItem::accessible(DebugProbeInfo {
69 identifier: "Glasgow".to_owned(),
70 vendor_id: *vendor_id,
71 product_id: *product_id,
72 serial_number: serial_number.clone(),
73 is_hid_interface: false,
74 probe_factory: &Self,
75 interface: *interface,
76 })];
77 }
78
79 vec![]
80 }
81}
82
83impl GlasgowDevice {
84 fn identify(&mut self) -> Result<(), DebugProbeError> {
85 self.send(Target::Root, &[proto::root::CMD_IDENTIFY]);
86 let identifier = self.recv(Target::Root, proto::root::IDENTIFIER.len())?;
87 let utf8_identifier = String::from_utf8_lossy(&identifier);
88 tracing::debug!("identify(): {utf8_identifier}");
89 if identifier == proto::root::IDENTIFIER {
90 Ok(())
91 } else {
92 Err(DebugProbeError::Other(format!(
93 "unsupported probe: {utf8_identifier:?}"
94 )))?
95 }
96 }
97
98 fn get_ref_clock(&mut self) -> Result<u32, DebugProbeError> {
99 self.send(Target::Root, &[proto::root::CMD_GET_REF_CLOCK]);
100 Ok(u32::from_le_bytes(
101 self.recv(Target::Root, 4)?.try_into().unwrap(),
102 ))
103 }
104
105 fn get_divisor(&mut self) -> Result<u16, DebugProbeError> {
106 self.send(Target::Root, &[proto::root::CMD_GET_DIVISOR]);
107 Ok(u16::from_le_bytes(
108 self.recv(Target::Root, 2)?.try_into().unwrap(),
109 ))
110 }
111
112 fn set_divisor(&mut self, divisor: u16) -> Result<(), DebugProbeError> {
113 self.send(Target::Root, &[proto::root::CMD_SET_DIVISOR]);
114 self.send(Target::Root, &u16::to_le_bytes(divisor));
115 Ok(())
116 }
117
118 fn assert_reset(&mut self) -> Result<(), DebugProbeError> {
119 self.send(Target::Root, &[proto::root::CMD_ASSERT_RESET]);
120 self.recv(Target::Root, 0)?;
121 Ok(())
122 }
123
124 fn clear_reset(&mut self) -> Result<(), DebugProbeError> {
125 self.send(Target::Root, &[proto::root::CMD_CLEAR_RESET]);
126 self.recv(Target::Root, 0)?;
127 Ok(())
128 }
129
130 fn swd_sequence(&mut self, len: u8, bits: u32) -> Result<(), DebugProbeError> {
131 assert!(len > 0 && len <= 32);
132 self.send(
133 Target::Swd,
134 &[proto::swd::CMD_SEQUENCE | (len & proto::swd::SEQ_LEN_MASK)],
135 );
136 self.send(Target::Swd, &bits.to_le_bytes()[..]);
137 self.recv(Target::Swd, 0)?;
138 Ok(())
139 }
140
141 fn swd_batch_cmd(&mut self, addr: RegisterAddress, data: Option<u32>) -> Result<(), ArmError> {
142 self.send(
143 Target::Swd,
144 &[proto::swd::CMD_TRANSFER
145 | (addr.is_ap() as u8)
146 | (data.is_none() as u8) << 1
147 | (addr.lsb() & 0b1100)],
148 );
149 if let Some(data) = data {
150 self.send(Target::Swd, &data.to_le_bytes()[..]);
151 }
152 Ok(())
153 }
154
155 fn swd_batch_ack(&mut self) -> Result<Option<u32>, ArmError> {
156 let response = self.recv(Target::Swd, 1)?[0];
157 if response & proto::swd::RSP_TYPE_MASK == proto::swd::RSP_TYPE_DATA {
158 Ok(Some(u32::from_le_bytes(
159 self.recv(Target::Swd, 4)?.try_into().unwrap(),
160 )))
161 } else if response & proto::swd::RSP_TYPE_MASK == proto::swd::RSP_TYPE_NO_DATA {
162 if response & proto::swd::RSP_ACK_MASK == proto::swd::RSP_ACK_OK {
163 Ok(None)
164 } else if response & proto::swd::RSP_ACK_MASK == proto::swd::RSP_ACK_WAIT {
165 Err(DapError::WaitResponse)?
166 } else if response & proto::swd::RSP_ACK_MASK == proto::swd::RSP_ACK_FAULT {
167 Err(DapError::FaultResponse)?
168 } else {
169 unreachable!()
170 }
171 } else if response & proto::swd::RSP_TYPE_MASK == proto::swd::RSP_TYPE_ERROR {
172 Err(DapError::Protocol(WireProtocol::Swd))?
173 } else {
174 unreachable!()
175 }
176 }
177}
178
179pub struct Glasgow {
181 device: GlasgowDevice,
182 ref_clock: u32,
183 divisor: u16,
184}
185
186impl std::fmt::Debug for Glasgow {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 f.debug_struct("Glasgow").finish()
189 }
190}
191
192impl Glasgow {
193 fn new_from_device(mut device: GlasgowDevice) -> Result<Self, DebugProbeError> {
194 device.identify()?;
195 let ref_clock = device.get_ref_clock()?;
196 Ok(Glasgow {
197 device,
198 ref_clock,
199 divisor: 0,
200 })
201 }
202}
203
204impl DebugProbe for Glasgow {
205 fn get_name(&self) -> &str {
206 "Glasgow Interface Explorer"
207 }
208
209 fn speed_khz(&self) -> u32 {
210 proto::root::divisor_to_frequency(self.ref_clock, self.divisor) / 1000
211 }
212
213 fn set_speed(&mut self, speed_khz: u32) -> Result<u32, DebugProbeError> {
214 tracing::debug!("set_speed({speed_khz})");
215 self.device.set_divisor(proto::root::frequency_to_divisor(
216 self.ref_clock,
217 speed_khz * 1000,
218 ))?;
219 self.divisor = self.device.get_divisor()?;
220 Ok(self.speed_khz())
221 }
222
223 fn attach(&mut self) -> Result<(), DebugProbeError> {
224 tracing::debug!("attach()");
225 Ok(())
226 }
227
228 fn detach(&mut self) -> Result<(), crate::Error> {
229 tracing::debug!("detach()");
230 Ok(())
231 }
232
233 fn target_reset(&mut self) -> Result<(), DebugProbeError> {
234 tracing::debug!("target_reset()");
235 Err(DebugProbeError::CommandNotSupportedByProbe {
236 command_name: "target_reset",
237 })
238 }
239
240 fn target_reset_assert(&mut self) -> Result<(), DebugProbeError> {
241 tracing::debug!("target_reset_assert()");
242 self.device.assert_reset()
243 }
244
245 fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError> {
246 tracing::debug!("target_reset_deassert()");
247 self.device.clear_reset()
248 }
249
250 fn active_protocol(&self) -> Option<super::WireProtocol> {
251 Some(WireProtocol::Swd)
252 }
253
254 fn select_protocol(&mut self, protocol: super::WireProtocol) -> Result<(), DebugProbeError> {
255 tracing::debug!("select_protocol({protocol})");
256 match protocol {
257 WireProtocol::Swd => Ok(()),
258 _ => Err(DebugProbeError::UnsupportedProtocol(protocol)),
259 }
260 }
261
262 fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
263 self
264 }
265
266 fn try_as_dap_probe(&mut self) -> Option<&mut dyn DapProbe> {
267 Some(self)
268 }
269
270 fn has_arm_interface(&self) -> bool {
271 true
272 }
273
274 fn try_get_arm_debug_interface<'probe>(
275 self: Box<Self>,
276 sequence: Arc<dyn ArmDebugSequence>,
277 ) -> Result<Box<dyn ArmDebugInterface + 'probe>, (Box<dyn DebugProbe>, ArmError)> {
278 Ok(ArmCommunicationInterface::create(
280 self, sequence, false,
281 ))
282 }
283}
284
285impl DapProbe for Glasgow {}
286
287impl RawDapAccess for Glasgow {
288 fn raw_read_register(&mut self, address: RegisterAddress) -> Result<u32, ArmError> {
289 if address.is_ap() {
290 let mut value = 0;
291 self.raw_read_block(address, std::slice::from_mut(&mut value))?;
292 Ok(value)
293 } else {
294 self.device.swd_batch_cmd(address, None)?;
295 let value = self.device.swd_batch_ack()?.expect("expected data");
296 tracing::debug!("raw_read_register({address:x?}) -> {value:x}");
297 Ok(value)
298 }
299 }
300
301 fn raw_read_block(
302 &mut self,
303 address: RegisterAddress,
304 values: &mut [u32],
305 ) -> Result<(), ArmError> {
306 assert!(address.is_ap());
307 for _ in 0..values.len() {
308 self.device.swd_batch_cmd(address, None)?;
309 }
310 self.device
311 .swd_batch_cmd(RegisterAddress::DpRegister(RdBuff::ADDRESS), None)?;
312 let _ = self.device.swd_batch_ack()?.expect("expected data");
313 for value in values.iter_mut() {
314 *value = self.device.swd_batch_ack()?.expect("expected data");
315 }
316 tracing::debug!(
317 "raw_read_block({address:x?}, {}) -> {values:x?}",
318 values.len()
319 );
320 Ok(())
321 }
322
323 fn raw_write_register(&mut self, address: RegisterAddress, value: u32) -> Result<(), ArmError> {
324 tracing::debug!("raw_write_register({address:x?}, {value:x})");
325 self.device.swd_batch_cmd(address, Some(value))?;
326 let response = self.device.swd_batch_ack()?;
327 assert!(response.is_none(), "unexpected data");
328 Ok(())
329 }
330
331 fn raw_write_block(
332 &mut self,
333 address: RegisterAddress,
334 values: &[u32],
335 ) -> Result<(), ArmError> {
336 tracing::debug!("raw_write_block({address:x?}, {values:x?})");
337 assert!(address.is_ap());
338 for value in values {
339 self.device.swd_batch_cmd(address, Some(*value))?;
340 }
341 for _ in 0..values.len() {
342 let response = self.device.swd_batch_ack()?;
343 assert!(response.is_none(), "unexpected data");
344 }
345 Ok(())
346 }
347
348 fn jtag_sequence(&mut self, cycles: u8, tms: bool, tdi: u64) -> Result<(), DebugProbeError> {
349 tracing::debug!("jtag_sequence({cycles}, {tms}, {tdi})");
350 Err(DebugProbeError::CommandNotSupportedByProbe {
351 command_name: "jtag_sequence",
352 })
353 }
354
355 fn swj_sequence(&mut self, len: u8, bits: u64) -> Result<(), DebugProbeError> {
356 tracing::debug!("swj_sequence({len}, {bits:#x})");
357 if len > 0 {
358 self.device.swd_sequence(len.min(32), bits as u32)?;
359 }
360 if len > 32 {
361 self.device.swd_sequence(len - 32, (bits >> 32) as u32)?;
362 }
363 Ok(())
364 }
365
366 fn swj_pins(
367 &mut self,
368 pin_out: u32,
369 pin_select: u32,
370 pin_wait: u32,
371 ) -> Result<u32, DebugProbeError> {
372 tracing::debug!("swj_pins({pin_out:#010b}, {pin_select:#010b}, {pin_wait:#010b})");
373 const PIN_NSRST: u32 = 0x80;
374 if pin_select != PIN_NSRST || pin_wait != 0 {
375 Err(DebugProbeError::CommandNotSupportedByProbe {
376 command_name: "swj_pins",
377 })
378 } else {
379 if pin_out & PIN_NSRST == 0 {
380 self.device.assert_reset()?;
381 } else {
382 self.device.clear_reset()?;
383 }
384 Ok(0xFFFF_FFFF)
386 }
387 }
388
389 fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
390 self
391 }
392
393 fn core_status_notification(
394 &mut self,
395 _state: crate::CoreStatus,
396 ) -> Result<(), DebugProbeError> {
397 Ok(())
398 }
399}