1use super::{
4 CortexAState,
5 instructions::aarch32::{
6 build_ldc, build_mcr, build_mov, build_mrc, build_mrs, build_msr, build_stc, build_vmov,
7 build_vmrs,
8 },
9 registers::{
10 aarch32::{
11 AARCH32_CORE_REGISTERS, AARCH32_WITH_FP_16_CORE_REGISTERS,
12 AARCH32_WITH_FP_32_CORE_REGISTERS,
13 },
14 cortex_m::{FP, PC, RA, SP},
15 },
16};
17use crate::{
18 Architecture, CoreInformation, CoreInterface, CoreRegister, CoreStatus, CoreType,
19 InstructionSet, MemoryInterface,
20 architecture::arm::{
21 ArmError, core::armv7a_debug_regs::*, memory::ArmMemoryInterface,
22 sequences::ArmDebugSequence,
23 },
24 core::{CoreRegisters, MemoryMappedRegister, RegisterId, RegisterValue},
25 error::Error,
26 memory::valid_32bit_address,
27};
28use std::{
29 mem::size_of,
30 sync::Arc,
31 time::{Duration, Instant},
32};
33
34#[derive(thiserror::Error, Debug)]
36pub enum Armv7aError {
37 #[error("Register number {0} is not valid for ARMv7-A")]
39 InvalidRegisterNumber(u16),
40
41 #[error("Core is running but operation requires it to be halted")]
43 NotHalted,
44
45 #[error("A data abort occurred")]
47 DataAbort,
48}
49
50pub struct Armv7a<'probe> {
52 memory: Box<dyn ArmMemoryInterface + 'probe>,
53
54 state: &'probe mut CortexAState,
55
56 base_address: u64,
57
58 sequence: Arc<dyn ArmDebugSequence>,
59
60 num_breakpoints: Option<u32>,
61
62 itr_enabled: bool,
63}
64
65impl<'probe> Armv7a<'probe> {
66 pub(crate) fn new(
67 mut memory: Box<dyn ArmMemoryInterface + 'probe>,
68 state: &'probe mut CortexAState,
69 base_address: u64,
70 sequence: Arc<dyn ArmDebugSequence>,
71 ) -> Result<Self, Error> {
72 if !state.initialized() {
73 let address = Dbgdscr::get_mmio_address_from_base(base_address)?;
75 let dbgdscr = Dbgdscr(memory.read_word_32(address)?);
76
77 tracing::debug!("State when connecting: {:x?}", dbgdscr);
78
79 let core_state = if dbgdscr.halted() {
80 let reason = dbgdscr.halt_reason();
81
82 tracing::debug!("Core was halted when connecting, reason: {:?}", reason);
83
84 CoreStatus::Halted(reason)
85 } else {
86 CoreStatus::Running
87 };
88
89 state.current_state = core_state;
90 }
91
92 let mut core = Self {
93 memory,
94 state,
95 base_address,
96 sequence,
97 num_breakpoints: None,
98 itr_enabled: false,
99 };
100
101 if !core.state.initialized() {
102 core.reset_register_cache();
103 core.read_fp_reg_count()?;
104 core.state.initialize();
105 }
106
107 Ok(core)
108 }
109
110 fn read_fp_reg_count(&mut self) -> Result<(), Error> {
111 if self.state.fp_reg_count == 0 && matches!(self.state.current_state, CoreStatus::Halted(_))
112 {
113 self.prepare_r0_for_clobber()?;
114
115 let instruction = build_vmrs(0, 0b0111);
117 self.execute_instruction(instruction)?;
118
119 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
121 let vmrs = self.execute_instruction_with_result(instruction)?;
122
123 self.state.fp_reg_count = match vmrs & 0b111 {
124 0b001 => 16,
125 0b010 => 32,
126 _ => 0,
127 };
128 }
129
130 Ok(())
131 }
132
133 fn execute_instruction(&mut self, instruction: u32) -> Result<Dbgdscr, ArmError> {
135 if !self.state.current_state.is_halted() {
136 return Err(ArmError::CoreNotHalted);
137 }
138
139 if !self.itr_enabled {
141 let address = Dbgdscr::get_mmio_address_from_base(self.base_address)?;
142 let mut dbgdscr = Dbgdscr(self.memory.read_word_32(address)?);
143 dbgdscr.set_itren(true);
144
145 self.memory.write_word_32(address, dbgdscr.into())?;
146
147 self.itr_enabled = true;
148 }
149
150 execute_instruction(&mut *self.memory, self.base_address, instruction)
151 }
152
153 fn execute_instruction_with_result(&mut self, instruction: u32) -> Result<u32, Error> {
155 let mut dbgdscr = self.execute_instruction(instruction)?;
157
158 while !dbgdscr.txfull_l() {
160 let address = Dbgdscr::get_mmio_address_from_base(self.base_address)?;
161 dbgdscr = Dbgdscr(self.memory.read_word_32(address)?);
162 }
163
164 let address = Dbgdtrtx::get_mmio_address_from_base(self.base_address)?;
166 let result = self.memory.read_word_32(address)?;
167
168 Ok(result)
169 }
170
171 fn execute_instruction_with_input(
172 &mut self,
173 instruction: u32,
174 value: u32,
175 ) -> Result<(), Error> {
176 let address = Dbgdtrrx::get_mmio_address_from_base(self.base_address)?;
178 self.memory.write_word_32(address, value)?;
179
180 let address = Dbgdscr::get_mmio_address_from_base(self.base_address)?;
182 let mut dbgdscr = Dbgdscr(self.memory.read_word_32(address)?);
183
184 while !dbgdscr.rxfull_l() {
185 dbgdscr = Dbgdscr(self.memory.read_word_32(address)?);
186 }
187
188 self.execute_instruction(instruction)?;
190
191 Ok(())
192 }
193
194 fn reset_register_cache(&mut self) {
195 self.state.register_cache = vec![None; 51];
196 }
197
198 fn writeback_registers(&mut self) -> Result<(), Error> {
200 let writeback_iter = (17u16..=48).chain(15u16..=16).chain(0u16..=14);
201
202 for i in writeback_iter {
203 if let Some((val, writeback)) = self.state.register_cache[i as usize] {
204 if writeback {
205 match i {
206 0..=14 => {
207 let instruction = build_mrc(14, 0, i, 0, 5, 0);
208
209 self.execute_instruction_with_input(instruction, val.try_into()?)?;
210 }
211 15 => {
212 let instruction = build_mrc(14, 0, 0, 0, 5, 0);
214
215 self.execute_instruction_with_input(instruction, val.try_into()?)?;
216
217 let instruction = build_mov(15, 0);
221 self.execute_instruction(instruction)?;
222 }
223 16 => {
224 let instruction = build_msr(0);
226 self.execute_instruction_with_input(instruction, val.try_into()?)?;
227 }
228 17..=48 => {
229 let value: u64 = val.try_into()?;
231 let low_word = value as u32;
232 let high_word = (value >> 32) as u32;
233
234 let instruction = build_mrc(14, 0, 0, 0, 5, 0);
235 self.execute_instruction_with_input(instruction, low_word)?;
236
237 let instruction = build_mrc(14, 0, 1, 0, 5, 0);
238 self.execute_instruction_with_input(instruction, high_word)?;
239
240 let instruction = build_vmov(0, 0, 1, i - 17);
242 self.execute_instruction(instruction)?;
243 }
244 _ => {
245 panic!("Logic missing for writeback of register {i}");
246 }
247 }
248 }
249 }
250 }
251
252 self.reset_register_cache();
253
254 Ok(())
255 }
256
257 fn prepare_r0_for_clobber(&mut self) -> Result<(), Error> {
259 self.prepare_for_clobber(0)
260 }
261
262 fn prepare_for_clobber(&mut self, reg: usize) -> Result<(), Error> {
264 if self.state.register_cache[reg].is_none() {
265 let val: u32 = self.read_core_reg(RegisterId(reg as u16))?.try_into()?;
267
268 self.state.register_cache[reg] = Some((val.into(), true));
270 }
271
272 Ok(())
273 }
274
275 fn set_r0(&mut self, value: u32) -> Result<(), Error> {
276 let instruction = build_mrc(14, 0, 0, 0, 5, 0);
277
278 self.execute_instruction_with_input(instruction, value)
279 }
280
281 fn set_core_status(&mut self, new_status: CoreStatus) {
282 super::update_core_status(&mut self.memory, &mut self.state.current_state, new_status);
283 }
284
285 pub(crate) fn halted_access<R>(
286 &mut self,
287 op: impl FnOnce(&mut Self) -> Result<R, Error>,
288 ) -> Result<R, Error> {
289 let was_running = !(self.state.current_state.is_halted() || self.status()?.is_halted());
290
291 if was_running {
292 self.halt(Duration::from_millis(100))?;
293 }
294
295 let result = op(self);
296
297 if was_running {
298 self.run()?
299 }
300
301 result
302 }
303}
304
305pub(crate) fn request_halt(
310 memory: &mut dyn ArmMemoryInterface,
311 base_address: u64,
312) -> Result<(), ArmError> {
313 let address = Dbgdrcr::get_mmio_address_from_base(base_address)?;
314 let mut value = Dbgdrcr(0);
315 value.set_hrq(true);
316
317 memory.write_word_32(address, value.into())?;
318 Ok(())
319}
320
321pub(crate) fn run(memory: &mut dyn ArmMemoryInterface, base_address: u64) -> Result<(), ArmError> {
323 let address = Dbgdrcr::get_mmio_address_from_base(base_address)?;
324 let mut value = Dbgdrcr(0);
325 value.set_rrq(true);
326
327 memory.write_word_32(address, value.into())?;
328
329 let address = Dbgdscr::get_mmio_address_from_base(base_address)?;
331
332 loop {
333 let dbgdscr = Dbgdscr(memory.read_word_32(address)?);
334 if dbgdscr.restarted() {
335 return Ok(());
336 }
337 }
338}
339
340pub(crate) fn wait_for_core_halted(
343 memory: &mut dyn ArmMemoryInterface,
344 base_address: u64,
345 timeout: Duration,
346) -> Result<(), ArmError> {
347 let start = Instant::now();
349
350 while !core_halted(memory, base_address)? {
351 if start.elapsed() >= timeout {
352 return Err(ArmError::Timeout);
353 }
354 std::thread::sleep(Duration::from_millis(1));
356 }
357
358 Ok(())
359}
360
361fn core_halted(memory: &mut dyn ArmMemoryInterface, base_address: u64) -> Result<bool, ArmError> {
363 let address = Dbgdscr::get_mmio_address_from_base(base_address)?;
364 let dbgdscr = Dbgdscr(memory.read_word_32(address)?);
365
366 Ok(dbgdscr.halted())
367}
368
369pub(crate) fn set_hw_breakpoint(
372 memory: &mut dyn ArmMemoryInterface,
373 base_address: u64,
374 bp_unit_index: usize,
375 addr: u32,
376) -> Result<(), ArmError> {
377 let bp_value_addr = Dbgbvr::get_mmio_address_from_base(base_address)?
378 + (bp_unit_index * size_of::<u32>()) as u64;
379 let bp_control_addr = Dbgbcr::get_mmio_address_from_base(base_address)?
380 + (bp_unit_index * size_of::<u32>()) as u64;
381 let mut bp_control = Dbgbcr(0);
382
383 bp_control.set_bt(0b0000);
385 bp_control.set_hmc(true);
387 bp_control.set_pmc(0b11);
388 bp_control.set_bas(0b1111);
390 bp_control.set_e(true);
392
393 memory.write_word_32(bp_value_addr, addr)?;
394 memory.write_word_32(bp_control_addr, bp_control.into())?;
395
396 Ok(())
397}
398
399pub(crate) fn clear_hw_breakpoint(
401 memory: &mut dyn ArmMemoryInterface,
402 base_address: u64,
403 bp_unit_index: usize,
404) -> Result<(), ArmError> {
405 let bp_value_addr = Dbgbvr::get_mmio_address_from_base(base_address)?
406 + (bp_unit_index * size_of::<u32>()) as u64;
407 let bp_control_addr = Dbgbcr::get_mmio_address_from_base(base_address)?
408 + (bp_unit_index * size_of::<u32>()) as u64;
409
410 memory.write_word_32(bp_value_addr, 0)?;
411 memory.write_word_32(bp_control_addr, 0)?;
412 Ok(())
413}
414
415pub(crate) fn get_hw_breakpoint(
417 memory: &mut dyn ArmMemoryInterface,
418 base_address: u64,
419 bp_unit_index: usize,
420) -> Result<Option<u32>, ArmError> {
421 let bp_value_addr = Dbgbvr::get_mmio_address_from_base(base_address)?
422 + (bp_unit_index * size_of::<u32>()) as u64;
423 let bp_value = memory.read_word_32(bp_value_addr)?;
424
425 let bp_control_addr = Dbgbcr::get_mmio_address_from_base(base_address)?
426 + (bp_unit_index * size_of::<u32>()) as u64;
427 let bp_control = Dbgbcr(memory.read_word_32(bp_control_addr)?);
428
429 Ok(if bp_control.e() { Some(bp_value) } else { None })
430}
431
432fn execute_instruction(
434 memory: &mut dyn ArmMemoryInterface,
435 base_address: u64,
436 instruction: u32,
437) -> Result<Dbgdscr, ArmError> {
438 let address = Dbgitr::get_mmio_address_from_base(base_address)?;
440 memory.write_word_32(address, instruction)?;
441
442 let address = Dbgdscr::get_mmio_address_from_base(base_address)?;
444 let mut dbgdscr = Dbgdscr(memory.read_word_32(address)?);
445
446 while !dbgdscr.instrcoml_l() {
447 dbgdscr = Dbgdscr(memory.read_word_32(address)?);
448 }
449
450 if dbgdscr.adabort_l() || dbgdscr.sdabort_l() {
452 let address = Dbgdrcr::get_mmio_address_from_base(base_address)?;
453 let mut dbgdrcr = Dbgdrcr(0);
454 dbgdrcr.set_cse(true);
455
456 memory.write_word_32(address, dbgdrcr.into())?;
457 return Err(ArmError::Armv7a(
458 crate::architecture::arm::armv7a::Armv7aError::DataAbort,
459 ));
460 }
461
462 Ok(dbgdscr)
463}
464
465fn set_instruction_input(
468 memory: &mut dyn ArmMemoryInterface,
469 base_address: u64,
470 value: u32,
471) -> Result<(), ArmError> {
472 let address = Dbgdtrrx::get_mmio_address_from_base(base_address)?;
474 memory.write_word_32(address, value)?;
475
476 let address = Dbgdscr::get_mmio_address_from_base(base_address)?;
478 let mut dbgdscr = Dbgdscr(memory.read_word_32(address)?);
479
480 while !dbgdscr.rxfull_l() {
481 dbgdscr = Dbgdscr(memory.read_word_32(address)?);
482 }
483 Ok(())
484}
485
486fn get_instruction_result(
489 memory: &mut dyn ArmMemoryInterface,
490 base_address: u64,
491) -> Result<u32, ArmError> {
492 let address = Dbgdscr::get_mmio_address_from_base(base_address)?;
494 loop {
495 let dbgdscr = Dbgdscr(memory.read_word_32(address)?);
496 if dbgdscr.txfull_l() {
497 break;
498 }
499 }
500
501 let address = Dbgdtrtx::get_mmio_address_from_base(base_address)?;
503 memory.read_word_32(address)
504}
505
506pub(crate) fn write_word_32(
509 memory: &mut dyn ArmMemoryInterface,
510 base_address: u64,
511 address: u32,
512 data: u32,
513) -> Result<(), ArmError> {
514 set_instruction_input(memory, base_address, address)?;
516 execute_instruction(memory, base_address, build_mrc(14, 0, 0, 0, 5, 0))?;
517
518 set_instruction_input(memory, base_address, data)?;
521 execute_instruction(memory, base_address, build_stc(14, 5, 0, 4))?;
522 Ok(())
523}
524
525pub(crate) fn read_word_32(
528 memory: &mut dyn ArmMemoryInterface,
529 base_address: u64,
530 address: u32,
531) -> Result<u32, ArmError> {
532 set_instruction_input(memory, base_address, address)?;
534 execute_instruction(memory, base_address, build_mrc(14, 0, 0, 0, 5, 0))?;
535
536 execute_instruction(memory, base_address, build_ldc(14, 5, 0, 4))?;
539 get_instruction_result(memory, base_address)
540}
541
542impl CoreInterface for Armv7a<'_> {
543 fn wait_for_core_halted(&mut self, timeout: Duration) -> Result<(), Error> {
544 wait_for_core_halted(&mut *self.memory, self.base_address, timeout).map_err(|e| e.into())
545 }
546
547 fn core_halted(&mut self) -> Result<bool, Error> {
548 core_halted(&mut *self.memory, self.base_address).map_err(|e| e.into())
549 }
550
551 fn status(&mut self) -> Result<crate::core::CoreStatus, Error> {
552 let address = Dbgdscr::get_mmio_address_from_base(self.base_address)?;
554 let dbgdscr = Dbgdscr(self.memory.read_word_32(address)?);
555
556 if dbgdscr.halted() {
557 let reason = dbgdscr.halt_reason();
558
559 self.set_core_status(CoreStatus::Halted(reason));
560
561 self.read_fp_reg_count()?;
562
563 return Ok(CoreStatus::Halted(reason));
564 }
565 if self.state.current_state.is_halted() {
567 tracing::warn!("Core is running, but we expected it to be halted");
568 }
569
570 self.set_core_status(CoreStatus::Running);
571
572 Ok(CoreStatus::Running)
573 }
574
575 fn halt(&mut self, timeout: Duration) -> Result<CoreInformation, Error> {
576 if !matches!(self.state.current_state, CoreStatus::Halted(_)) {
577 request_halt(&mut *self.memory, self.base_address)?;
578 self.wait_for_core_halted(timeout)?;
579
580 self.reset_register_cache();
582 }
583 let _ = self.status()?;
585
586 let pc_value = self.read_core_reg(self.program_counter().into())?;
588
589 Ok(CoreInformation {
591 pc: pc_value.try_into()?,
592 })
593 }
594
595 fn run(&mut self) -> Result<(), Error> {
596 if matches!(self.state.current_state, CoreStatus::Running) {
597 return Ok(());
598 }
599
600 self.writeback_registers()?;
602
603 run(&mut *self.memory, self.base_address)?;
604
605 self.set_core_status(CoreStatus::Running);
607 let _ = self.status()?;
608
609 Ok(())
610 }
611
612 fn reset(&mut self) -> Result<(), Error> {
613 self.sequence.reset_system(
614 &mut *self.memory,
615 crate::CoreType::Armv7a,
616 Some(self.base_address),
617 )?;
618
619 self.reset_register_cache();
621
622 Ok(())
623 }
624
625 fn reset_and_halt(&mut self, timeout: Duration) -> Result<CoreInformation, Error> {
626 self.sequence.reset_catch_set(
627 &mut *self.memory,
628 crate::CoreType::Armv7a,
629 Some(self.base_address),
630 )?;
631 self.sequence.reset_system(
632 &mut *self.memory,
633 crate::CoreType::Armv7a,
634 Some(self.base_address),
635 )?;
636
637 let address = Dbgdrcr::get_mmio_address_from_base(self.base_address)?;
639 let mut value = Dbgdrcr(0);
640 value.set_hrq(true);
641
642 self.memory.write_word_32(address, value.into())?;
643
644 self.sequence.reset_catch_clear(
646 &mut *self.memory,
647 crate::CoreType::Armv7a,
648 Some(self.base_address),
649 )?;
650
651 self.wait_for_core_halted(timeout)?;
652
653 let _ = self.status()?;
655
656 self.reset_register_cache();
658
659 let pc_value = self.read_core_reg(self.program_counter().into())?;
661
662 Ok(CoreInformation {
664 pc: pc_value.try_into()?,
665 })
666 }
667
668 fn step(&mut self) -> Result<CoreInformation, Error> {
669 let bp_unit_index = (self.available_breakpoint_units()? - 1) as usize;
671 let bp_value_addr = Dbgbvr::get_mmio_address_from_base(self.base_address)?
672 + (bp_unit_index * size_of::<u32>()) as u64;
673 let saved_bp_value = self.memory.read_word_32(bp_value_addr)?;
674
675 let bp_control_addr = Dbgbcr::get_mmio_address_from_base(self.base_address)?
676 + (bp_unit_index * size_of::<u32>()) as u64;
677 let saved_bp_control = self.memory.read_word_32(bp_control_addr)?;
678
679 let current_pc: u32 = self
681 .read_core_reg(self.program_counter().into())?
682 .try_into()?;
683 let mut bp_control = Dbgbcr(0);
684
685 bp_control.set_bt(0b0100);
687 bp_control.set_hmc(true);
689 bp_control.set_pmc(0b11);
690 bp_control.set_bas(0b1111);
692 bp_control.set_e(true);
694
695 self.memory.write_word_32(bp_value_addr, current_pc)?;
696 self.memory
697 .write_word_32(bp_control_addr, bp_control.into())?;
698
699 self.run()?;
701
702 self.wait_for_core_halted(Duration::from_millis(100))?;
704
705 self.memory.write_word_32(bp_value_addr, saved_bp_value)?;
707 self.memory
708 .write_word_32(bp_control_addr, saved_bp_control)?;
709
710 let pc_value = self.read_core_reg(self.program_counter().into())?;
712
713 Ok(CoreInformation {
715 pc: pc_value.try_into()?,
716 })
717 }
718
719 fn read_core_reg(&mut self, address: RegisterId) -> Result<RegisterValue, Error> {
720 let reg_num = address.0;
721
722 if (reg_num as usize) < self.state.register_cache.len() {
724 if let Some(cached_result) = self.state.register_cache[reg_num as usize] {
725 return Ok(cached_result.0);
726 }
727 }
728
729 let result: Result<RegisterValue, Error> = match reg_num {
731 0..=14 => {
732 let instruction = build_mcr(14, 0, reg_num, 0, 5, 0);
735
736 let val = self.execute_instruction_with_result(instruction)?;
737
738 Ok(val.into())
739 }
740 15 => {
741 self.prepare_r0_for_clobber()?;
743
744 let instruction = build_mov(0, 15);
746 self.execute_instruction(instruction)?;
747
748 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
750 let pra_plus_offset = self.execute_instruction_with_result(instruction)?;
751
752 Ok((pra_plus_offset - 8).into())
754 }
755 16 => {
756 self.prepare_r0_for_clobber()?;
758
759 let instruction = build_mrs(0);
761 self.execute_instruction(instruction)?;
762
763 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
765 let cpsr = self.execute_instruction_with_result(instruction)?;
766
767 Ok(cpsr.into())
768 }
769 17..=48 => {
770 self.prepare_for_clobber(0)?;
772 self.prepare_for_clobber(1)?;
773
774 let fpexc: u32 = self.read_core_reg(50.into())?.try_into()?;
776 if (fpexc & (1 << 30)) == 0 {
777 return Ok(0u32.into());
779 }
780
781 let instruction = build_vmov(1, 0, 1, reg_num - 17);
783 self.execute_instruction(instruction)?;
784
785 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
787 let mut value = self.execute_instruction_with_result(instruction)? as u64;
788
789 let instruction = build_mcr(14, 0, 1, 0, 5, 0);
791 value |= (self.execute_instruction_with_result(instruction)? as u64) << 32;
792
793 Ok(value.into())
794 }
795 49 => {
796 self.prepare_for_clobber(0)?;
798
799 let fpexc: u32 = self.read_core_reg(50.into())?.try_into()?;
801 if (fpexc & (1 << 30)) == 0 {
802 return Ok(0u32.into());
804 }
805
806 let instruction = build_vmrs(0, 1);
808 self.execute_instruction(instruction)?;
809
810 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
812 let value = self.execute_instruction_with_result(instruction)?;
813
814 Ok(value.into())
815 }
816 50 => {
817 self.prepare_for_clobber(0)?;
819
820 let instruction = build_vmrs(0, 0b1000);
822 self.execute_instruction(instruction)?;
823
824 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
825 let value = self.execute_instruction_with_result(instruction)?;
826
827 Ok(value.into())
828 }
829 _ => Err(Error::Arm(
830 Armv7aError::InvalidRegisterNumber(reg_num).into(),
831 )),
832 };
833
834 if let Ok(value) = result {
835 self.state.register_cache[reg_num as usize] = Some((value, false));
836
837 Ok(value)
838 } else {
839 Err(result.err().unwrap())
840 }
841 }
842
843 fn write_core_reg(&mut self, address: RegisterId, value: RegisterValue) -> Result<(), Error> {
844 let reg_num = address.0;
845
846 if (reg_num as usize) >= self.state.register_cache.len() {
847 return Err(Error::Arm(
848 Armv7aError::InvalidRegisterNumber(reg_num).into(),
849 ));
850 }
851 self.state.register_cache[reg_num as usize] = Some((value, true));
852
853 Ok(())
854 }
855
856 fn available_breakpoint_units(&mut self) -> Result<u32, Error> {
857 if self.num_breakpoints.is_none() {
858 let address = Dbgdidr::get_mmio_address_from_base(self.base_address)?;
859 let dbgdidr = Dbgdidr(self.memory.read_word_32(address)?);
860
861 self.num_breakpoints = Some(dbgdidr.brps() + 1);
862 }
863 Ok(self.num_breakpoints.unwrap())
864 }
865
866 fn hw_breakpoints(&mut self) -> Result<Vec<Option<u64>>, Error> {
868 let mut breakpoints = vec![];
869 let num_hw_breakpoints = self.available_breakpoint_units()? as usize;
870
871 for bp_unit_index in 0..num_hw_breakpoints {
872 let bp_value_addr = Dbgbvr::get_mmio_address_from_base(self.base_address)?
873 + (bp_unit_index * size_of::<u32>()) as u64;
874 let bp_value = self.memory.read_word_32(bp_value_addr)?;
875
876 let bp_control_addr = Dbgbcr::get_mmio_address_from_base(self.base_address)?
877 + (bp_unit_index * size_of::<u32>()) as u64;
878 let bp_control = Dbgbcr(self.memory.read_word_32(bp_control_addr)?);
879
880 if bp_control.e() {
881 breakpoints.push(Some(bp_value as u64));
882 } else {
883 breakpoints.push(None);
884 }
885 }
886 Ok(breakpoints)
887 }
888
889 fn enable_breakpoints(&mut self, _state: bool) -> Result<(), Error> {
890 Ok(())
892 }
893
894 fn set_hw_breakpoint(&mut self, bp_unit_index: usize, addr: u64) -> Result<(), Error> {
895 let addr = valid_32bit_address(addr)?;
896 set_hw_breakpoint(&mut *self.memory, self.base_address, bp_unit_index, addr)?;
897 Ok(())
898 }
899
900 fn clear_hw_breakpoint(&mut self, bp_unit_index: usize) -> Result<(), Error> {
901 clear_hw_breakpoint(&mut *self.memory, self.base_address, bp_unit_index)?;
902 Ok(())
903 }
904
905 fn registers(&self) -> &'static CoreRegisters {
906 match self.state.fp_reg_count {
907 16 => &AARCH32_WITH_FP_16_CORE_REGISTERS,
908 32 => &AARCH32_WITH_FP_32_CORE_REGISTERS,
909 _ => &AARCH32_CORE_REGISTERS,
910 }
911 }
912
913 fn program_counter(&self) -> &'static CoreRegister {
914 &PC
915 }
916
917 fn frame_pointer(&self) -> &'static CoreRegister {
918 &FP
919 }
920
921 fn stack_pointer(&self) -> &'static CoreRegister {
922 &SP
923 }
924
925 fn return_address(&self) -> &'static CoreRegister {
926 &RA
927 }
928
929 fn hw_breakpoints_enabled(&self) -> bool {
930 true
931 }
932
933 fn architecture(&self) -> Architecture {
934 Architecture::Arm
935 }
936
937 fn core_type(&self) -> CoreType {
938 CoreType::Armv7a
939 }
940
941 fn instruction_set(&mut self) -> Result<InstructionSet, Error> {
942 let cpsr: u32 = self.read_core_reg(RegisterId(16))?.try_into()?;
943
944 match (cpsr >> 5) & 1 {
946 1 => Ok(InstructionSet::Thumb2),
947 _ => Ok(InstructionSet::A32),
948 }
949 }
950
951 fn fpu_support(&mut self) -> Result<bool, Error> {
952 Ok(self.state.fp_reg_count != 0)
953 }
954
955 fn floating_point_register_count(&mut self) -> Result<usize, Error> {
956 Ok(self.state.fp_reg_count)
957 }
958
959 #[tracing::instrument(skip(self))]
960 fn reset_catch_set(&mut self) -> Result<(), Error> {
961 self.halted_access(|core| {
962 core.sequence.reset_catch_set(
963 &mut *core.memory,
964 CoreType::Armv7a,
965 Some(core.base_address),
966 )?;
967 Ok(())
968 })?;
969 Ok(())
970 }
971
972 #[tracing::instrument(skip(self))]
973 fn reset_catch_clear(&mut self) -> Result<(), Error> {
974 self.halted_access(|core| {
976 core.sequence.reset_catch_clear(
977 &mut *core.memory,
978 CoreType::Armv7a,
979 Some(core.base_address),
980 )?;
981 Ok(())
982 })?;
983 Ok(())
984 }
985
986 #[tracing::instrument(skip(self))]
987 fn debug_core_stop(&mut self) -> Result<(), Error> {
988 if matches!(self.state.current_state, CoreStatus::Halted(_)) {
989 self.writeback_registers()?;
992 }
993
994 self.sequence
995 .debug_core_stop(&mut *self.memory, CoreType::Armv7a)?;
996
997 Ok(())
998 }
999}
1000
1001impl MemoryInterface for Armv7a<'_> {
1002 fn supports_native_64bit_access(&mut self) -> bool {
1003 false
1004 }
1005
1006 fn read_word_64(&mut self, address: u64) -> Result<u64, Error> {
1007 self.halted_access(|core| {
1008 let mut ret: u64 = core.read_word_32(address)? as u64;
1009 ret |= (core.read_word_32(address + 4)? as u64) << 32;
1010
1011 Ok(ret)
1012 })
1013 }
1014
1015 fn read_word_32(&mut self, address: u64) -> Result<u32, Error> {
1016 self.halted_access(|core| {
1017 let address = valid_32bit_address(address)?;
1018
1019 let instr = build_ldc(14, 5, 0, 4);
1021
1022 core.prepare_r0_for_clobber()?;
1024
1025 core.set_r0(address)?;
1027
1028 core.execute_instruction_with_result(instr)
1030 })
1031 }
1032
1033 fn read_word_16(&mut self, address: u64) -> Result<u16, Error> {
1034 self.halted_access(|core| {
1035 let byte_offset = address % 4;
1037 let word_start = address - byte_offset;
1038
1039 let data = core.read_word_32(word_start)?;
1041
1042 Ok((data >> (byte_offset * 8)) as u16)
1044 })
1045 }
1046
1047 fn read_word_8(&mut self, address: u64) -> Result<u8, Error> {
1048 self.halted_access(|core| {
1049 let byte_offset = address % 4;
1051 let word_start = address - byte_offset;
1052
1053 let data = core.read_word_32(word_start)?;
1055
1056 Ok(data.to_le_bytes()[byte_offset as usize])
1058 })
1059 }
1060
1061 fn read_64(&mut self, address: u64, data: &mut [u64]) -> Result<(), Error> {
1062 self.halted_access(|core| {
1063 for (i, word) in data.iter_mut().enumerate() {
1064 *word = core.read_word_64(address + ((i as u64) * 8))?;
1065 }
1066
1067 Ok(())
1068 })
1069 }
1070
1071 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), Error> {
1072 self.halted_access(|core| {
1073 for (i, word) in data.iter_mut().enumerate() {
1074 *word = core.read_word_32(address + ((i as u64) * 4))?;
1075 }
1076
1077 Ok(())
1078 })
1079 }
1080
1081 fn read_16(&mut self, address: u64, data: &mut [u16]) -> Result<(), Error> {
1082 self.halted_access(|core| {
1083 for (i, word) in data.iter_mut().enumerate() {
1084 *word = core.read_word_16(address + ((i as u64) * 2))?;
1085 }
1086
1087 Ok(())
1088 })
1089 }
1090
1091 fn read_8(&mut self, address: u64, data: &mut [u8]) -> Result<(), Error> {
1092 self.halted_access(|core| {
1093 for (i, byte) in data.iter_mut().enumerate() {
1094 *byte = core.read_word_8(address + (i as u64))?;
1095 }
1096
1097 Ok(())
1098 })
1099 }
1100
1101 fn write_word_64(&mut self, address: u64, data: u64) -> Result<(), Error> {
1102 self.halted_access(|core| {
1103 let data_low = data as u32;
1104 let data_high = (data >> 32) as u32;
1105
1106 core.write_word_32(address, data_low)?;
1107 core.write_word_32(address + 4, data_high)
1108 })
1109 }
1110
1111 fn write_word_32(&mut self, address: u64, data: u32) -> Result<(), Error> {
1112 self.halted_access(|core| {
1113 let address = valid_32bit_address(address)?;
1114
1115 let instr = build_stc(14, 5, 0, 4);
1117
1118 core.prepare_r0_for_clobber()?;
1120
1121 core.set_r0(address)?;
1123
1124 core.execute_instruction_with_input(instr, data)
1126 })
1127 }
1128
1129 fn write_word_8(&mut self, address: u64, data: u8) -> Result<(), Error> {
1130 self.halted_access(|core| {
1131 let byte_offset = address % 4;
1133 let word_start = address - byte_offset;
1134
1135 let current_word = core.read_word_32(word_start)?;
1137 let mut word_bytes = current_word.to_le_bytes();
1138 word_bytes[byte_offset as usize] = data;
1139
1140 core.write_word_32(word_start, u32::from_le_bytes(word_bytes))
1141 })
1142 }
1143
1144 fn write_word_16(&mut self, address: u64, data: u16) -> Result<(), Error> {
1145 self.halted_access(|core| {
1146 let byte_offset = address % 4;
1148 let word_start = address - byte_offset;
1149
1150 let mut word = core.read_word_32(word_start)?;
1152
1153 word &= !(0xFFFFu32 << (byte_offset * 8));
1155 word |= (data as u32) << (byte_offset * 8);
1156
1157 core.write_word_32(word_start, word)
1158 })
1159 }
1160
1161 fn write_64(&mut self, address: u64, data: &[u64]) -> Result<(), Error> {
1162 self.halted_access(|core| {
1163 for (i, word) in data.iter().enumerate() {
1164 core.write_word_64(address + ((i as u64) * 8), *word)?;
1165 }
1166
1167 Ok(())
1168 })
1169 }
1170
1171 fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), Error> {
1172 self.halted_access(|core| {
1173 for (i, word) in data.iter().enumerate() {
1174 core.write_word_32(address + ((i as u64) * 4), *word)?;
1175 }
1176
1177 Ok(())
1178 })
1179 }
1180
1181 fn write_16(&mut self, address: u64, data: &[u16]) -> Result<(), Error> {
1182 self.halted_access(|core| {
1183 for (i, word) in data.iter().enumerate() {
1184 core.write_word_16(address + ((i as u64) * 2), *word)?;
1185 }
1186
1187 Ok(())
1188 })
1189 }
1190
1191 fn write_8(&mut self, address: u64, data: &[u8]) -> Result<(), Error> {
1192 self.halted_access(|core| {
1193 for (i, byte) in data.iter().enumerate() {
1194 core.write_word_8(address + (i as u64), *byte)?;
1195 }
1196
1197 Ok(())
1198 })
1199 }
1200
1201 fn supports_8bit_transfers(&self) -> Result<bool, Error> {
1202 Ok(false)
1203 }
1204
1205 fn flush(&mut self) -> Result<(), Error> {
1206 Ok(())
1208 }
1209}
1210
1211#[cfg(test)]
1212mod test {
1213 use crate::{
1214 architecture::arm::{
1215 FullyQualifiedApAddress, communication_interface::SwdSequence,
1216 sequences::DefaultArmSequence,
1217 },
1218 probe::DebugProbeError,
1219 };
1220
1221 use super::*;
1222
1223 const TEST_BASE_ADDRESS: u64 = 0x8000_1000;
1224
1225 fn address_to_reg_num(address: u64) -> u32 {
1226 ((address - TEST_BASE_ADDRESS) / 4) as u32
1227 }
1228
1229 pub struct ExpectedMemoryOp {
1230 read: bool,
1231 address: u64,
1232 value: u32,
1233 }
1234
1235 pub struct MockProbe {
1236 expected_ops: Vec<ExpectedMemoryOp>,
1237 }
1238
1239 impl MockProbe {
1240 pub fn new() -> Self {
1241 MockProbe {
1242 expected_ops: vec![],
1243 }
1244 }
1245
1246 pub fn expected_read(&mut self, addr: u64, value: u32) {
1247 self.expected_ops.push(ExpectedMemoryOp {
1248 read: true,
1249 address: addr,
1250 value,
1251 });
1252 }
1253
1254 pub fn expected_write(&mut self, addr: u64, value: u32) {
1255 self.expected_ops.push(ExpectedMemoryOp {
1256 read: false,
1257 address: addr,
1258 value,
1259 });
1260 }
1261 }
1262
1263 impl MemoryInterface<ArmError> for MockProbe {
1264 fn read_8(&mut self, _address: u64, _data: &mut [u8]) -> Result<(), ArmError> {
1265 todo!()
1266 }
1267
1268 fn read_16(&mut self, _address: u64, _data: &mut [u16]) -> Result<(), ArmError> {
1269 todo!()
1270 }
1271
1272 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), ArmError> {
1273 if self.expected_ops.is_empty() {
1274 panic!(
1275 "Received unexpected read_32 op: register {:#}",
1276 address_to_reg_num(address)
1277 );
1278 }
1279
1280 assert_eq!(data.len(), 1);
1281
1282 let expected_op = self.expected_ops.remove(0);
1283
1284 assert!(
1285 expected_op.read,
1286 "R/W mismatch for register: Expected {:#} Actual: {:#}",
1287 address_to_reg_num(expected_op.address),
1288 address_to_reg_num(address)
1289 );
1290 assert_eq!(
1291 expected_op.address,
1292 address,
1293 "Read from unexpected register: Expected {:#} Actual: {:#}",
1294 address_to_reg_num(expected_op.address),
1295 address_to_reg_num(address)
1296 );
1297
1298 data[0] = expected_op.value;
1299
1300 Ok(())
1301 }
1302
1303 fn read(&mut self, address: u64, data: &mut [u8]) -> Result<(), ArmError> {
1304 self.read_8(address, data)
1305 }
1306
1307 fn write_8(&mut self, _address: u64, _data: &[u8]) -> Result<(), ArmError> {
1308 todo!()
1309 }
1310
1311 fn write_16(&mut self, _address: u64, _data: &[u16]) -> Result<(), ArmError> {
1312 todo!()
1313 }
1314
1315 fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), ArmError> {
1316 if self.expected_ops.is_empty() {
1317 panic!(
1318 "Received unexpected write_32 op: register {:#}",
1319 address_to_reg_num(address)
1320 );
1321 }
1322
1323 assert_eq!(data.len(), 1);
1324
1325 let expected_op = self.expected_ops.remove(0);
1326
1327 assert!(
1328 !expected_op.read,
1329 "Read/write mismatch on register: {:#}",
1330 address_to_reg_num(address)
1331 );
1332 assert_eq!(
1333 expected_op.address,
1334 address,
1335 "Write to unexpected register: Expected {:#} Actual: {:#}",
1336 address_to_reg_num(expected_op.address),
1337 address_to_reg_num(address)
1338 );
1339
1340 assert_eq!(
1341 expected_op.value, data[0],
1342 "Write value mismatch Expected {:#X} Actual: {:#X}",
1343 expected_op.value, data[0]
1344 );
1345
1346 Ok(())
1347 }
1348
1349 fn write(&mut self, address: u64, data: &[u8]) -> Result<(), ArmError> {
1350 self.write_8(address, data)
1351 }
1352
1353 fn flush(&mut self) -> Result<(), ArmError> {
1354 todo!()
1355 }
1356
1357 fn read_64(&mut self, _address: u64, _data: &mut [u64]) -> Result<(), ArmError> {
1358 todo!()
1359 }
1360
1361 fn write_64(&mut self, _address: u64, _data: &[u64]) -> Result<(), ArmError> {
1362 todo!()
1363 }
1364
1365 fn supports_8bit_transfers(&self) -> Result<bool, ArmError> {
1366 Ok(false)
1367 }
1368
1369 fn supports_native_64bit_access(&mut self) -> bool {
1370 false
1371 }
1372 }
1373
1374 impl ArmMemoryInterface for MockProbe {
1375 fn fully_qualified_address(&self) -> FullyQualifiedApAddress {
1376 todo!()
1377 }
1378
1379 fn get_swd_sequence(&mut self) -> Result<&mut dyn SwdSequence, DebugProbeError> {
1380 Err(DebugProbeError::NotImplemented {
1381 function_name: "get_swd_sequence",
1382 })
1383 }
1384
1385 fn get_arm_probe_interface(
1386 &mut self,
1387 ) -> Result<&mut dyn crate::architecture::arm::ArmProbeInterface, DebugProbeError> {
1388 Err(DebugProbeError::NotImplemented {
1389 function_name: "get_arm_probe_interface",
1390 })
1391 }
1392
1393 fn get_dap_access(
1394 &mut self,
1395 ) -> Result<&mut dyn crate::architecture::arm::DapAccess, DebugProbeError> {
1396 Err(DebugProbeError::NotImplemented {
1397 function_name: "get_dap_access",
1398 })
1399 }
1400
1401 fn generic_status(&mut self) -> Result<crate::architecture::arm::ap::CSW, ArmError> {
1402 Err(ArmError::Probe(DebugProbeError::NotImplemented {
1403 function_name: "generic_status",
1404 }))
1405 }
1406
1407 fn base_address(&mut self) -> Result<u64, ArmError> {
1408 todo!()
1409 }
1410 }
1411
1412 impl SwdSequence for MockProbe {
1413 fn swj_sequence(&mut self, _bit_len: u8, _bits: u64) -> Result<(), DebugProbeError> {
1414 todo!()
1415 }
1416
1417 fn swj_pins(
1418 &mut self,
1419 _pin_out: u32,
1420 _pin_select: u32,
1421 _pin_wait: u32,
1422 ) -> Result<u32, DebugProbeError> {
1423 todo!()
1424 }
1425 }
1426
1427 fn add_status_expectations(probe: &mut MockProbe, halted: bool) {
1428 let mut dbgdscr = Dbgdscr(0);
1429 dbgdscr.set_halted(halted);
1430 dbgdscr.set_restarted(true);
1431 probe.expected_read(
1432 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1433 dbgdscr.into(),
1434 );
1435 }
1436
1437 fn add_enable_itr_expectations(probe: &mut MockProbe) {
1438 let mut dbgdscr = Dbgdscr(0);
1439 dbgdscr.set_halted(true);
1440 probe.expected_read(
1441 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1442 dbgdscr.into(),
1443 );
1444 dbgdscr.set_itren(true);
1445 probe.expected_write(
1446 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1447 dbgdscr.into(),
1448 );
1449 }
1450
1451 fn add_read_reg_expectations(probe: &mut MockProbe, reg: u16, value: u32) {
1452 probe.expected_write(
1453 Dbgitr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1454 build_mcr(14, 0, reg, 0, 5, 0),
1455 );
1456 let mut dbgdscr = Dbgdscr(0);
1457 dbgdscr.set_instrcoml_l(true);
1458 dbgdscr.set_txfull_l(true);
1459
1460 probe.expected_read(
1461 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1462 dbgdscr.into(),
1463 );
1464 probe.expected_read(
1465 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1466 value,
1467 );
1468 }
1469
1470 fn add_read_pc_expectations(probe: &mut MockProbe, value: u32) {
1471 let mut dbgdscr = Dbgdscr(0);
1472 dbgdscr.set_instrcoml_l(true);
1473 dbgdscr.set_txfull_l(true);
1474
1475 probe.expected_write(
1476 Dbgitr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1477 build_mov(0, 15),
1478 );
1479 probe.expected_read(
1480 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1481 dbgdscr.into(),
1482 );
1483 add_read_reg_expectations(probe, 0, value + 8);
1485 }
1486
1487 fn add_read_fp_count_expectations(probe: &mut MockProbe) {
1488 let mut dbgdscr = Dbgdscr(0);
1489 dbgdscr.set_instrcoml_l(true);
1490 dbgdscr.set_txfull_l(true);
1491
1492 probe.expected_write(
1493 Dbgitr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1494 build_vmrs(0, 0b0111),
1495 );
1496 probe.expected_read(
1497 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1498 dbgdscr.into(),
1499 );
1500 add_read_reg_expectations(probe, 0, 0b010);
1501 }
1502
1503 fn add_read_cpsr_expectations(probe: &mut MockProbe, value: u32) {
1504 let mut dbgdscr = Dbgdscr(0);
1505 dbgdscr.set_instrcoml_l(true);
1506 dbgdscr.set_txfull_l(true);
1507
1508 probe.expected_write(
1509 Dbgitr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1510 build_mrs(0),
1511 );
1512 probe.expected_read(
1513 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1514 dbgdscr.into(),
1515 );
1516 add_read_reg_expectations(probe, 0, value);
1517 }
1518
1519 fn add_idr_expectations(probe: &mut MockProbe, bp_count: u32) {
1520 let mut dbgdidr = Dbgdidr(0);
1521 dbgdidr.set_brps(bp_count - 1);
1522 probe.expected_read(
1523 Dbgdidr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1524 dbgdidr.into(),
1525 );
1526 }
1527
1528 fn add_set_r0_expectation(probe: &mut MockProbe, value: u32) {
1529 let mut dbgdscr = Dbgdscr(0);
1530 dbgdscr.set_instrcoml_l(true);
1531 dbgdscr.set_rxfull_l(true);
1532
1533 probe.expected_write(
1534 Dbgdtrrx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1535 value,
1536 );
1537 probe.expected_read(
1538 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1539 dbgdscr.into(),
1540 );
1541
1542 probe.expected_write(
1543 Dbgitr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1544 build_mrc(14, 0, 0, 0, 5, 0),
1545 );
1546 probe.expected_read(
1547 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1548 dbgdscr.into(),
1549 );
1550 }
1551
1552 fn add_read_memory_expectations(probe: &mut MockProbe, address: u64, value: u32) {
1553 add_set_r0_expectation(probe, address as u32);
1554
1555 let mut dbgdscr = Dbgdscr(0);
1556 dbgdscr.set_instrcoml_l(true);
1557 dbgdscr.set_txfull_l(true);
1558
1559 probe.expected_write(
1560 Dbgitr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1561 build_ldc(14, 5, 0, 4),
1562 );
1563 probe.expected_read(
1564 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1565 dbgdscr.into(),
1566 );
1567 probe.expected_read(
1568 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1569 value,
1570 );
1571 }
1572
1573 #[test]
1574 fn armv7a_new() {
1575 let mut probe = MockProbe::new();
1576
1577 add_status_expectations(&mut probe, true);
1579 add_enable_itr_expectations(&mut probe);
1580 add_read_reg_expectations(&mut probe, 0, 0);
1581 add_read_fp_count_expectations(&mut probe);
1582
1583 let mock_mem = Box::new(probe) as _;
1584
1585 let _ = Armv7a::new(
1586 mock_mem,
1587 &mut CortexAState::new(),
1588 TEST_BASE_ADDRESS,
1589 DefaultArmSequence::create(),
1590 )
1591 .unwrap();
1592 }
1593
1594 #[test]
1595 fn armv7a_core_halted() {
1596 let mut probe = MockProbe::new();
1597 let mut state = CortexAState::new();
1598
1599 add_status_expectations(&mut probe, true);
1601 add_enable_itr_expectations(&mut probe);
1602 add_read_reg_expectations(&mut probe, 0, 0);
1603 add_read_fp_count_expectations(&mut probe);
1604
1605 let mut dbgdscr = Dbgdscr(0);
1606 dbgdscr.set_halted(false);
1607 probe.expected_read(
1608 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1609 dbgdscr.into(),
1610 );
1611
1612 dbgdscr.set_halted(true);
1613 probe.expected_read(
1614 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1615 dbgdscr.into(),
1616 );
1617
1618 let mock_mem = Box::new(probe) as _;
1619
1620 let mut armv7a = Armv7a::new(
1621 mock_mem,
1622 &mut state,
1623 TEST_BASE_ADDRESS,
1624 DefaultArmSequence::create(),
1625 )
1626 .unwrap();
1627
1628 assert!(!armv7a.core_halted().unwrap());
1630 assert!(armv7a.core_halted().unwrap());
1631 }
1632
1633 #[test]
1634 fn armv7a_wait_for_core_halted() {
1635 let mut probe = MockProbe::new();
1636 let mut state = CortexAState::new();
1637
1638 add_status_expectations(&mut probe, true);
1640 add_enable_itr_expectations(&mut probe);
1641 add_read_reg_expectations(&mut probe, 0, 0);
1642 add_read_fp_count_expectations(&mut probe);
1643
1644 let mut dbgdscr = Dbgdscr(0);
1645 dbgdscr.set_halted(false);
1646 probe.expected_read(
1647 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1648 dbgdscr.into(),
1649 );
1650
1651 dbgdscr.set_halted(true);
1652 probe.expected_read(
1653 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1654 dbgdscr.into(),
1655 );
1656
1657 let mock_mem = Box::new(probe) as _;
1658
1659 let mut armv7a = Armv7a::new(
1660 mock_mem,
1661 &mut state,
1662 TEST_BASE_ADDRESS,
1663 DefaultArmSequence::create(),
1664 )
1665 .unwrap();
1666
1667 armv7a
1669 .wait_for_core_halted(Duration::from_millis(100))
1670 .unwrap();
1671 }
1672
1673 #[test]
1674 fn armv7a_status_running() {
1675 let mut probe = MockProbe::new();
1676 let mut state = CortexAState::new();
1677
1678 add_status_expectations(&mut probe, true);
1680 add_enable_itr_expectations(&mut probe);
1681 add_read_reg_expectations(&mut probe, 0, 0);
1682 add_read_fp_count_expectations(&mut probe);
1683
1684 let mut dbgdscr = Dbgdscr(0);
1685 dbgdscr.set_halted(false);
1686 probe.expected_read(
1687 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1688 dbgdscr.into(),
1689 );
1690
1691 let mock_mem = Box::new(probe) as _;
1692
1693 let mut armv7a = Armv7a::new(
1694 mock_mem,
1695 &mut state,
1696 TEST_BASE_ADDRESS,
1697 DefaultArmSequence::create(),
1698 )
1699 .unwrap();
1700
1701 assert_eq!(CoreStatus::Running, armv7a.status().unwrap());
1703 }
1704
1705 #[test]
1706 fn armv7a_status_halted() {
1707 let mut probe = MockProbe::new();
1708 let mut state = CortexAState::new();
1709
1710 add_status_expectations(&mut probe, true);
1712 add_enable_itr_expectations(&mut probe);
1713 add_read_reg_expectations(&mut probe, 0, 0);
1714 add_read_fp_count_expectations(&mut probe);
1715
1716 let mut dbgdscr = Dbgdscr(0);
1717 dbgdscr.set_halted(true);
1718 probe.expected_read(
1719 Dbgdscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1720 dbgdscr.into(),
1721 );
1722 add_read_fp_count_expectations(&mut probe);
1723
1724 let mock_mem = Box::new(probe) as _;
1725
1726 let mut armv7a = Armv7a::new(
1727 mock_mem,
1728 &mut state,
1729 TEST_BASE_ADDRESS,
1730 DefaultArmSequence::create(),
1731 )
1732 .unwrap();
1733
1734 assert_eq!(
1736 CoreStatus::Halted(crate::HaltReason::Request),
1737 armv7a.status().unwrap()
1738 );
1739 }
1740
1741 #[test]
1742 fn armv7a_read_core_reg_common() {
1743 const REG_VALUE: u32 = 0xABCD;
1744
1745 let mut probe = MockProbe::new();
1746 let mut state = CortexAState::new();
1747
1748 add_status_expectations(&mut probe, true);
1750 add_enable_itr_expectations(&mut probe);
1751 add_read_reg_expectations(&mut probe, 0, 0);
1752 add_read_fp_count_expectations(&mut probe);
1753
1754 add_read_reg_expectations(&mut probe, 2, REG_VALUE);
1756
1757 let mock_mem = Box::new(probe) as _;
1758
1759 let mut armv7a = Armv7a::new(
1760 mock_mem,
1761 &mut state,
1762 TEST_BASE_ADDRESS,
1763 DefaultArmSequence::create(),
1764 )
1765 .unwrap();
1766
1767 assert_eq!(
1769 RegisterValue::from(REG_VALUE),
1770 armv7a.read_core_reg(RegisterId(2)).unwrap()
1771 );
1772
1773 assert_eq!(
1775 RegisterValue::from(REG_VALUE),
1776 armv7a.read_core_reg(RegisterId(2)).unwrap()
1777 );
1778 }
1779
1780 #[test]
1781 fn armv7a_read_core_reg_pc() {
1782 const REG_VALUE: u32 = 0xABCD;
1783
1784 let mut probe = MockProbe::new();
1785 let mut state = CortexAState::new();
1786
1787 add_status_expectations(&mut probe, true);
1789 add_enable_itr_expectations(&mut probe);
1790 add_read_reg_expectations(&mut probe, 0, 0);
1791 add_read_fp_count_expectations(&mut probe);
1792
1793 add_read_pc_expectations(&mut probe, REG_VALUE);
1795
1796 let mock_mem = Box::new(probe) as _;
1797
1798 let mut armv7a = Armv7a::new(
1799 mock_mem,
1800 &mut state,
1801 TEST_BASE_ADDRESS,
1802 DefaultArmSequence::create(),
1803 )
1804 .unwrap();
1805
1806 assert_eq!(
1808 RegisterValue::from(REG_VALUE),
1809 armv7a.read_core_reg(RegisterId(15)).unwrap()
1810 );
1811
1812 assert_eq!(
1814 RegisterValue::from(REG_VALUE),
1815 armv7a.read_core_reg(RegisterId(15)).unwrap()
1816 );
1817 }
1818
1819 #[test]
1820 fn armv7a_read_core_reg_cpsr() {
1821 const REG_VALUE: u32 = 0xABCD;
1822
1823 let mut probe = MockProbe::new();
1824 let mut state = CortexAState::new();
1825
1826 add_status_expectations(&mut probe, true);
1828 add_enable_itr_expectations(&mut probe);
1829 add_read_reg_expectations(&mut probe, 0, 0);
1830 add_read_fp_count_expectations(&mut probe);
1831
1832 add_read_cpsr_expectations(&mut probe, REG_VALUE);
1834
1835 let mock_mem = Box::new(probe) as _;
1836
1837 let mut armv7a = Armv7a::new(
1838 mock_mem,
1839 &mut state,
1840 TEST_BASE_ADDRESS,
1841 DefaultArmSequence::create(),
1842 )
1843 .unwrap();
1844
1845 assert_eq!(
1847 RegisterValue::from(REG_VALUE),
1848 armv7a.read_core_reg(RegisterId(16)).unwrap()
1849 );
1850
1851 assert_eq!(
1853 RegisterValue::from(REG_VALUE),
1854 armv7a.read_core_reg(RegisterId(16)).unwrap()
1855 );
1856 }
1857
1858 #[test]
1859 fn armv7a_halt() {
1860 const REG_VALUE: u32 = 0xABCD;
1861
1862 let mut probe = MockProbe::new();
1863 let mut state = CortexAState::new();
1864
1865 add_status_expectations(&mut probe, false);
1867
1868 let mut dbgdrcr = Dbgdrcr(0);
1870 dbgdrcr.set_hrq(true);
1871 probe.expected_write(
1872 Dbgdrcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1873 dbgdrcr.into(),
1874 );
1875
1876 add_status_expectations(&mut probe, true);
1878
1879 add_status_expectations(&mut probe, true);
1881 add_enable_itr_expectations(&mut probe);
1882 add_read_reg_expectations(&mut probe, 0, 0);
1883 add_read_fp_count_expectations(&mut probe);
1884
1885 add_read_pc_expectations(&mut probe, REG_VALUE);
1887
1888 let mock_mem = Box::new(probe) as _;
1889
1890 let mut armv7a = Armv7a::new(
1891 mock_mem,
1892 &mut state,
1893 TEST_BASE_ADDRESS,
1894 DefaultArmSequence::create(),
1895 )
1896 .unwrap();
1897
1898 assert_eq!(
1900 REG_VALUE as u64,
1901 armv7a.halt(Duration::from_millis(100)).unwrap().pc
1902 );
1903 }
1904
1905 #[test]
1906 fn armv7a_run() {
1907 let mut probe = MockProbe::new();
1908 let mut state = CortexAState::new();
1909
1910 add_status_expectations(&mut probe, true);
1912 add_enable_itr_expectations(&mut probe);
1913 add_read_reg_expectations(&mut probe, 0, 0);
1914 add_read_fp_count_expectations(&mut probe);
1915
1916 add_set_r0_expectation(&mut probe, 0);
1918
1919 let mut dbgdrcr = Dbgdrcr(0);
1921 dbgdrcr.set_rrq(true);
1922 probe.expected_write(
1923 Dbgdrcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1924 dbgdrcr.into(),
1925 );
1926
1927 add_status_expectations(&mut probe, false);
1929
1930 add_status_expectations(&mut probe, false);
1932
1933 let mock_mem = Box::new(probe) as _;
1934
1935 let mut armv7a = Armv7a::new(
1936 mock_mem,
1937 &mut state,
1938 TEST_BASE_ADDRESS,
1939 DefaultArmSequence::create(),
1940 )
1941 .unwrap();
1942
1943 armv7a.run().unwrap();
1944 }
1945
1946 #[test]
1947 fn armv7a_available_breakpoint_units() {
1948 const BP_COUNT: u32 = 4;
1949 let mut probe = MockProbe::new();
1950 let mut state = CortexAState::new();
1951
1952 add_status_expectations(&mut probe, true);
1954 add_enable_itr_expectations(&mut probe);
1955 add_read_reg_expectations(&mut probe, 0, 0);
1956 add_read_fp_count_expectations(&mut probe);
1957
1958 add_idr_expectations(&mut probe, BP_COUNT);
1960
1961 let mock_mem = Box::new(probe) as _;
1962
1963 let mut armv7a = Armv7a::new(
1964 mock_mem,
1965 &mut state,
1966 TEST_BASE_ADDRESS,
1967 DefaultArmSequence::create(),
1968 )
1969 .unwrap();
1970
1971 assert_eq!(BP_COUNT, armv7a.available_breakpoint_units().unwrap());
1972 }
1973
1974 #[test]
1975 fn armv7a_hw_breakpoints() {
1976 const BP_COUNT: u32 = 4;
1977 const BP1: u64 = 0x2345;
1978 const BP2: u64 = 0x8000_0000;
1979 let mut probe = MockProbe::new();
1980 let mut state = CortexAState::new();
1981
1982 add_status_expectations(&mut probe, true);
1984 add_enable_itr_expectations(&mut probe);
1985 add_read_reg_expectations(&mut probe, 0, 0);
1986 add_read_fp_count_expectations(&mut probe);
1987
1988 add_idr_expectations(&mut probe, BP_COUNT);
1990
1991 probe.expected_read(
1993 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1994 BP1 as u32,
1995 );
1996 probe.expected_read(
1997 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1998 1,
1999 );
2000
2001 probe.expected_read(
2002 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4,
2003 BP2 as u32,
2004 );
2005 probe.expected_read(
2006 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4,
2007 1,
2008 );
2009
2010 probe.expected_read(
2011 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (2 * 4),
2012 0,
2013 );
2014 probe.expected_read(
2015 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (2 * 4),
2016 0,
2017 );
2018
2019 probe.expected_read(
2020 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (3 * 4),
2021 0,
2022 );
2023 probe.expected_read(
2024 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (3 * 4),
2025 0,
2026 );
2027
2028 let mock_mem = Box::new(probe) as _;
2029
2030 let mut armv7a = Armv7a::new(
2031 mock_mem,
2032 &mut state,
2033 TEST_BASE_ADDRESS,
2034 DefaultArmSequence::create(),
2035 )
2036 .unwrap();
2037
2038 let results = armv7a.hw_breakpoints().unwrap();
2039 assert_eq!(Some(BP1), results[0]);
2040 assert_eq!(Some(BP2), results[1]);
2041 assert_eq!(None, results[2]);
2042 assert_eq!(None, results[3]);
2043 }
2044
2045 #[test]
2046 fn armv7a_set_hw_breakpoint() {
2047 const BP_VALUE: u64 = 0x2345;
2048 let mut probe = MockProbe::new();
2049 let mut state = CortexAState::new();
2050
2051 add_status_expectations(&mut probe, true);
2053 add_enable_itr_expectations(&mut probe);
2054 add_read_reg_expectations(&mut probe, 0, 0);
2055 add_read_fp_count_expectations(&mut probe);
2056
2057 let mut dbgbcr = Dbgbcr(0);
2059 dbgbcr.set_hmc(true);
2061 dbgbcr.set_pmc(0b11);
2062 dbgbcr.set_bas(0b1111);
2064 dbgbcr.set_e(true);
2066
2067 probe.expected_write(
2068 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2069 BP_VALUE as u32,
2070 );
2071 probe.expected_write(
2072 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2073 dbgbcr.into(),
2074 );
2075
2076 let mock_mem = Box::new(probe) as _;
2077
2078 let mut armv7a = Armv7a::new(
2079 mock_mem,
2080 &mut state,
2081 TEST_BASE_ADDRESS,
2082 DefaultArmSequence::create(),
2083 )
2084 .unwrap();
2085
2086 armv7a.set_hw_breakpoint(0, BP_VALUE).unwrap();
2087 }
2088
2089 #[test]
2090 fn armv7a_clear_hw_breakpoint() {
2091 let mut probe = MockProbe::new();
2092 let mut state = CortexAState::new();
2093
2094 add_status_expectations(&mut probe, true);
2096 add_enable_itr_expectations(&mut probe);
2097 add_read_reg_expectations(&mut probe, 0, 0);
2098 add_read_fp_count_expectations(&mut probe);
2099
2100 probe.expected_write(
2102 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2103 0,
2104 );
2105 probe.expected_write(
2106 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2107 0,
2108 );
2109
2110 let mock_mem = Box::new(probe) as _;
2111
2112 let mut armv7a = Armv7a::new(
2113 mock_mem,
2114 &mut state,
2115 TEST_BASE_ADDRESS,
2116 DefaultArmSequence::create(),
2117 )
2118 .unwrap();
2119
2120 armv7a.clear_hw_breakpoint(0).unwrap();
2121 }
2122
2123 #[test]
2124 fn armv7a_read_word_32() {
2125 const MEMORY_VALUE: u32 = 0xBA5EBA11;
2126 const MEMORY_ADDRESS: u64 = 0x12345678;
2127
2128 let mut probe = MockProbe::new();
2129 let mut state = CortexAState::new();
2130
2131 add_status_expectations(&mut probe, true);
2133 add_enable_itr_expectations(&mut probe);
2134 add_read_reg_expectations(&mut probe, 0, 0);
2135 add_read_fp_count_expectations(&mut probe);
2136
2137 add_read_memory_expectations(&mut probe, MEMORY_ADDRESS, MEMORY_VALUE);
2139
2140 let mock_mem = Box::new(probe) as _;
2141
2142 let mut armv7a = Armv7a::new(
2143 mock_mem,
2144 &mut state,
2145 TEST_BASE_ADDRESS,
2146 DefaultArmSequence::create(),
2147 )
2148 .unwrap();
2149
2150 assert_eq!(MEMORY_VALUE, armv7a.read_word_32(MEMORY_ADDRESS).unwrap());
2151 }
2152
2153 #[test]
2154 fn armv7a_read_word_8() {
2155 const MEMORY_VALUE: u32 = 0xBA5EBA11;
2156 const MEMORY_ADDRESS: u64 = 0x12345679;
2157 const MEMORY_WORD_ADDRESS: u64 = 0x12345678;
2158
2159 let mut probe = MockProbe::new();
2160 let mut state = CortexAState::new();
2161
2162 add_status_expectations(&mut probe, true);
2164 add_enable_itr_expectations(&mut probe);
2165 add_read_reg_expectations(&mut probe, 0, 0);
2166 add_read_fp_count_expectations(&mut probe);
2167
2168 add_read_memory_expectations(&mut probe, MEMORY_WORD_ADDRESS, MEMORY_VALUE);
2170
2171 let mock_mem = Box::new(probe) as _;
2172
2173 let mut armv7a = Armv7a::new(
2174 mock_mem,
2175 &mut state,
2176 TEST_BASE_ADDRESS,
2177 DefaultArmSequence::create(),
2178 )
2179 .unwrap();
2180
2181 assert_eq!(0xBA, armv7a.read_word_8(MEMORY_ADDRESS).unwrap());
2182 }
2183}