1use super::{
4 CortexAState,
5 instructions::{
6 aarch64,
7 thumb2::{build_ldr, build_mcr, build_mrc, build_str, build_vmov, build_vmrs},
8 },
9 registers::{aarch32::AARCH32_WITH_FP_32_CORE_REGISTERS, aarch64::AARCH64_CORE_REGISTERS},
10};
11use crate::{
12 Architecture, CoreInformation, CoreInterface, CoreRegister, CoreStatus, CoreType,
13 InstructionSet, MemoryInterface,
14 architecture::arm::{
15 ArmError, core::armv8a_debug_regs::*, memory::ArmMemoryInterface,
16 sequences::ArmDebugSequence,
17 },
18 core::{
19 CoreRegisters, RegisterId, RegisterValue, memory_mapped_registers::MemoryMappedRegister,
20 },
21 error::Error,
22 memory::{MemoryNotAlignedError, valid_32bit_address},
23};
24use std::{
25 sync::Arc,
26 time::{Duration, Instant},
27};
28
29const OPERATION_TIMEOUT: Duration = Duration::from_millis(250);
30
31#[derive(thiserror::Error, Debug)]
33pub enum Armv8aError {
34 #[error("Register number {0} is not valid for ARMv8-A in {1}-bit mode")]
36 InvalidRegisterNumber(u16, u16),
37
38 #[error("Core is running but operation requires it to be halted")]
40 NotHalted,
41
42 #[error("A data abort occurred")]
44 DataAbort,
45}
46
47fn prep_instr_for_itr_32(instruction: u32) -> u32 {
49 ((instruction & 0xFFFF) << 16) | ((instruction & 0xFFFF_0000) >> 16)
50}
51
52pub struct Armv8a<'probe> {
54 memory: Box<dyn ArmMemoryInterface + 'probe>,
55
56 state: &'probe mut CortexAState,
57
58 base_address: u64,
59
60 cti_address: u64,
61
62 sequence: Arc<dyn ArmDebugSequence>,
63
64 num_breakpoints: Option<u32>,
65}
66
67impl<'probe> Armv8a<'probe> {
68 pub(crate) fn new(
69 mut memory: Box<dyn ArmMemoryInterface + 'probe>,
70 state: &'probe mut CortexAState,
71 base_address: u64,
72 cti_address: u64,
73 sequence: Arc<dyn ArmDebugSequence>,
74 ) -> Result<Self, Error> {
75 if !state.initialized() {
76 let address = Edscr::get_mmio_address_from_base(base_address)?;
78 let edscr = Edscr(memory.read_word_32(address)?);
79
80 tracing::debug!("State when connecting: {:x?}", edscr);
81
82 let core_state = if edscr.halted() {
83 let reason = edscr.halt_reason();
84
85 tracing::debug!("Core was halted when connecting, reason: {:?}", reason);
86
87 CoreStatus::Halted(reason)
88 } else {
89 CoreStatus::Running
90 };
91
92 state.current_state = core_state;
93 state.is_64_bit = edscr.currently_64_bit();
94 state.fp_reg_count = 32;
96 }
97
98 let mut core = Self {
99 memory,
100 state,
101 base_address,
102 cti_address,
103 sequence,
104 num_breakpoints: None,
105 };
106
107 if !core.state.initialized() {
108 core.reset_register_cache();
109 core.state.initialize();
110 }
111
112 Ok(core)
113 }
114
115 fn execute_instruction(&mut self, instruction: u32) -> Result<Edscr, Error> {
117 if !self.state.current_state.is_halted() {
118 return Err(Error::Arm(Armv8aError::NotHalted.into()));
119 }
120
121 let mut final_instruction = instruction;
122
123 if !self.state.is_64_bit {
124 final_instruction = prep_instr_for_itr_32(instruction)
126 }
127
128 let address = Editr::get_mmio_address_from_base(self.base_address)?;
130 self.memory.write_word_32(address, final_instruction)?;
131
132 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
134 let mut edscr = Edscr(self.memory.read_word_32(address)?);
135
136 let start = Instant::now();
137 while !edscr.ite() {
138 if start.elapsed() > OPERATION_TIMEOUT {
139 return Err(Error::Arm(ArmError::Timeout));
140 }
141 edscr = Edscr(self.memory.read_word_32(address)?);
142 }
143
144 if edscr.err() || edscr.a() {
146 let address = Edrcr::get_mmio_address_from_base(self.base_address)?;
147 let mut edrcr = Edrcr(0);
148 edrcr.set_cse(true);
149
150 self.memory.write_word_32(address, edrcr.into())?;
151
152 return Err(Error::Arm(Armv8aError::DataAbort.into()));
153 }
154
155 Ok(edscr)
156 }
157
158 fn execute_instruction_with_result_32(&mut self, instruction: u32) -> Result<u32, Error> {
160 let mut edscr = self.execute_instruction(instruction)?;
162
163 let start = Instant::now();
165 while !edscr.txfull() {
166 if start.elapsed() > OPERATION_TIMEOUT {
167 return Err(Error::Timeout);
168 }
169 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
170 edscr = Edscr(self.memory.read_word_32(address)?);
171 }
172
173 let address = Dbgdtrtx::get_mmio_address_from_base(self.base_address)?;
175 let result = self.memory.read_word_32(address)?;
176
177 Ok(result)
178 }
179
180 fn execute_instruction_with_result_64(&mut self, instruction: u32) -> Result<u64, Error> {
182 let mut edscr = self.execute_instruction(instruction)?;
184
185 let start = Instant::now();
187 while !edscr.txfull() {
188 if start.elapsed() > OPERATION_TIMEOUT {
189 return Err(Error::Timeout);
190 }
191 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
192 edscr = Edscr(self.memory.read_word_32(address)?);
193 }
194
195 let address = Dbgdtrrx::get_mmio_address_from_base(self.base_address)?;
197 let mut result: u64 = (self.memory.read_word_32(address)? as u64) << 32;
198
199 let address = Dbgdtrtx::get_mmio_address_from_base(self.base_address)?;
200 result |= self.memory.read_word_32(address)? as u64;
201
202 Ok(result)
203 }
204
205 fn execute_instruction_with_input_32(
206 &mut self,
207 instruction: u32,
208 value: u32,
209 ) -> Result<(), Error> {
210 let address = Dbgdtrrx::get_mmio_address_from_base(self.base_address)?;
212 self.memory.write_word_32(address, value)?;
213
214 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
216 let mut edscr = Edscr(self.memory.read_word_32(address)?);
217
218 let start = Instant::now();
219 while !edscr.rxfull() {
220 if start.elapsed() > OPERATION_TIMEOUT {
221 return Err(Error::Timeout);
222 }
223 edscr = Edscr(self.memory.read_word_32(address)?);
224 }
225
226 self.execute_instruction(instruction)?;
228
229 Ok(())
230 }
231
232 fn execute_instruction_with_input_64(
233 &mut self,
234 instruction: u32,
235 value: u64,
236 ) -> Result<(), Error> {
237 let high_word = (value >> 32) as u32;
239 let low_word = (value & 0xFFFF_FFFF) as u32;
240
241 let address = Dbgdtrtx::get_mmio_address_from_base(self.base_address)?;
242 self.memory.write_word_32(address, high_word)?;
243
244 let address = Dbgdtrrx::get_mmio_address_from_base(self.base_address)?;
245 self.memory.write_word_32(address, low_word)?;
246
247 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
249 let mut edscr = Edscr(self.memory.read_word_32(address)?);
250
251 let start = Instant::now();
252 while !edscr.rxfull() {
253 if start.elapsed() > OPERATION_TIMEOUT {
254 return Err(Error::Timeout);
255 }
256 edscr = Edscr(self.memory.read_word_32(address)?);
257 }
258
259 self.execute_instruction(instruction)?;
261
262 Ok(())
263 }
264
265 fn reset_register_cache(&mut self) {
266 if self.state.is_64_bit {
267 self.state.register_cache = vec![None; 68];
270 } else {
271 self.state.register_cache = vec![None; 50];
273 }
274 }
275
276 fn writeback_registers_aarch32(&mut self) -> Result<(), Error> {
277 let writeback_iter = (15u16..=16).chain(17u16..=48).chain(0u16..=14);
279
280 for i in writeback_iter {
281 if let Some((val, writeback)) = self.state.register_cache[i as usize]
282 && writeback
283 {
284 match i {
285 0..=14 => {
286 let instruction = build_mrc(14, 0, i, 0, 5, 0);
287
288 self.execute_instruction_with_input_32(instruction, val.try_into()?)?;
289 }
290 15 => {
291 let instruction = build_mrc(14, 0, 0, 0, 5, 0);
293
294 self.execute_instruction_with_input_32(instruction, val.try_into()?)?;
295
296 let instruction = build_mcr(15, 3, 0, 4, 5, 1);
304 self.execute_instruction(instruction)?;
305 }
306 17..=48 => {
307 let value: u64 = val.try_into()?;
309 let low_word = value as u32;
310 let high_word = (value >> 32) as u32;
311
312 let instruction = build_mrc(14, 0, 0, 0, 5, 0);
313 self.execute_instruction_with_input_32(instruction, low_word)?;
314
315 let instruction = build_mrc(14, 0, 1, 0, 5, 0);
316 self.execute_instruction_with_input_32(instruction, high_word)?;
317
318 let instruction = build_vmov(0, 0, 1, i - 17);
320 self.execute_instruction(instruction)?;
321 }
322 _ => {
323 panic!("Logic missing for writeback of register {i}");
324 }
325 }
326 }
327 }
328
329 Ok(())
330 }
331
332 fn writeback_registers_aarch64(&mut self) -> Result<(), Error> {
333 let writeback_iter = (31u16..=33).chain(34u16..=65).chain(0u16..=30);
335
336 for i in writeback_iter {
337 if let Some((val, writeback)) = self.state.register_cache[i as usize]
338 && writeback
339 {
340 match i {
341 0..=30 => {
342 self.set_reg_value(i, val.try_into()?)?;
343 }
344 31 => {
345 self.set_reg_value(0, val.try_into()?)?;
347
348 let instruction = aarch64::build_msr(3, 0, 4, 1, 0, 0);
350 self.execute_instruction(instruction)?;
351 }
352 32 => {
353 self.set_reg_value(0, val.try_into()?)?;
355
356 let instruction = aarch64::build_msr(3, 3, 4, 5, 1, 0);
358 self.execute_instruction(instruction)?;
359 }
360 34..=65 => {
361 let val: u128 = val.try_into()?;
362
363 self.set_reg_value(0, val as u64)?;
365
366 let instruction = aarch64::build_ins_gp_to_fp(i - 34, 0, 0);
368 self.execute_instruction(instruction)?;
369
370 self.set_reg_value(0, (val >> 64) as u64)?;
372
373 let instruction = aarch64::build_ins_gp_to_fp(i - 34, 0, 1);
375 self.execute_instruction(instruction)?;
376 }
377 _ => {
378 panic!("Logic missing for writeback of register {i}");
379 }
380 }
381 }
382 }
383
384 Ok(())
385 }
386
387 fn writeback_registers(&mut self) -> Result<(), Error> {
389 if self.state.is_64_bit {
390 self.writeback_registers_aarch64()?;
391 } else {
392 self.writeback_registers_aarch32()?;
393 }
394
395 self.reset_register_cache();
396
397 Ok(())
398 }
399
400 fn prepare_for_clobber(&mut self, reg: u16) -> Result<(), Error> {
402 if let Some(val) = &mut self.state.register_cache[reg as usize] {
403 val.1 = true;
405 } else {
406 let val = self.read_core_reg(RegisterId(reg))?;
408
409 self.state.register_cache[reg as usize] = Some((val, true));
411 }
412
413 Ok(())
414 }
415
416 fn set_reg_value(&mut self, reg: u16, value: u64) -> Result<(), Error> {
417 if self.state.is_64_bit {
418 let instruction = aarch64::build_mrs(2, 3, 0, 4, 0, reg);
420
421 self.execute_instruction_with_input_64(instruction, value)
422 } else {
423 let value = valid_32bit_address(value)?;
424
425 let instruction = build_mrc(14, 0, reg, 0, 5, 0);
426
427 self.execute_instruction_with_input_32(instruction, value)
428 }
429 }
430
431 fn ack_cti_halt(&mut self) -> Result<(), Error> {
432 let mut ack = CtiIntack(0);
433 ack.set_ack(0, 1);
434
435 let address = CtiIntack::get_mmio_address_from_base(self.cti_address)?;
436 self.memory.write_word_32(address, ack.into())?;
437
438 let start = Instant::now();
439 loop {
440 let address = CtiTrigoutstatus::get_mmio_address_from_base(self.cti_address)?;
441 let trig_status = CtiTrigoutstatus(self.memory.read_word_32(address)?);
442
443 if trig_status.status(0) == 0 {
444 break;
445 }
446 if start.elapsed() > OPERATION_TIMEOUT {
447 return Err(Error::Timeout);
448 }
449 }
450
451 Ok(())
452 }
453
454 fn read_core_reg_32(&mut self, reg_num: u16) -> Result<RegisterValue, Error> {
455 match reg_num {
457 0..=14 => {
458 let instruction = build_mcr(14, 0, reg_num, 0, 5, 0);
461
462 let reg_value = self.execute_instruction_with_result_32(instruction)?;
463
464 Ok(reg_value.into())
465 }
466 15 => {
467 self.prepare_for_clobber(0)?;
469
470 let instruction = build_mrc(15, 3, 0, 4, 5, 1);
472 self.execute_instruction(instruction)?;
473
474 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
476 let pc = self.execute_instruction_with_result_32(instruction)?;
477
478 Ok(pc.into())
479 }
480 16 => {
481 self.prepare_for_clobber(0)?;
483
484 let instruction = build_mrc(15, 3, 0, 4, 5, 0);
486 self.execute_instruction(instruction)?;
487
488 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
490 let cpsr = self.execute_instruction_with_result_32(instruction)?;
491
492 Ok(cpsr.into())
493 }
494 17..=48 => {
495 self.prepare_for_clobber(0)?;
497 self.prepare_for_clobber(1)?;
498
499 let instruction = build_vmov(1, 0, 1, reg_num - 17);
501 self.execute_instruction(instruction)?;
502
503 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
505 let mut value = self.execute_instruction_with_result_32(instruction)? as u64;
506
507 let instruction = build_mcr(14, 0, 1, 0, 5, 0);
509 value |= (self.execute_instruction_with_result_32(instruction)? as u64) << 32;
510
511 Ok(value.into())
512 }
513 49 => {
514 self.prepare_for_clobber(0)?;
516
517 let instruction = build_vmrs(0, 1);
519 self.execute_instruction(instruction)?;
520
521 let instruction = build_mcr(14, 0, 0, 0, 5, 0);
523 let value = self.execute_instruction_with_result_32(instruction)?;
524
525 Ok(value.into())
526 }
527 _ => Err(Error::Arm(
528 Armv8aError::InvalidRegisterNumber(reg_num, 32).into(),
529 )),
530 }
531 }
532
533 fn read_core_reg_64(&mut self, reg_num: u16) -> Result<RegisterValue, Error> {
534 match reg_num {
535 0..=30 => {
536 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, reg_num);
540
541 let reg_value = self.execute_instruction_with_result_64(instruction)?;
542
543 Ok(reg_value.into())
544 }
545 31 => {
546 self.prepare_for_clobber(0)?;
548
549 let instruction = aarch64::build_mrs(3, 0, 4, 1, 0, 0);
551 self.execute_instruction(instruction)?;
552
553 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
555 let sp = self.execute_instruction_with_result_64(instruction)?;
556
557 Ok(sp.into())
558 }
559 32 => {
560 self.prepare_for_clobber(0)?;
562
563 let instruction = aarch64::build_mrs(3, 3, 4, 5, 1, 0);
565 self.execute_instruction(instruction)?;
566
567 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
569 let pc = self.execute_instruction_with_result_64(instruction)?;
570
571 Ok(pc.into())
572 }
573 33 => {
574 self.prepare_for_clobber(0)?;
576
577 let instruction = aarch64::build_mrs(3, 3, 4, 5, 0, 0);
579 self.execute_instruction(instruction)?;
580
581 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
583 let psr: u32 = self.execute_instruction_with_result_64(instruction)? as u32;
584
585 Ok(psr.into())
586 }
587 34..=65 => {
588 self.prepare_for_clobber(0)?;
590
591 let instruction = aarch64::build_ins_fp_to_gp(0, reg_num - 34, 0);
593 self.execute_instruction(instruction)?;
594
595 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
597 let mut value: u128 = self.execute_instruction_with_result_64(instruction)? as u128;
598
599 let instruction = aarch64::build_ins_fp_to_gp(0, reg_num - 34, 1);
601 self.execute_instruction(instruction)?;
602
603 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
605 value |= (self.execute_instruction_with_result_64(instruction)? as u128) << 64;
606
607 Ok(value.into())
608 }
609 66 => {
610 self.prepare_for_clobber(0)?;
612
613 let instruction = aarch64::build_mrs(3, 3, 4, 4, 1, 0);
615 self.execute_instruction(instruction)?;
616
617 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
619 let fpsr: u32 = self.execute_instruction_with_result_64(instruction)? as u32;
620
621 Ok(fpsr.into())
622 }
623 67 => {
624 self.prepare_for_clobber(0)?;
626
627 let instruction = aarch64::build_mrs(3, 3, 4, 4, 0, 0);
629 self.execute_instruction(instruction)?;
630
631 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
633 let fpcr: u32 = self.execute_instruction_with_result_64(instruction)? as u32;
634
635 Ok(fpcr.into())
636 }
637 _ => Err(Error::Arm(
638 Armv8aError::InvalidRegisterNumber(reg_num, 64).into(),
639 )),
640 }
641 }
642
643 fn with_core_halted<F, R>(&mut self, f: F) -> Result<R, Error>
644 where
645 F: FnOnce(&mut Self) -> Result<R, Error>,
646 {
647 let original_halt_status = self.state.current_state.is_halted();
649 if !original_halt_status {
650 self.halt(Duration::from_millis(100))?;
651 }
652
653 let result = f(self);
654
655 if !original_halt_status {
657 self.run()?;
658 }
659 result
660 }
661
662 fn with_memory_access_mode<F, R>(&mut self, f: F) -> Result<R, Error>
665 where
666 F: FnOnce(&mut Self) -> Result<R, Error>,
667 {
668 self.set_memory_access_mode(true)?;
670
671 let result = f(self);
672
673 self.set_memory_access_mode(false)?;
675
676 result
677 }
678
679 fn read_cpu_memory_aarch32_32(&mut self, address: u64) -> Result<u32, Error> {
680 let address = valid_32bit_address(address)?;
681
682 self.with_core_halted(|armv8a| {
683 armv8a.prepare_for_clobber(0)?;
685 armv8a.prepare_for_clobber(1)?;
686
687 armv8a.set_reg_value(0, address.into())?;
689
690 let instruction = build_ldr(1, 0, 4);
692
693 armv8a.execute_instruction(instruction)?;
694
695 let instruction = build_mcr(14, 0, 1, 0, 5, 0);
697 armv8a.execute_instruction_with_result_32(instruction)
698 })
699 }
700
701 fn read_cpu_memory_aarch64_bytes(
702 &mut self,
703 address: u64,
704 data: &mut [u8],
705 ) -> Result<(), Error> {
706 self.with_core_halted(|armv8a| {
707 armv8a.prepare_for_clobber(0)?;
709 armv8a.prepare_for_clobber(1)?;
710
711 armv8a.set_reg_value(0, address)?;
713
714 for d in data {
715 let instruction = aarch64::build_ldrb(1, 0, 1);
717
718 armv8a.execute_instruction(instruction)?;
719
720 let instruction = aarch64::build_msr(2, 3, 0, 5, 0, 1);
722 *d = armv8a.execute_instruction_with_result_32(instruction)? as u8;
723 }
724
725 Ok(())
726 })
727 }
728
729 fn read_cpu_memory_aarch64_32(&mut self, address: u64) -> Result<u32, Error> {
730 self.with_core_halted(|armv8a| {
731 armv8a.prepare_for_clobber(0)?;
733 armv8a.prepare_for_clobber(1)?;
734
735 armv8a.set_reg_value(0, address)?;
737
738 let instruction = aarch64::build_ldrw(1, 0, 4);
740
741 armv8a.execute_instruction(instruction)?;
742
743 let instruction = aarch64::build_msr(2, 3, 0, 5, 0, 1);
745 armv8a.execute_instruction_with_result_32(instruction)
746 })
747 }
748
749 fn read_cpu_memory_aarch64_64(&mut self, address: u64) -> Result<u64, Error> {
750 self.with_core_halted(|armv8a| {
751 armv8a.prepare_for_clobber(0)?;
753 armv8a.prepare_for_clobber(1)?;
754
755 armv8a.set_reg_value(0, address)?;
757
758 let instruction = aarch64::build_ldr(1, 0, 8);
760
761 armv8a.execute_instruction(instruction)?;
762
763 let instruction = aarch64::build_msr(2, 3, 0, 4, 0, 1);
765 armv8a.execute_instruction_with_result_64(instruction)
766 })
767 }
768
769 fn write_cpu_memory_aarch32_32(&mut self, address: u64, data: u32) -> Result<(), Error> {
770 let address = valid_32bit_address(address)?;
771 self.with_core_halted(|armv8a| {
772 armv8a.prepare_for_clobber(0)?;
774 armv8a.prepare_for_clobber(1)?;
775
776 armv8a.set_reg_value(0, address.into())?;
778 armv8a.set_reg_value(1, data.into())?;
779
780 let instruction = build_str(1, 0, 4);
782
783 armv8a.execute_instruction(instruction)?;
784 Ok(())
785 })
786 }
787
788 fn write_cpu_memory_aarch64_32(&mut self, address: u64, data: u32) -> Result<(), Error> {
789 self.with_core_halted(|armv8a| {
790 armv8a.prepare_for_clobber(0)?;
792 armv8a.prepare_for_clobber(1)?;
793
794 armv8a.set_reg_value(0, address)?;
796 armv8a.set_reg_value(1, data.into())?;
797
798 let instruction = aarch64::build_strw(1, 0, 4);
800
801 armv8a.execute_instruction(instruction)?;
802 Ok(())
803 })
804 }
805
806 fn write_cpu_memory_aarch64_64(&mut self, address: u64, data: u64) -> Result<(), Error> {
807 self.with_core_halted(|armv8a| {
808 armv8a.prepare_for_clobber(0)?;
810 armv8a.prepare_for_clobber(1)?;
811
812 armv8a.set_reg_value(0, address)?;
814 armv8a.set_reg_value(1, data)?;
815
816 let instruction = aarch64::build_str(1, 0, 8);
818
819 armv8a.execute_instruction(instruction)?;
820 Ok(())
821 })
822 }
823
824 fn set_memory_access_mode(&mut self, enable_ma_mode: bool) -> Result<(), Error> {
825 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
826 let mut edscr: Edscr = Edscr(self.memory.read_word_32(address)?);
827 edscr.set_ma(enable_ma_mode);
828 self.memory.write_word_32(address, edscr.into())?;
829
830 Ok(())
831 }
832
833 fn write_cpu_memory_fast(&mut self, address: u64, data: &[u8]) -> Result<(), Error> {
834 self.with_core_halted(|armv8a| {
835 let (prefix, aligned, suffix) = armv8a.aligned_to_32(address, data);
836 let mut address = address;
837
838 for d in prefix {
840 armv8a.write_word_8(address, *d)?;
841 address += 1;
842 }
843
844 armv8a.write_cpu_memory_fast_inner(address, aligned)?;
846 address += u64::try_from(aligned.len()).unwrap();
847
848 for d in suffix {
850 armv8a.write_word_8(address, *d)?;
851 address += 1;
852 }
853
854 Ok(())
855 })
856 }
857
858 fn write_cpu_memory_fast_inner(&mut self, address: u64, data: &[u8]) -> Result<(), Error> {
861 if data.is_empty() {
863 return Ok(());
864 }
865 if !data.len().is_multiple_of(4) || !address.is_multiple_of(4) {
866 return Err(MemoryNotAlignedError {
867 address,
868 alignment: 4,
869 }
870 .into());
871 }
872
873 self.prepare_for_clobber(0)?;
876 self.prepare_for_clobber(1)?;
877
878 self.set_reg_value(0, address)?;
880
881 self.with_memory_access_mode(|armv8a| {
882 for d in data.chunks(4) {
883 let word = u32::from_le_bytes([d[0], d[1], d[2], d[3]]);
884 let dbgdtr_rx_address = Dbgdtrrx::get_mmio_address_from_base(armv8a.base_address)?;
893 armv8a.memory.write_word_32(dbgdtr_rx_address, word)?;
894 }
895 Ok(())
896 })?;
897
898 let edscr_address = Edscr::get_mmio_address_from_base(self.base_address)?;
900 if Edscr(self.memory.read_word_32(edscr_address)?).err() {
901 let edrcr_address = Edrcr::get_mmio_address_from_base(self.base_address)?;
905 let mut edrcr = Edrcr(0);
906 edrcr.set_cse(true);
907 self.memory.write_word_32(edrcr_address, edrcr.into())?;
908
909 return Err(Error::Arm(ArmError::Armv8a(Armv8aError::DataAbort)));
910 }
911
912 Ok(())
913 }
914
915 fn aligned_to_32_split_offset(&self, address: u64, data: &[u8]) -> (usize, usize) {
916 let word_aligned_address = (address + 3) & (!0x03u64);
918 let unaligned_prefix_size = usize::try_from(word_aligned_address - address).unwrap();
919 let unaligned_suffix_size =
920 usize::try_from((address + u64::try_from(data.len()).unwrap()) % 4).unwrap();
921 let word_aligned_size = data.len() - (unaligned_prefix_size + unaligned_suffix_size);
922
923 (unaligned_prefix_size, word_aligned_size)
924 }
925
926 fn aligned_to_32_mut<'a>(
927 &self,
928 address: u64,
929 data: &'a mut [u8],
930 ) -> (&'a mut [u8], &'a mut [u8], &'a mut [u8]) {
931 let (unaligned_prefix_size, word_aligned_size) =
933 self.aligned_to_32_split_offset(address, data);
934
935 let (prefix, rest) = data.split_at_mut(unaligned_prefix_size);
937 let (aligned, suffix) = rest.split_at_mut(word_aligned_size);
938 (prefix, aligned, suffix)
939 }
940
941 fn aligned_to_32<'a>(&self, address: u64, data: &'a [u8]) -> (&'a [u8], &'a [u8], &'a [u8]) {
942 let (unaligned_prefix_size, word_aligned_size) =
944 self.aligned_to_32_split_offset(address, data);
945
946 let (prefix, rest) = data.split_at(unaligned_prefix_size);
948 let (aligned, suffix) = rest.split_at(word_aligned_size);
949 (prefix, aligned, suffix)
950 }
951
952 fn read_cpu_memory_aarch64_fast(&mut self, address: u64, data: &mut [u8]) -> Result<(), Error> {
953 self.with_core_halted(|armv8a| {
954 let (prefix, aligned, suffix) = armv8a.aligned_to_32_mut(address, data);
955 let mut address = address;
956
957 if !prefix.is_empty() {
959 armv8a.read_cpu_memory_aarch64_bytes(address, prefix)?;
960 address += u64::try_from(prefix.len()).unwrap();
961 }
962
963 armv8a.read_cpu_memory_aarch64_fast_inner(address, aligned)?;
965 address += u64::try_from(aligned.len()).unwrap();
966
967 if !suffix.is_empty() {
969 armv8a.read_cpu_memory_aarch64_bytes(address, suffix)?;
970 }
971
972 Ok(())
973 })
974 }
975
976 fn read_cpu_memory_aarch64_fast_inner(
979 &mut self,
980 address: u64,
981 data: &mut [u8],
982 ) -> Result<(), Error> {
983 if data.is_empty() {
985 return Ok(());
986 }
987 if !data.len().is_multiple_of(4) || !address.is_multiple_of(4) {
988 return Err(MemoryNotAlignedError {
989 address,
990 alignment: 4,
991 }
992 .into());
993 }
994
995 self.prepare_for_clobber(0)?;
998 self.prepare_for_clobber(1)?;
999
1000 self.set_reg_value(0, address)?;
1002
1003 let msr_instruction = aarch64::build_msr(2, 3, 0, 4, 0, 0);
1005 let editr_address = Editr::get_mmio_address_from_base(self.base_address)?;
1006 self.memory.write_word_32(editr_address, msr_instruction)?;
1007
1008 let edscr_address = Edscr::get_mmio_address_from_base(self.base_address)?;
1010 let start = Instant::now();
1011 while !{
1012 if start.elapsed() > OPERATION_TIMEOUT {
1013 return Err(Error::Timeout);
1014 }
1015 Edscr(self.memory.read_word_32(edscr_address)?)
1016 }
1017 .txfull()
1018 {}
1019
1020 let dbgdtr_tx_address = Dbgdtrtx::get_mmio_address_from_base(self.base_address)?;
1021 let (data, last) = data.split_at_mut(data.len() - std::mem::size_of::<u32>());
1022
1023 self.with_memory_access_mode(|armv8a| {
1024 let _ = armv8a.memory.read_word_32(dbgdtr_tx_address)?;
1026 for d in data.chunks_mut(4) {
1027 let tmp = armv8a.memory.read_word_32(dbgdtr_tx_address)?.to_le_bytes();
1029 d.copy_from_slice(&tmp);
1030 }
1031
1032 Ok(())
1033 })?;
1034
1035 let l = self.memory.read_word_32(dbgdtr_tx_address)?.to_le_bytes();
1037 last.copy_from_slice(&l);
1038
1039 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
1041 let edscr = Edscr(self.memory.read_word_32(address)?);
1042 if edscr.err() {
1043 let edrcr_address = Edrcr::get_mmio_address_from_base(self.base_address)?;
1045 let mut edrcr = Edrcr(0);
1046 edrcr.set_cse(true);
1047 self.memory.write_word_32(edrcr_address, edrcr.into())?;
1048
1049 Err(Error::Arm(ArmError::Armv8a(Armv8aError::DataAbort)))
1050 } else {
1051 Ok(())
1052 }
1053 }
1054
1055 fn set_core_status(&mut self, new_status: CoreStatus) {
1056 super::update_core_status(&mut self.memory, &mut self.state.current_state, new_status);
1057 }
1058}
1059
1060impl CoreInterface for Armv8a<'_> {
1061 fn wait_for_core_halted(&mut self, timeout: Duration) -> Result<(), Error> {
1062 let start = Instant::now();
1064
1065 while !self.core_halted()? {
1066 if start.elapsed() >= timeout {
1067 return Err(Error::Arm(ArmError::Timeout));
1068 }
1069 std::thread::sleep(Duration::from_millis(1));
1071 }
1072
1073 Ok(())
1074 }
1075
1076 fn core_halted(&mut self) -> Result<bool, Error> {
1077 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
1078 let edscr = Edscr(self.memory.read_word_32(address)?);
1079
1080 Ok(edscr.halted())
1081 }
1082
1083 fn status(&mut self) -> Result<crate::core::CoreStatus, Error> {
1084 let address = Edscr::get_mmio_address_from_base(self.base_address)?;
1086 let edscr = Edscr(self.memory.read_word_32(address)?);
1087
1088 if edscr.halted() {
1089 let reason = edscr.halt_reason();
1090
1091 self.set_core_status(CoreStatus::Halted(reason));
1092 self.state.is_64_bit = edscr.currently_64_bit();
1093
1094 return Ok(CoreStatus::Halted(reason));
1095 }
1096 if self.state.current_state.is_halted() {
1098 tracing::warn!("Core is running, but we expected it to be halted");
1099 }
1100
1101 self.set_core_status(CoreStatus::Running);
1102
1103 Ok(CoreStatus::Running)
1104 }
1105
1106 fn halt(&mut self, timeout: Duration) -> Result<CoreInformation, Error> {
1107 if !matches!(self.state.current_state, CoreStatus::Halted(_)) {
1108 let mut cti_gate = CtiGate(0);
1110 cti_gate.set_en(0, 1);
1111
1112 let address = CtiGate::get_mmio_address_from_base(self.cti_address)?;
1113 self.memory.write_word_32(address, cti_gate.into())?;
1114
1115 let mut pulse = CtiApppulse(0);
1117 pulse.set_apppulse(0, 1);
1118
1119 let address = CtiApppulse::get_mmio_address_from_base(self.cti_address)?;
1120 self.memory.write_word_32(address, pulse.into())?;
1121
1122 self.wait_for_core_halted(timeout)?;
1124
1125 self.reset_register_cache();
1127 }
1128
1129 let _ = self.status()?;
1131
1132 let cti_gate = CtiGate(0);
1134
1135 let address = CtiGate::get_mmio_address_from_base(self.cti_address)?;
1136 self.memory.write_word_32(address, cti_gate.into())?;
1137
1138 let pc_value = self.read_core_reg(self.program_counter().into())?;
1140
1141 Ok(CoreInformation {
1143 pc: pc_value.try_into()?,
1144 })
1145 }
1146
1147 fn run(&mut self) -> Result<(), Error> {
1148 if matches!(self.state.current_state, CoreStatus::Running) {
1149 return Ok(());
1150 }
1151
1152 self.writeback_registers()?;
1154
1155 self.ack_cti_halt()?;
1156
1157 let mut cti_gate = CtiGate(0);
1159 cti_gate.set_en(1, 1);
1160
1161 let address = CtiGate::get_mmio_address_from_base(self.cti_address)?;
1162 self.memory.write_word_32(address, cti_gate.into())?;
1163
1164 let mut pulse = CtiApppulse(0);
1166 pulse.set_apppulse(1, 1);
1167
1168 let address = CtiApppulse::get_mmio_address_from_base(self.cti_address)?;
1169 self.memory.write_word_32(address, pulse.into())?;
1170
1171 let address = Edprsr::get_mmio_address_from_base(self.base_address)?;
1173
1174 let start = Instant::now();
1175 loop {
1176 let edprsr = Edprsr(self.memory.read_word_32(address)?);
1177 if edprsr.sdr() {
1178 break;
1179 }
1180 if start.elapsed() > OPERATION_TIMEOUT {
1181 return Err(Error::Timeout);
1182 }
1183 }
1184
1185 self.set_core_status(CoreStatus::Running);
1187 let _ = self.status()?;
1188
1189 let cti_gate = CtiGate(0);
1191
1192 let address = CtiGate::get_mmio_address_from_base(self.cti_address)?;
1193 self.memory.write_word_32(address, cti_gate.into())?;
1194
1195 Ok(())
1196 }
1197
1198 fn reset(&mut self) -> Result<(), Error> {
1199 self.sequence.reset_system(
1200 &mut *self.memory,
1201 crate::CoreType::Armv8a,
1202 Some(self.base_address),
1203 )?;
1204
1205 self.reset_register_cache();
1207
1208 self.set_core_status(CoreStatus::Running);
1210 let _ = self.status()?;
1211
1212 Ok(())
1213 }
1214
1215 fn reset_and_halt(&mut self, timeout: Duration) -> Result<CoreInformation, Error> {
1216 self.sequence.reset_catch_set(
1217 &mut *self.memory,
1218 crate::CoreType::Armv8a,
1219 Some(self.base_address),
1220 )?;
1221 self.sequence.reset_system(
1222 &mut *self.memory,
1223 crate::CoreType::Armv8a,
1224 Some(self.base_address),
1225 )?;
1226
1227 self.sequence.reset_catch_clear(
1229 &mut *self.memory,
1230 crate::CoreType::Armv8a,
1231 Some(self.base_address),
1232 )?;
1233
1234 self.wait_for_core_halted(timeout)?;
1235
1236 let _ = self.status()?;
1238
1239 self.reset_register_cache();
1241
1242 let pc_value = self.read_core_reg(self.program_counter().into())?;
1244
1245 Ok(CoreInformation {
1247 pc: pc_value.try_into()?,
1248 })
1249 }
1250
1251 fn step(&mut self) -> Result<CoreInformation, Error> {
1252 let edecr_address = Edecr::get_mmio_address_from_base(self.base_address)?;
1254 let mut edecr = Edecr(self.memory.read_word_32(edecr_address)?);
1255
1256 edecr.set_ss(true);
1257 self.memory.write_word_32(edecr_address, edecr.into())?;
1258
1259 self.run()?;
1261
1262 self.wait_for_core_halted(Duration::from_millis(100))?;
1264
1265 edecr.set_ss(false);
1267 self.memory.write_word_32(edecr_address, edecr.into())?;
1268
1269 let pc_value = self.read_core_reg(self.program_counter().into())?;
1271
1272 Ok(CoreInformation {
1274 pc: pc_value.try_into()?,
1275 })
1276 }
1277
1278 fn read_core_reg(&mut self, address: RegisterId) -> Result<RegisterValue, Error> {
1279 let reg_num = address.0;
1280
1281 if (reg_num as usize) < self.state.register_cache.len()
1283 && let Some(cached_result) = self.state.register_cache[reg_num as usize]
1284 {
1285 return Ok(cached_result.0);
1286 }
1287
1288 let result = if self.state.is_64_bit {
1289 self.read_core_reg_64(reg_num)
1290 } else {
1291 self.read_core_reg_32(reg_num)
1292 };
1293
1294 if let Ok(value) = result {
1295 self.state.register_cache[reg_num as usize] = Some((value, false));
1296
1297 Ok(value)
1298 } else {
1299 Err(result.err().unwrap())
1300 }
1301 }
1302
1303 fn write_core_reg(&mut self, address: RegisterId, value: RegisterValue) -> Result<(), Error> {
1304 let reg_num = address.0;
1305 let current_mode = if self.state.is_64_bit { 64 } else { 32 };
1306
1307 if (reg_num as usize) >= self.state.register_cache.len() {
1308 return Err(Error::Arm(
1309 Armv8aError::InvalidRegisterNumber(reg_num, current_mode).into(),
1310 ));
1311 }
1312 self.state.register_cache[reg_num as usize] = Some((value, true));
1313
1314 Ok(())
1315 }
1316
1317 fn available_breakpoint_units(&mut self) -> Result<u32, Error> {
1318 if self.num_breakpoints.is_none() {
1319 let address = Eddfr::get_mmio_address_from_base(self.base_address)?;
1320 let eddfr = Eddfr(self.memory.read_word_32(address)?);
1321
1322 self.num_breakpoints = Some(eddfr.brps() + 1);
1323 }
1324 Ok(self.num_breakpoints.unwrap())
1325 }
1326
1327 fn hw_breakpoints(&mut self) -> Result<Vec<Option<u64>>, Error> {
1329 let mut breakpoints = vec![];
1330 let num_hw_breakpoints = self.available_breakpoint_units()? as usize;
1331
1332 for bp_unit_index in 0..num_hw_breakpoints {
1333 let bp_value_addr = Dbgbvr::get_mmio_address_from_base(self.base_address)?
1334 + (bp_unit_index * 16) as u64;
1335 let mut bp_value = self.memory.read_word_32(bp_value_addr)? as u64;
1336 bp_value |= (self.memory.read_word_32(bp_value_addr + 4)? as u64) << 32;
1337
1338 let bp_control_addr = Dbgbcr::get_mmio_address_from_base(self.base_address)?
1339 + (bp_unit_index * 16) as u64;
1340 let bp_control = Dbgbcr(self.memory.read_word_32(bp_control_addr)?);
1341
1342 if bp_control.e() {
1343 breakpoints.push(Some(bp_value));
1344 } else {
1345 breakpoints.push(None);
1346 }
1347 }
1348 Ok(breakpoints)
1349 }
1350
1351 fn enable_breakpoints(&mut self, _state: bool) -> Result<(), Error> {
1352 Ok(())
1354 }
1355
1356 fn set_hw_breakpoint(&mut self, bp_unit_index: usize, addr: u64) -> Result<(), Error> {
1357 let bp_value_addr =
1358 Dbgbvr::get_mmio_address_from_base(self.base_address)? + (bp_unit_index * 16) as u64;
1359 let bp_control_addr =
1360 Dbgbcr::get_mmio_address_from_base(self.base_address)? + (bp_unit_index * 16) as u64;
1361 let mut bp_control = Dbgbcr(0);
1362
1363 bp_control.set_bt(0b0000);
1365 bp_control.set_hmc(true);
1367 bp_control.set_pmc(0b11);
1368 bp_control.set_bas(0b1111);
1370 bp_control.set_e(true);
1372
1373 let addr_low = addr as u32;
1374 let addr_high = (addr >> 32) as u32;
1375
1376 self.memory.write_word_32(bp_value_addr, addr_low)?;
1377 self.memory.write_word_32(bp_value_addr + 4, addr_high)?;
1378 self.memory
1379 .write_word_32(bp_control_addr, bp_control.into())?;
1380
1381 Ok(())
1382 }
1383
1384 fn clear_hw_breakpoint(&mut self, bp_unit_index: usize) -> Result<(), Error> {
1385 let bp_value_addr =
1386 Dbgbvr::get_mmio_address_from_base(self.base_address)? + (bp_unit_index * 16) as u64;
1387 let bp_control_addr =
1388 Dbgbcr::get_mmio_address_from_base(self.base_address)? + (bp_unit_index * 16) as u64;
1389
1390 self.memory.write_word_32(bp_value_addr, 0)?;
1391 self.memory.write_word_32(bp_value_addr + 4, 0)?;
1392 self.memory.write_word_32(bp_control_addr, 0)?;
1393
1394 Ok(())
1395 }
1396
1397 fn registers(&self) -> &'static CoreRegisters {
1398 if self.state.is_64_bit {
1399 &AARCH64_CORE_REGISTERS
1400 } else {
1401 &AARCH32_WITH_FP_32_CORE_REGISTERS
1402 }
1403 }
1404
1405 fn program_counter(&self) -> &'static CoreRegister {
1406 if self.state.is_64_bit {
1407 &super::registers::aarch64::PC
1408 } else {
1409 &super::registers::cortex_m::PC
1410 }
1411 }
1412
1413 fn frame_pointer(&self) -> &'static CoreRegister {
1414 if self.state.is_64_bit {
1415 &super::registers::aarch64::FP
1416 } else {
1417 &super::registers::cortex_m::FP
1418 }
1419 }
1420
1421 fn stack_pointer(&self) -> &'static CoreRegister {
1422 if self.state.is_64_bit {
1423 &super::registers::aarch64::SP
1424 } else {
1425 &super::registers::cortex_m::SP
1426 }
1427 }
1428
1429 fn return_address(&self) -> &'static CoreRegister {
1430 if self.state.is_64_bit {
1431 &super::registers::aarch64::RA
1432 } else {
1433 &super::registers::cortex_m::RA
1434 }
1435 }
1436
1437 fn hw_breakpoints_enabled(&self) -> bool {
1438 true
1439 }
1440
1441 fn architecture(&self) -> Architecture {
1442 Architecture::Arm
1443 }
1444
1445 fn core_type(&self) -> CoreType {
1446 CoreType::Armv8a
1447 }
1448
1449 fn instruction_set(&mut self) -> Result<InstructionSet, Error> {
1450 if self.state.is_64_bit {
1451 Ok(InstructionSet::A64)
1452 } else {
1453 let cpsr: u32 = self.read_core_reg(RegisterId(16))?.try_into()?;
1454
1455 match (cpsr >> 5) & 1 {
1457 1 => Ok(InstructionSet::Thumb2),
1458 _ => Ok(InstructionSet::A32),
1459 }
1460 }
1461 }
1462
1463 fn fpu_support(&mut self) -> Result<bool, crate::error::Error> {
1464 Ok(true)
1466 }
1467
1468 fn floating_point_register_count(&mut self) -> Result<usize, crate::error::Error> {
1469 Ok(self.state.fp_reg_count)
1471 }
1472
1473 #[tracing::instrument(skip(self))]
1474 fn reset_catch_set(&mut self) -> Result<(), Error> {
1475 self.sequence.reset_catch_set(
1476 &mut *self.memory,
1477 CoreType::Armv8a,
1478 Some(self.base_address),
1479 )?;
1480
1481 Ok(())
1482 }
1483
1484 #[tracing::instrument(skip(self))]
1485 fn reset_catch_clear(&mut self) -> Result<(), Error> {
1486 self.sequence.reset_catch_clear(
1487 &mut *self.memory,
1488 CoreType::Armv8a,
1489 Some(self.base_address),
1490 )?;
1491
1492 Ok(())
1493 }
1494
1495 #[tracing::instrument(skip(self))]
1496 fn debug_core_stop(&mut self) -> Result<(), Error> {
1497 if matches!(self.state.current_state, CoreStatus::Halted(_)) {
1498 self.writeback_registers()?;
1501 }
1502
1503 self.sequence
1504 .debug_core_stop(&mut *self.memory, CoreType::Armv8a)?;
1505
1506 Ok(())
1507 }
1508
1509 fn is_64_bit(&self) -> bool {
1510 self.state.is_64_bit
1511 }
1512}
1513
1514impl MemoryInterface for Armv8a<'_> {
1515 fn supports_native_64bit_access(&mut self) -> bool {
1516 self.state.is_64_bit
1517 }
1518
1519 fn read_word_64(&mut self, address: u64) -> Result<u64, Error> {
1520 if self.state.is_64_bit {
1521 self.read_cpu_memory_aarch64_64(address)
1522 } else {
1523 let mut ret = self.read_cpu_memory_aarch32_32(address)? as u64;
1524 ret |= (self.read_cpu_memory_aarch32_32(address + 4)? as u64) << 32;
1525
1526 Ok(ret)
1527 }
1528 }
1529
1530 fn read_word_32(&mut self, address: u64) -> Result<u32, Error> {
1531 if self.state.is_64_bit {
1532 self.read_cpu_memory_aarch64_32(address)
1533 } else {
1534 self.read_cpu_memory_aarch32_32(address)
1535 }
1536 }
1537
1538 fn read_word_16(&mut self, address: u64) -> Result<u16, Error> {
1539 let byte_offset = address % 4;
1541 let word_start = address - byte_offset;
1542
1543 let data = self.read_word_32(word_start)?;
1545
1546 Ok((data >> (byte_offset * 8)) as u16)
1548 }
1549
1550 fn read_word_8(&mut self, address: u64) -> Result<u8, Error> {
1551 let byte_offset = address % 4;
1553 let word_start = address - byte_offset;
1554
1555 let data = self.read_word_32(word_start)?;
1557
1558 Ok(data.to_le_bytes()[byte_offset as usize])
1560 }
1561
1562 fn read_64(&mut self, address: u64, data: &mut [u64]) -> Result<(), Error> {
1563 if self.state.is_64_bit {
1564 let (_prefix, data, _suffix) = unsafe { data.align_to_mut::<u8>() };
1565 self.read_cpu_memory_aarch64_fast(address, data)?;
1566 } else {
1567 for (i, word) in data.iter_mut().enumerate() {
1568 *word = self.read_word_64(address + ((i as u64) * 8))?;
1569 }
1570 }
1571
1572 Ok(())
1573 }
1574
1575 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), Error> {
1576 if self.state.is_64_bit {
1577 let (_prefix, data, _suffix) = unsafe { data.align_to_mut::<u8>() };
1578 self.read_cpu_memory_aarch64_fast(address, data)?;
1579 } else {
1580 for (i, word) in data.iter_mut().enumerate() {
1581 *word = self.read_word_32(address + ((i as u64) * 4))?;
1582 }
1583 }
1584
1585 Ok(())
1586 }
1587
1588 fn read_16(&mut self, address: u64, data: &mut [u16]) -> Result<(), Error> {
1589 if self.state.is_64_bit {
1590 let (_prefix, data, _suffix) = unsafe { data.align_to_mut::<u8>() };
1591 self.read_cpu_memory_aarch64_fast(address, data)?;
1592 } else {
1593 for (i, word) in data.iter_mut().enumerate() {
1594 *word = self.read_word_16(address + ((i as u64) * 2))?;
1595 }
1596 }
1597
1598 Ok(())
1599 }
1600
1601 fn read_8(&mut self, address: u64, data: &mut [u8]) -> Result<(), Error> {
1602 if self.state.is_64_bit {
1603 self.read_cpu_memory_aarch64_fast(address, data)?;
1604 } else {
1605 for (i, byte) in data.iter_mut().enumerate() {
1606 *byte = self.read_word_8(address + (i as u64))?;
1607 }
1608 }
1609
1610 Ok(())
1611 }
1612
1613 fn write_word_64(&mut self, address: u64, data: u64) -> Result<(), Error> {
1614 if self.state.is_64_bit {
1615 self.write_cpu_memory_aarch64_64(address, data)
1616 } else {
1617 let low_word = data as u32;
1618 let high_word = (data >> 32) as u32;
1619
1620 self.write_cpu_memory_aarch32_32(address, low_word)?;
1621 self.write_cpu_memory_aarch32_32(address + 4, high_word)
1622 }
1623 }
1624
1625 fn write_word_32(&mut self, address: u64, data: u32) -> Result<(), Error> {
1626 if self.state.is_64_bit {
1627 self.write_cpu_memory_aarch64_32(address, data)
1628 } else {
1629 self.write_cpu_memory_aarch32_32(address, data)
1630 }
1631 }
1632
1633 fn write_word_16(&mut self, address: u64, data: u16) -> Result<(), Error> {
1634 let byte_offset = address % 4;
1636 let word_start = address - byte_offset;
1637
1638 let mut word = self.read_word_32(word_start)?;
1640
1641 word &= !(0xFFFFu32 << (byte_offset * 8));
1643 word |= (data as u32) << (byte_offset * 8);
1644
1645 self.write_word_32(word_start, word)
1646 }
1647
1648 fn write_word_8(&mut self, address: u64, data: u8) -> Result<(), Error> {
1649 let byte_offset = address % 4;
1651 let word_start = address - byte_offset;
1652
1653 let current_word = self.read_word_32(word_start)?;
1655 let mut word_bytes = current_word.to_le_bytes();
1656 word_bytes[byte_offset as usize] = data;
1657
1658 self.write_word_32(word_start, u32::from_le_bytes(word_bytes))
1659 }
1660
1661 fn write_64(&mut self, address: u64, data: &[u64]) -> Result<(), Error> {
1662 let (_prefix, data, _suffix) = unsafe { data.align_to::<u8>() };
1664 self.write_cpu_memory_fast(address, data)?;
1665
1666 Ok(())
1667 }
1668
1669 fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), Error> {
1670 let (_prefix, data, _suffix) = unsafe { data.align_to::<u8>() };
1671 self.write_cpu_memory_fast(address, data)?;
1672
1673 Ok(())
1674 }
1675
1676 fn write_16(&mut self, address: u64, data: &[u16]) -> Result<(), Error> {
1677 let (_prefix, data, _suffix) = unsafe { data.align_to::<u8>() };
1678 self.write_cpu_memory_fast(address, data)?;
1679
1680 Ok(())
1681 }
1682
1683 fn write_8(&mut self, address: u64, data: &[u8]) -> Result<(), Error> {
1684 self.write_cpu_memory_fast(address, data)?;
1685
1686 Ok(())
1687 }
1688
1689 fn supports_8bit_transfers(&self) -> Result<bool, Error> {
1690 Ok(false)
1691 }
1692
1693 fn flush(&mut self) -> Result<(), Error> {
1694 Ok(())
1696 }
1697}
1698
1699#[cfg(test)]
1700mod test {
1701 use crate::{
1702 architecture::arm::{
1703 FullyQualifiedApAddress, communication_interface::SwdSequence,
1704 sequences::DefaultArmSequence,
1705 },
1706 probe::DebugProbeError,
1707 };
1708
1709 use super::*;
1710
1711 const TEST_BASE_ADDRESS: u64 = 0x8000_1000;
1712 const TEST_CTI_ADDRESS: u64 = 0x8000_2000;
1713
1714 fn address_to_reg_num(address: u64) -> u32 {
1715 ((address - TEST_BASE_ADDRESS) / 4) as u32
1716 }
1717
1718 pub struct ExpectedMemoryOp {
1719 read: bool,
1720 address: u64,
1721 value: u32,
1722 }
1723
1724 pub struct MockProbe {
1725 expected_ops: Vec<ExpectedMemoryOp>,
1726 is_64_bit: bool,
1727 }
1728
1729 impl MockProbe {
1730 pub fn new(is_64_bit: bool) -> Self {
1731 MockProbe {
1732 expected_ops: vec![],
1733 is_64_bit,
1734 }
1735 }
1736
1737 pub fn expected_read(&mut self, addr: u64, value: u32) {
1738 self.expected_ops.push(ExpectedMemoryOp {
1739 read: true,
1740 address: addr,
1741 value,
1742 });
1743 }
1744
1745 pub fn expected_write(&mut self, addr: u64, value: u32) {
1746 self.expected_ops.push(ExpectedMemoryOp {
1747 read: false,
1748 address: addr,
1749 value,
1750 });
1751 }
1752 }
1753 impl MemoryInterface<ArmError> for MockProbe {
1754 fn read_8(&mut self, _address: u64, _data: &mut [u8]) -> Result<(), ArmError> {
1755 todo!()
1756 }
1757
1758 fn read_16(&mut self, _address: u64, _data: &mut [u16]) -> Result<(), ArmError> {
1759 todo!()
1760 }
1761
1762 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), ArmError> {
1763 if self.expected_ops.is_empty() {
1764 panic!(
1765 "Received unexpected read_32 op: register {:#}",
1766 address_to_reg_num(address)
1767 );
1768 }
1769
1770 assert_eq!(data.len(), 1);
1771
1772 let expected_op = self.expected_ops.remove(0);
1773
1774 assert!(
1775 expected_op.read,
1776 "R/W mismatch for register: Expected {:#} Actual: {:#}",
1777 address_to_reg_num(expected_op.address),
1778 address_to_reg_num(address)
1779 );
1780 assert_eq!(
1781 expected_op.address,
1782 address,
1783 "Read from unexpected register: Expected {:#} Actual: {:#}",
1784 address_to_reg_num(expected_op.address),
1785 address_to_reg_num(address)
1786 );
1787
1788 data[0] = expected_op.value;
1789
1790 Ok(())
1791 }
1792
1793 fn write_8(&mut self, _address: u64, _data: &[u8]) -> Result<(), ArmError> {
1794 todo!()
1795 }
1796
1797 fn write_16(&mut self, _address: u64, _data: &[u16]) -> Result<(), ArmError> {
1798 todo!()
1799 }
1800
1801 fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), ArmError> {
1802 if self.expected_ops.is_empty() {
1803 panic!(
1804 "Received unexpected write_32 op: register {:#}",
1805 address_to_reg_num(address)
1806 );
1807 }
1808
1809 assert_eq!(data.len(), 1);
1810
1811 let expected_op = self.expected_ops.remove(0);
1812
1813 assert!(!expected_op.read);
1814 assert_eq!(
1815 expected_op.address,
1816 address,
1817 "Write to unexpected register: Expected {:#} Actual: {:#}",
1818 address_to_reg_num(expected_op.address),
1819 address_to_reg_num(address)
1820 );
1821
1822 assert_eq!(
1823 expected_op.value, data[0],
1824 "Write value mismatch Expected {:#X} Actual: {:#X}",
1825 expected_op.value, data[0]
1826 );
1827
1828 Ok(())
1829 }
1830
1831 fn read_64(&mut self, _address: u64, _data: &mut [u64]) -> Result<(), ArmError> {
1832 todo!()
1833 }
1834
1835 fn write_64(&mut self, _address: u64, _data: &[u64]) -> Result<(), ArmError> {
1836 todo!()
1837 }
1838
1839 fn flush(&mut self) -> Result<(), ArmError> {
1840 todo!()
1841 }
1842
1843 fn supports_8bit_transfers(&self) -> Result<bool, ArmError> {
1844 Ok(false)
1845 }
1846
1847 fn supports_native_64bit_access(&mut self) -> bool {
1848 false
1849 }
1850 }
1851
1852 impl ArmMemoryInterface for MockProbe {
1853 fn fully_qualified_address(&self) -> FullyQualifiedApAddress {
1854 todo!()
1855 }
1856
1857 fn get_arm_debug_interface(
1858 &mut self,
1859 ) -> Result<&mut dyn crate::architecture::arm::ArmDebugInterface, DebugProbeError> {
1860 Err(DebugProbeError::NotImplemented {
1861 function_name: "get_arm_debug_interface",
1862 })
1863 }
1864
1865 fn generic_status(&mut self) -> Result<crate::architecture::arm::ap::CSW, ArmError> {
1866 Err(ArmError::Probe(DebugProbeError::NotImplemented {
1867 function_name: "generic_status",
1868 }))
1869 }
1870
1871 fn base_address(&mut self) -> Result<u64, ArmError> {
1872 todo!()
1873 }
1874 }
1875
1876 impl SwdSequence for MockProbe {
1877 fn swj_sequence(&mut self, _bit_len: u8, _bits: u64) -> Result<(), DebugProbeError> {
1878 todo!()
1879 }
1880
1881 fn swj_pins(
1882 &mut self,
1883 _pin_out: u32,
1884 _pin_select: u32,
1885 _pin_wait: u32,
1886 ) -> Result<u32, DebugProbeError> {
1887 todo!()
1888 }
1889 }
1890
1891 fn add_status_expectations(probe: &mut MockProbe, halted: bool) {
1892 let mut edscr = Edscr(0);
1893 edscr.set_status(if halted { 0b010011 } else { 0b000010 });
1894 if probe.is_64_bit {
1895 edscr.set_rw(0b1111);
1896 }
1897 probe.expected_read(
1898 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1899 edscr.into(),
1900 );
1901 }
1902
1903 fn add_read_reg_expectations(probe: &mut MockProbe, reg: u16, value: u32) {
1904 probe.expected_write(
1905 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1906 prep_instr_for_itr_32(build_mcr(14, 0, reg, 0, 5, 0)),
1907 );
1908 let mut edscr = Edscr(0);
1909 edscr.set_ite(true);
1910 edscr.set_txfull(true);
1911
1912 probe.expected_read(
1913 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1914 edscr.into(),
1915 );
1916 probe.expected_read(
1917 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1918 value,
1919 );
1920 }
1921
1922 fn add_read_reg_64_expectations(probe: &mut MockProbe, reg: u16, value: u64) {
1923 probe.expected_write(
1924 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1925 aarch64::build_msr(2, 3, 0, 4, 0, reg),
1926 );
1927 let mut edscr = Edscr(0);
1928 edscr.set_ite(true);
1929 edscr.set_txfull(true);
1930
1931 probe.expected_read(
1932 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1933 edscr.into(),
1934 );
1935 probe.expected_read(
1936 Dbgdtrrx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1937 (value >> 32) as u32,
1938 );
1939 probe.expected_read(
1940 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1941 value as u32,
1942 );
1943 }
1944
1945 fn add_read_pc_expectations(probe: &mut MockProbe, value: u32) {
1946 let mut edscr = Edscr(0);
1947 edscr.set_ite(true);
1948 edscr.set_txfull(true);
1949
1950 probe.expected_write(
1951 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1952 prep_instr_for_itr_32(build_mrc(15, 3, 0, 4, 5, 1)),
1953 );
1954 probe.expected_read(
1955 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1956 edscr.into(),
1957 );
1958 add_read_reg_expectations(probe, 0, value);
1959 }
1960
1961 fn add_read_pc_64_expectations(probe: &mut MockProbe, value: u64) {
1962 let mut edscr = Edscr(0);
1963 edscr.set_ite(true);
1964 edscr.set_txfull(true);
1965
1966 probe.expected_write(
1967 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1968 aarch64::build_mrs(3, 3, 4, 5, 1, 0),
1969 );
1970 probe.expected_read(
1971 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1972 edscr.into(),
1973 );
1974 add_read_reg_64_expectations(probe, 0, value);
1975 }
1976
1977 fn add_read_cpsr_expectations(probe: &mut MockProbe, value: u32) {
1978 let mut edscr = Edscr(0);
1979 edscr.set_ite(true);
1980 edscr.set_txfull(true);
1981
1982 probe.expected_write(
1983 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1984 prep_instr_for_itr_32(build_mrc(15, 3, 0, 4, 5, 0)),
1985 );
1986 probe.expected_read(
1987 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
1988 edscr.into(),
1989 );
1990 add_read_reg_expectations(probe, 0, value);
1991 }
1992
1993 fn add_read_cpsr_64_expectations(probe: &mut MockProbe, value: u32) {
1994 let mut edscr = Edscr(0);
1995 edscr.set_ite(true);
1996 edscr.set_txfull(true);
1997
1998 probe.expected_write(
1999 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2000 aarch64::build_mrs(3, 3, 4, 5, 0, 0),
2001 );
2002 probe.expected_read(
2003 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2004 edscr.into(),
2005 );
2006 add_read_reg_64_expectations(probe, 0, value.into());
2007 }
2008
2009 fn add_halt_expectations(probe: &mut MockProbe) {
2010 let mut cti_gate = CtiGate(0);
2011 cti_gate.set_en(0, 1);
2012
2013 probe.expected_write(
2014 CtiGate::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2015 cti_gate.into(),
2016 );
2017
2018 let mut pulse = CtiApppulse(0);
2019 pulse.set_apppulse(0, 1);
2020
2021 probe.expected_write(
2022 CtiApppulse::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2023 pulse.into(),
2024 );
2025 }
2026
2027 fn add_halt_cleanup_expectations(probe: &mut MockProbe) {
2028 let cti_gate = CtiGate(0);
2029
2030 probe.expected_write(
2031 CtiGate::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2032 cti_gate.into(),
2033 );
2034 }
2035
2036 fn add_resume_expectations(probe: &mut MockProbe) {
2037 let mut ack = CtiIntack(0);
2038 ack.set_ack(0, 1);
2039
2040 probe.expected_write(
2041 CtiIntack::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2042 ack.into(),
2043 );
2044
2045 let status = CtiTrigoutstatus(0);
2046 probe.expected_read(
2047 CtiTrigoutstatus::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2048 status.into(),
2049 );
2050
2051 let mut cti_gate = CtiGate(0);
2052 cti_gate.set_en(1, 1);
2053 probe.expected_write(
2054 CtiGate::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2055 cti_gate.into(),
2056 );
2057
2058 let mut pulse = CtiApppulse(0);
2059 pulse.set_apppulse(1, 1);
2060 probe.expected_write(
2061 CtiApppulse::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2062 pulse.into(),
2063 );
2064
2065 let mut edprsr = Edprsr(0);
2066 edprsr.set_sdr(true);
2067 probe.expected_read(
2068 Edprsr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2069 edprsr.into(),
2070 );
2071 }
2072
2073 fn add_resume_cleanup_expectations(probe: &mut MockProbe) {
2074 let cti_gate = CtiGate(0);
2075 probe.expected_write(
2076 CtiGate::get_mmio_address_from_base(TEST_CTI_ADDRESS).unwrap(),
2077 cti_gate.into(),
2078 );
2079 }
2080
2081 fn add_idr_expectations(probe: &mut MockProbe, bp_count: u32) {
2082 let mut eddfr = Eddfr(0);
2083 eddfr.set_brps(bp_count - 1);
2084 probe.expected_read(
2085 Eddfr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2086 eddfr.into(),
2087 );
2088 }
2089
2090 fn add_set_r0_expectation(probe: &mut MockProbe, value: u32) {
2091 let mut edscr = Edscr(0);
2092 edscr.set_ite(true);
2093 edscr.set_rxfull(true);
2094
2095 probe.expected_write(
2096 Dbgdtrrx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2097 value,
2098 );
2099 probe.expected_read(
2100 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2101 edscr.into(),
2102 );
2103
2104 probe.expected_write(
2105 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2106 prep_instr_for_itr_32(build_mrc(14, 0, 0, 0, 5, 0)),
2107 );
2108 probe.expected_read(
2109 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2110 edscr.into(),
2111 );
2112 }
2113
2114 fn add_set_x0_expectation(probe: &mut MockProbe, value: u64) {
2115 let mut edscr = Edscr(0);
2116 edscr.set_ite(true);
2117 edscr.set_rxfull(true);
2118
2119 probe.expected_write(
2120 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2121 (value >> 32) as u32,
2122 );
2123 probe.expected_write(
2124 Dbgdtrrx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2125 value as u32,
2126 );
2127 probe.expected_read(
2128 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2129 edscr.into(),
2130 );
2131
2132 probe.expected_write(
2133 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2134 aarch64::build_mrs(2, 3, 0, 4, 0, 0),
2135 );
2136 probe.expected_read(
2137 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2138 edscr.into(),
2139 );
2140 }
2141
2142 fn add_read_memory_expectations(probe: &mut MockProbe, address: u64, value: u32) {
2143 add_set_r0_expectation(probe, address as u32);
2144
2145 let mut edscr = Edscr(0);
2146 edscr.set_ite(true);
2147 edscr.set_txfull(true);
2148
2149 probe.expected_write(
2150 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2151 prep_instr_for_itr_32(build_ldr(1, 0, 4)),
2152 );
2153 probe.expected_read(
2154 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2155 edscr.into(),
2156 );
2157
2158 probe.expected_write(
2159 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2160 prep_instr_for_itr_32(build_mcr(14, 0, 1, 0, 5, 0)),
2161 );
2162 probe.expected_read(
2163 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2164 edscr.into(),
2165 );
2166 probe.expected_read(
2167 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2168 value,
2169 );
2170 }
2171
2172 fn add_read_memory_aarch64_expectations(probe: &mut MockProbe, address: u64, value: u32) {
2173 add_set_x0_expectation(probe, address);
2174
2175 let mut edscr = Edscr(0);
2176 edscr.set_ite(true);
2177 edscr.set_txfull(true);
2178
2179 probe.expected_write(
2180 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2181 aarch64::build_ldrw(1, 0, 4),
2182 );
2183 probe.expected_read(
2184 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2185 edscr.into(),
2186 );
2187
2188 probe.expected_write(
2189 Editr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2190 aarch64::build_msr(2, 3, 0, 5, 0, 1),
2191 );
2192 probe.expected_read(
2193 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2194 edscr.into(),
2195 );
2196 probe.expected_read(
2197 Dbgdtrtx::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2198 value,
2199 );
2200 }
2201
2202 #[test]
2203 fn armv8a_new() {
2204 let mut probe = MockProbe::new(false);
2205
2206 add_status_expectations(&mut probe, true);
2208
2209 let mock_mem = Box::new(probe) as _;
2210
2211 let mut state = CortexAState::new();
2212
2213 let core = Armv8a::new(
2214 mock_mem,
2215 &mut state,
2216 TEST_BASE_ADDRESS,
2217 TEST_CTI_ADDRESS,
2218 DefaultArmSequence::create(),
2219 )
2220 .unwrap();
2221
2222 assert!(!core.state.is_64_bit);
2223 }
2224
2225 #[test]
2226 fn armv8a_core_halted() {
2227 let mut probe = MockProbe::new(false);
2228 let mut state = CortexAState::new();
2229
2230 add_status_expectations(&mut probe, true);
2232
2233 let mut edscr = Edscr(0);
2234 edscr.set_status(0b000010);
2235 probe.expected_read(
2236 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2237 edscr.into(),
2238 );
2239
2240 edscr.set_status(0b010011);
2241 probe.expected_read(
2242 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2243 edscr.into(),
2244 );
2245
2246 let mock_mem = Box::new(probe) as _;
2247
2248 let mut armv8a = Armv8a::new(
2249 mock_mem,
2250 &mut state,
2251 TEST_BASE_ADDRESS,
2252 TEST_CTI_ADDRESS,
2253 DefaultArmSequence::create(),
2254 )
2255 .unwrap();
2256
2257 assert!(!armv8a.core_halted().unwrap());
2259 assert!(armv8a.core_halted().unwrap());
2260 }
2261
2262 #[test]
2263 fn armv8a_wait_for_core_halted() {
2264 let mut probe = MockProbe::new(false);
2265 let mut state = CortexAState::new();
2266
2267 add_status_expectations(&mut probe, true);
2269
2270 let mut edscr = Edscr(0);
2271 edscr.set_status(0b000010);
2272 probe.expected_read(
2273 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2274 edscr.into(),
2275 );
2276
2277 edscr.set_status(0b010011);
2278 probe.expected_read(
2279 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2280 edscr.into(),
2281 );
2282
2283 let mock_mem = Box::new(probe) as _;
2284
2285 let mut armv8a = Armv8a::new(
2286 mock_mem,
2287 &mut state,
2288 TEST_BASE_ADDRESS,
2289 TEST_CTI_ADDRESS,
2290 DefaultArmSequence::create(),
2291 )
2292 .unwrap();
2293
2294 armv8a
2296 .wait_for_core_halted(Duration::from_millis(100))
2297 .unwrap();
2298 }
2299
2300 #[test]
2301 fn armv8a_status_running() {
2302 let mut probe = MockProbe::new(false);
2303 let mut state = CortexAState::new();
2304
2305 add_status_expectations(&mut probe, true);
2307
2308 let mut edscr = Edscr(0);
2309 edscr.set_status(0b000010);
2310 probe.expected_read(
2311 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2312 edscr.into(),
2313 );
2314
2315 let mock_mem = Box::new(probe) as _;
2316
2317 let mut armv8a = Armv8a::new(
2318 mock_mem,
2319 &mut state,
2320 TEST_BASE_ADDRESS,
2321 TEST_CTI_ADDRESS,
2322 DefaultArmSequence::create(),
2323 )
2324 .unwrap();
2325
2326 assert_eq!(CoreStatus::Running, armv8a.status().unwrap());
2327 }
2328
2329 #[test]
2330 fn armv8a_status_halted() {
2331 let mut probe = MockProbe::new(false);
2332 let mut state = CortexAState::new();
2333
2334 add_status_expectations(&mut probe, true);
2336
2337 let mut edscr = Edscr(0);
2338 edscr.set_status(0b010011);
2339 probe.expected_read(
2340 Edscr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2341 edscr.into(),
2342 );
2343
2344 let mock_mem = Box::new(probe) as _;
2345
2346 let mut armv8a = Armv8a::new(
2347 mock_mem,
2348 &mut state,
2349 TEST_BASE_ADDRESS,
2350 TEST_CTI_ADDRESS,
2351 DefaultArmSequence::create(),
2352 )
2353 .unwrap();
2354
2355 assert_eq!(
2356 CoreStatus::Halted(crate::HaltReason::Request),
2357 armv8a.status().unwrap()
2358 );
2359 }
2360
2361 #[test]
2362 fn armv8a_read_core_reg_common() {
2363 const REG_VALUE: u32 = 0xABCD;
2364
2365 let mut probe = MockProbe::new(false);
2366 let mut state = CortexAState::new();
2367
2368 add_status_expectations(&mut probe, true);
2370
2371 add_read_reg_expectations(&mut probe, 2, REG_VALUE);
2373
2374 let mock_mem = Box::new(probe) as _;
2375
2376 let mut armv8a = Armv8a::new(
2377 mock_mem,
2378 &mut state,
2379 TEST_BASE_ADDRESS,
2380 TEST_CTI_ADDRESS,
2381 DefaultArmSequence::create(),
2382 )
2383 .unwrap();
2384
2385 assert_eq!(
2387 RegisterValue::from(REG_VALUE),
2388 armv8a.read_core_reg(RegisterId(2)).unwrap()
2389 );
2390
2391 assert_eq!(
2393 RegisterValue::from(REG_VALUE),
2394 armv8a.read_core_reg(RegisterId(2)).unwrap()
2395 );
2396 }
2397
2398 #[test]
2399 fn armv8a_read_core_reg_common_64() {
2400 const REG_VALUE: u64 = 0xFFFF_EEEE_0000_ABCD;
2401
2402 let mut probe = MockProbe::new(true);
2403 let mut state = CortexAState::new();
2404
2405 add_status_expectations(&mut probe, true);
2407
2408 add_read_reg_64_expectations(&mut probe, 2, REG_VALUE);
2410
2411 let mock_mem = Box::new(probe) as _;
2412
2413 let mut armv8a = Armv8a::new(
2414 mock_mem,
2415 &mut state,
2416 TEST_BASE_ADDRESS,
2417 TEST_CTI_ADDRESS,
2418 DefaultArmSequence::create(),
2419 )
2420 .unwrap();
2421
2422 assert_eq!(
2424 RegisterValue::from(REG_VALUE),
2425 armv8a.read_core_reg(RegisterId(2)).unwrap()
2426 );
2427
2428 assert_eq!(
2430 RegisterValue::from(REG_VALUE),
2431 armv8a.read_core_reg(RegisterId(2)).unwrap()
2432 );
2433 }
2434
2435 #[test]
2436 fn armv8a_read_core_reg_pc() {
2437 const REG_VALUE: u32 = 0xABCD;
2438
2439 let mut probe = MockProbe::new(false);
2440 let mut state = CortexAState::new();
2441
2442 add_status_expectations(&mut probe, true);
2444
2445 add_read_reg_expectations(&mut probe, 0, 0);
2447 add_read_pc_expectations(&mut probe, REG_VALUE);
2448
2449 let mock_mem = Box::new(probe) as _;
2450
2451 let mut armv8a = Armv8a::new(
2452 mock_mem,
2453 &mut state,
2454 TEST_BASE_ADDRESS,
2455 TEST_CTI_ADDRESS,
2456 DefaultArmSequence::create(),
2457 )
2458 .unwrap();
2459
2460 assert_eq!(
2462 RegisterValue::from(REG_VALUE),
2463 armv8a.read_core_reg(RegisterId(15)).unwrap()
2464 );
2465
2466 assert_eq!(
2468 RegisterValue::from(REG_VALUE),
2469 armv8a.read_core_reg(RegisterId(15)).unwrap()
2470 );
2471 }
2472
2473 #[test]
2474 fn armv8a_read_core_64_reg_pc() {
2475 const REG_VALUE: u64 = 0xFFFF_EEEE_0000_ABCD;
2476
2477 let mut probe = MockProbe::new(true);
2478 let mut state = CortexAState::new();
2479
2480 add_status_expectations(&mut probe, true);
2482
2483 add_read_reg_64_expectations(&mut probe, 0, 0);
2485 add_read_pc_64_expectations(&mut probe, REG_VALUE);
2486
2487 let mock_mem = Box::new(probe) as _;
2488
2489 let mut armv8a = Armv8a::new(
2490 mock_mem,
2491 &mut state,
2492 TEST_BASE_ADDRESS,
2493 TEST_CTI_ADDRESS,
2494 DefaultArmSequence::create(),
2495 )
2496 .unwrap();
2497
2498 assert_eq!(
2500 RegisterValue::from(REG_VALUE),
2501 armv8a.read_core_reg(RegisterId(32)).unwrap()
2502 );
2503
2504 assert_eq!(
2506 RegisterValue::from(REG_VALUE),
2507 armv8a.read_core_reg(RegisterId(32)).unwrap()
2508 );
2509 }
2510
2511 #[test]
2512 fn armv8a_read_core_reg_cpsr() {
2513 const REG_VALUE: u32 = 0xABCD;
2514
2515 let mut probe = MockProbe::new(false);
2516 let mut state = CortexAState::new();
2517
2518 add_status_expectations(&mut probe, true);
2520
2521 add_read_reg_expectations(&mut probe, 0, 0);
2523 add_read_cpsr_expectations(&mut probe, REG_VALUE);
2524
2525 let mock_mem = Box::new(probe) as _;
2526
2527 let mut armv8a = Armv8a::new(
2528 mock_mem,
2529 &mut state,
2530 TEST_BASE_ADDRESS,
2531 TEST_CTI_ADDRESS,
2532 DefaultArmSequence::create(),
2533 )
2534 .unwrap();
2535
2536 assert_eq!(
2538 RegisterValue::from(REG_VALUE),
2539 armv8a.read_core_reg(RegisterId(16)).unwrap()
2540 );
2541
2542 assert_eq!(
2544 RegisterValue::from(REG_VALUE),
2545 armv8a.read_core_reg(RegisterId(16)).unwrap()
2546 );
2547 }
2548
2549 #[test]
2550 fn armv8a_read_core_64_reg_cpsr() {
2551 const REG_VALUE: u32 = 0xABCD;
2552
2553 let mut probe = MockProbe::new(true);
2554 let mut state = CortexAState::new();
2555
2556 add_status_expectations(&mut probe, true);
2558
2559 add_read_reg_64_expectations(&mut probe, 0, 0);
2561 add_read_cpsr_64_expectations(&mut probe, REG_VALUE);
2562
2563 let mock_mem = Box::new(probe) as _;
2564
2565 let mut armv8a = Armv8a::new(
2566 mock_mem,
2567 &mut state,
2568 TEST_BASE_ADDRESS,
2569 TEST_CTI_ADDRESS,
2570 DefaultArmSequence::create(),
2571 )
2572 .unwrap();
2573
2574 assert_eq!(
2576 RegisterValue::from(REG_VALUE),
2577 armv8a.read_core_reg(RegisterId(33)).unwrap()
2578 );
2579
2580 assert_eq!(
2582 RegisterValue::from(REG_VALUE),
2583 armv8a.read_core_reg(RegisterId(33)).unwrap()
2584 );
2585 }
2586
2587 #[test]
2588 fn armv8a_halt() {
2589 const REG_VALUE: u32 = 0xABCD;
2590
2591 let mut probe = MockProbe::new(false);
2592 let mut state = CortexAState::new();
2593
2594 add_status_expectations(&mut probe, false);
2596
2597 add_halt_expectations(&mut probe);
2599
2600 add_status_expectations(&mut probe, true);
2602
2603 add_status_expectations(&mut probe, true);
2605 add_halt_cleanup_expectations(&mut probe);
2606
2607 add_read_reg_expectations(&mut probe, 0, 0);
2609 add_read_pc_expectations(&mut probe, REG_VALUE);
2610
2611 let mock_mem = Box::new(probe) as _;
2612
2613 let mut armv8a = Armv8a::new(
2614 mock_mem,
2615 &mut state,
2616 TEST_BASE_ADDRESS,
2617 TEST_CTI_ADDRESS,
2618 DefaultArmSequence::create(),
2619 )
2620 .unwrap();
2621
2622 assert_eq!(
2624 REG_VALUE as u64,
2625 armv8a.halt(Duration::from_millis(100)).unwrap().pc
2626 );
2627 }
2628
2629 #[test]
2630 fn armv8a_run() {
2631 let mut probe = MockProbe::new(false);
2632 let mut state = CortexAState::new();
2633
2634 add_status_expectations(&mut probe, true);
2636
2637 add_resume_expectations(&mut probe);
2639
2640 add_status_expectations(&mut probe, false);
2642
2643 add_resume_cleanup_expectations(&mut probe);
2644
2645 let mock_mem = Box::new(probe) as _;
2646
2647 let mut armv8a = Armv8a::new(
2648 mock_mem,
2649 &mut state,
2650 TEST_BASE_ADDRESS,
2651 TEST_CTI_ADDRESS,
2652 DefaultArmSequence::create(),
2653 )
2654 .unwrap();
2655
2656 armv8a.run().unwrap();
2657 }
2658
2659 #[test]
2660 fn armv8a_available_breakpoint_units() {
2661 const BP_COUNT: u32 = 4;
2662 let mut probe = MockProbe::new(false);
2663 let mut state = CortexAState::new();
2664
2665 add_status_expectations(&mut probe, true);
2667
2668 add_idr_expectations(&mut probe, BP_COUNT);
2670
2671 let mock_mem = Box::new(probe) as _;
2672
2673 let mut armv8a = Armv8a::new(
2674 mock_mem,
2675 &mut state,
2676 TEST_BASE_ADDRESS,
2677 TEST_CTI_ADDRESS,
2678 DefaultArmSequence::create(),
2679 )
2680 .unwrap();
2681
2682 assert_eq!(BP_COUNT, armv8a.available_breakpoint_units().unwrap());
2683 }
2684
2685 #[test]
2686 fn armv8a_hw_breakpoints() {
2687 const BP_COUNT: u32 = 4;
2688 const BP1: u64 = 0x2345;
2689 const BP2: u64 = 0x8000_0000;
2690 let mut probe = MockProbe::new(false);
2691 let mut state = CortexAState::new();
2692
2693 add_status_expectations(&mut probe, true);
2695
2696 add_idr_expectations(&mut probe, BP_COUNT);
2698
2699 probe.expected_read(
2701 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2702 BP1 as u32,
2703 );
2704 probe.expected_read(
2705 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4,
2706 0,
2707 );
2708 probe.expected_read(
2709 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2710 1,
2711 );
2712
2713 probe.expected_read(
2714 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 16,
2715 BP2 as u32,
2716 );
2717 probe.expected_read(
2718 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4 + 16,
2719 0,
2720 );
2721 probe.expected_read(
2722 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 16,
2723 1,
2724 );
2725
2726 probe.expected_read(
2727 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (2 * 16),
2728 0,
2729 );
2730 probe.expected_read(
2731 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4 + (2 * 16),
2732 0,
2733 );
2734 probe.expected_read(
2735 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (2 * 16),
2736 0,
2737 );
2738
2739 probe.expected_read(
2740 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (3 * 16),
2741 0,
2742 );
2743 probe.expected_read(
2744 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4 + (3 * 16),
2745 0,
2746 );
2747 probe.expected_read(
2748 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + (3 * 16),
2749 0,
2750 );
2751
2752 let mock_mem = Box::new(probe) as _;
2753
2754 let mut armv8a = Armv8a::new(
2755 mock_mem,
2756 &mut state,
2757 TEST_BASE_ADDRESS,
2758 TEST_CTI_ADDRESS,
2759 DefaultArmSequence::create(),
2760 )
2761 .unwrap();
2762
2763 let results = armv8a.hw_breakpoints().unwrap();
2764 assert_eq!(Some(BP1), results[0]);
2765 assert_eq!(Some(BP2), results[1]);
2766 assert_eq!(None, results[2]);
2767 assert_eq!(None, results[3]);
2768 }
2769
2770 #[test]
2771 fn armv8a_set_hw_breakpoint() {
2772 const BP_VALUE: u64 = 0x2345;
2773 let mut probe = MockProbe::new(false);
2774 let mut state = CortexAState::new();
2775
2776 add_status_expectations(&mut probe, true);
2778
2779 let mut dbgbcr = Dbgbcr(0);
2781 dbgbcr.set_hmc(true);
2783 dbgbcr.set_pmc(0b11);
2784 dbgbcr.set_bas(0b1111);
2786 dbgbcr.set_e(true);
2788
2789 probe.expected_write(
2790 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2791 BP_VALUE as u32,
2792 );
2793 probe.expected_write(
2794 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4,
2795 0,
2796 );
2797 probe.expected_write(
2798 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2799 dbgbcr.into(),
2800 );
2801
2802 let mock_mem = Box::new(probe) as _;
2803
2804 let mut armv8a = Armv8a::new(
2805 mock_mem,
2806 &mut state,
2807 TEST_BASE_ADDRESS,
2808 TEST_CTI_ADDRESS,
2809 DefaultArmSequence::create(),
2810 )
2811 .unwrap();
2812
2813 armv8a.set_hw_breakpoint(0, BP_VALUE).unwrap();
2814 }
2815
2816 #[test]
2817 fn armv8a_clear_hw_breakpoint() {
2818 let mut probe = MockProbe::new(false);
2819 let mut state = CortexAState::new();
2820
2821 add_status_expectations(&mut probe, true);
2823
2824 probe.expected_write(
2826 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2827 0,
2828 );
2829 probe.expected_write(
2830 Dbgbvr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap() + 4,
2831 0,
2832 );
2833 probe.expected_write(
2834 Dbgbcr::get_mmio_address_from_base(TEST_BASE_ADDRESS).unwrap(),
2835 0,
2836 );
2837
2838 let mock_mem = Box::new(probe) as _;
2839
2840 let mut armv8a = Armv8a::new(
2841 mock_mem,
2842 &mut state,
2843 TEST_BASE_ADDRESS,
2844 TEST_CTI_ADDRESS,
2845 DefaultArmSequence::create(),
2846 )
2847 .unwrap();
2848
2849 armv8a.clear_hw_breakpoint(0).unwrap();
2850 }
2851
2852 #[test]
2853 fn armv8a_read_word_32() {
2854 const MEMORY_VALUE: u32 = 0xBA5EBA11;
2855 const MEMORY_ADDRESS: u64 = 0x12345678;
2856
2857 let mut probe = MockProbe::new(false);
2858 let mut state = CortexAState::new();
2859
2860 add_status_expectations(&mut probe, true);
2862
2863 add_read_reg_expectations(&mut probe, 0, 0);
2865 add_read_reg_expectations(&mut probe, 1, 0);
2866
2867 add_read_memory_expectations(&mut probe, MEMORY_ADDRESS, MEMORY_VALUE);
2868
2869 let mock_mem = Box::new(probe) as _;
2870
2871 let mut armv8a = Armv8a::new(
2872 mock_mem,
2873 &mut state,
2874 TEST_BASE_ADDRESS,
2875 TEST_CTI_ADDRESS,
2876 DefaultArmSequence::create(),
2877 )
2878 .unwrap();
2879
2880 assert_eq!(MEMORY_VALUE, armv8a.read_word_32(MEMORY_ADDRESS).unwrap());
2881 }
2882
2883 #[test]
2884 fn armv8a_read_word_32_aarch64() {
2885 const MEMORY_VALUE: u32 = 0xBA5EBA11;
2886 const MEMORY_ADDRESS: u64 = 0x12345678;
2887
2888 let mut probe = MockProbe::new(true);
2889 let mut state = CortexAState::new();
2890
2891 add_status_expectations(&mut probe, true);
2893
2894 add_read_reg_64_expectations(&mut probe, 0, 0);
2896 add_read_reg_64_expectations(&mut probe, 1, 0);
2897
2898 add_read_memory_aarch64_expectations(&mut probe, MEMORY_ADDRESS, MEMORY_VALUE);
2899
2900 let mock_mem = Box::new(probe) as _;
2901
2902 let mut armv8a = Armv8a::new(
2903 mock_mem,
2904 &mut state,
2905 TEST_BASE_ADDRESS,
2906 TEST_CTI_ADDRESS,
2907 DefaultArmSequence::create(),
2908 )
2909 .unwrap();
2910
2911 assert_eq!(MEMORY_VALUE, armv8a.read_word_32(MEMORY_ADDRESS).unwrap());
2912 }
2913
2914 #[test]
2915 fn armv8a_read_word_8() {
2916 const MEMORY_VALUE: u32 = 0xBA5EBA11;
2917 const MEMORY_ADDRESS: u64 = 0x12345679;
2918 const MEMORY_WORD_ADDRESS: u64 = 0x12345678;
2919
2920 let mut probe = MockProbe::new(false);
2921 let mut state = CortexAState::new();
2922
2923 add_status_expectations(&mut probe, true);
2925
2926 add_read_reg_expectations(&mut probe, 0, 0);
2928 add_read_reg_expectations(&mut probe, 1, 0);
2929 add_read_memory_expectations(&mut probe, MEMORY_WORD_ADDRESS, MEMORY_VALUE);
2930
2931 let mock_mem = Box::new(probe) as _;
2932
2933 let mut armv8a = Armv8a::new(
2934 mock_mem,
2935 &mut state,
2936 TEST_BASE_ADDRESS,
2937 TEST_CTI_ADDRESS,
2938 DefaultArmSequence::create(),
2939 )
2940 .unwrap();
2941
2942 assert_eq!(0xBA, armv8a.read_word_8(MEMORY_ADDRESS).unwrap());
2943 }
2944
2945 #[test]
2946 fn armv8a_read_word_aarch64_8() {
2947 const MEMORY_VALUE: u32 = 0xBA5EBA11;
2948 const MEMORY_ADDRESS: u64 = 0x12345679;
2949 const MEMORY_WORD_ADDRESS: u64 = 0x12345678;
2950
2951 let mut probe = MockProbe::new(true);
2952 let mut state = CortexAState::new();
2953
2954 add_status_expectations(&mut probe, true);
2956
2957 add_read_reg_64_expectations(&mut probe, 0, 0);
2959 add_read_reg_64_expectations(&mut probe, 1, 0);
2960 add_read_memory_aarch64_expectations(&mut probe, MEMORY_WORD_ADDRESS, MEMORY_VALUE);
2961
2962 let mock_mem = Box::new(probe) as _;
2963
2964 let mut armv8a = Armv8a::new(
2965 mock_mem,
2966 &mut state,
2967 TEST_BASE_ADDRESS,
2968 TEST_CTI_ADDRESS,
2969 DefaultArmSequence::create(),
2970 )
2971 .unwrap();
2972
2973 assert_eq!(0xBA, armv8a.read_word_8(MEMORY_ADDRESS).unwrap());
2974 }
2975}