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