1use crate::architecture::riscv::dtm::DtmAccess;
8use crate::memory::valid_32bit_address;
9use crate::probe::queue::DeferredResultIndex;
10use crate::{
11 Error as ProbeRsError, architecture::riscv::*, config::Target, memory_mapped_bitfield_register,
12};
13use std::any::Any;
14use std::collections::HashMap;
15use std::ops::Range;
16
17#[derive(thiserror::Error, Debug)]
19pub enum RiscvError {
20 #[error("Error during transport")]
22 DtmOperationFailed,
23 #[error("Transport operation in progress")]
25 DtmOperationInProcess,
26 #[error("Debug Probe Error")]
28 DebugProbe(#[from] DebugProbeError),
29 #[error("Timeout during DMI access.")]
31 Timeout,
32 #[error("Error occurred during execution of an abstract command: {0:?}")]
34 AbstractCommand(AbstractCommandErrorKind),
35 #[error("The core did not acknowledge a request for reset, resume or halt")]
37 RequestNotAcknowledged,
38 #[error("The version '{0}' of the debug transport module (DTM) is currently not supported.")]
40 UnsupportedDebugTransportModuleVersion(u8),
41 #[error("The version '{0:?}' of the debug module is currently not supported.")]
43 UnsupportedDebugModuleVersion(DebugModuleVersion),
44 #[error("CSR at address '{0:x}' is unsupported.")]
46 UnsupportedCsrAddress(u16),
47 #[error("Program buffer register '{0}' is currently not supported.")]
49 UnsupportedProgramBufferRegister(usize),
50 #[error(
52 "Program buffer is too small for supplied program. Required: {required}, Actual: {actual}"
53 )]
54 ProgramBufferTooSmall {
55 required: usize,
57 actual: usize,
59 },
60 #[error("Memory width larger than 32 bits is not supported yet.")]
62 UnsupportedBusAccessWidth(RiscvBusAccess),
63 #[error("Error using system bus")]
65 SystemBusAccess,
66 #[error("Unexpected trigger type {0} for address breakpoint.")]
68 UnexpectedTriggerType(u32),
69 #[error("Connected target is not a RISC-V device.")]
71 NoRiscvTarget,
72 #[error("The target does not support halt after reset.")]
74 ResetHaltRequestNotSupported,
75 #[error("The requested data is not available due to a previous error.")]
77 BatchedResultNotAvailable,
78 #[error("The requested hart is unavailable.")]
80 HartUnavailable,
81}
82
83impl From<RiscvError> for ProbeRsError {
84 fn from(err: RiscvError) -> Self {
85 match err {
86 RiscvError::DebugProbe(e) => e.into(),
87 other => ProbeRsError::Riscv(other),
88 }
89 }
90}
91
92#[derive(Debug)]
94pub enum AbstractCommandErrorKind {
95 Busy = 1,
101 NotSupported = 2,
103 Exception = 3,
105 HaltResume = 4,
109 Bus = 5,
112 _Reserved = 6,
114 Other = 7,
116}
117
118impl From<AbstractCommandErrorKind> for RiscvError {
119 fn from(err: AbstractCommandErrorKind) -> Self {
120 RiscvError::AbstractCommand(err)
121 }
122}
123
124impl AbstractCommandErrorKind {
125 fn parse(status: Abstractcs) -> Result<(), Self> {
126 let err = match status.cmderr() {
127 0 => return Ok(()),
128 1 => Self::Busy,
129 2 => Self::NotSupported,
130 3 => Self::Exception,
131 4 => Self::HaltResume,
132 5 => Self::Bus,
133 6 => Self::_Reserved,
134 7 => Self::Other,
135 _ => unreachable!("cmderr is a 3 bit value, values higher than 7 should not occur."),
136 };
137
138 Err(err)
139 }
140}
141
142#[derive(Debug, Copy, Clone, PartialEq, Eq)]
147pub enum DebugModuleVersion {
148 NoModule,
150 Version0_11,
152 Version0_13,
154 Version1_0,
156 NonConforming,
158 Unknown(u8),
160}
161
162impl DebugModuleVersion {
163 fn is_implemented(self) -> bool {
164 matches!(
165 self,
166 DebugModuleVersion::Version0_13 | DebugModuleVersion::Version1_0
167 )
168 }
169}
170
171impl From<u8> for DebugModuleVersion {
172 fn from(raw: u8) -> Self {
173 match raw {
174 0 => Self::NoModule,
175 1 => Self::Version0_11,
176 2 => Self::Version0_13,
177 3 => Self::Version1_0,
178 15 => Self::NonConforming,
179 other => Self::Unknown(other),
180 }
181 }
182}
183
184#[derive(Copy, Clone, Debug)]
185struct CoreRegisterAbstractCmdSupport(u8);
186
187impl CoreRegisterAbstractCmdSupport {
188 const READ: Self = Self(1 << 0);
189 const WRITE: Self = Self(1 << 1);
190 const BOTH: Self = Self(Self::READ.0 | Self::WRITE.0);
191
192 fn supports(&self, o: Self) -> bool {
193 self.0 & o.0 == o.0
194 }
195
196 fn unset(&mut self, o: Self) {
197 self.0 &= !(o.0);
198 }
199}
200
201#[derive(Debug, Default)]
204struct ScratchState {
205 stack: Vec<u32>,
206}
207
208impl ScratchState {
209 fn push(&mut self, value: u32) {
210 self.stack.push(value);
211 }
212
213 fn pop(&mut self) -> Option<u32> {
214 self.stack.pop()
215 }
216}
217
218#[derive(Default, Debug)]
220pub struct MemoryAccessConfig {
221 has_program_buffer: bool,
222
223 default_method: HashMap<RiscvBusAccess, MemoryAccessMethod>,
225
226 region_override: HashMap<(Range<u64>, RiscvBusAccess), MemoryAccessMethod>,
227}
228
229impl MemoryAccessConfig {
230 pub fn set_default_method(&mut self, access: RiscvBusAccess, method: MemoryAccessMethod) {
232 self.default_method.insert(access, method);
233 }
234
235 pub fn set_region_override(
237 &mut self,
238 access: RiscvBusAccess,
239 range: Range<u64>,
240 method: MemoryAccessMethod,
241 ) {
242 self.region_override.insert((range, access), method);
243 }
244
245 pub fn default_method(&self, access: RiscvBusAccess) -> MemoryAccessMethod {
247 self.default_method
248 .get(&access)
249 .copied()
250 .unwrap_or(if self.has_program_buffer {
251 MemoryAccessMethod::ProgramBuffer
252 } else {
253 MemoryAccessMethod::AbstractCommand
254 })
255 }
256
257 pub fn method(&self, address: u64, access: RiscvBusAccess) -> MemoryAccessMethod {
259 for ((range, method_access), method) in &self.region_override {
260 if range.contains(&address) && method_access == &access {
261 return *method;
262 }
263 }
264
265 self.default_method(access)
266 }
267
268 pub fn range_method(
270 &self,
271 address_range: Range<u64>,
272 access: RiscvBusAccess,
273 ) -> MemoryAccessMethod {
274 fn range_overlaps(range: &Range<u64>, address_range: &Range<u64>) -> bool {
275 range.start < address_range.end && address_range.start < range.end
276 }
277
278 let mut max = self.default_method(access);
279
280 for ((range, method_access), method) in &self.region_override {
281 if range_overlaps(range, &address_range) && method_access == &access {
282 max = std::cmp::min(*method, max);
283 }
284 }
285
286 max
287 }
288}
289
290#[derive(Debug)]
292pub struct RiscvCommunicationInterfaceState {
293 debug_version: DebugModuleVersion,
295
296 progbuf_size: u8,
298
299 progbuf_cache: [u32; 16],
301
302 implicit_ebreak: bool,
305
306 data_register_count: u8,
308
309 nscratch: u8,
311
312 supports_autoexec: bool,
314
315 confstrptr: Option<u128>,
317
318 hartsellen: u8,
320
321 num_harts: u32,
323
324 abstract_cmd_register_info: HashMap<RegisterId, CoreRegisterAbstractCmdSupport>,
327
328 s0: ScratchState,
330
331 s1: ScratchState,
333
334 enabled_harts: u32,
336
337 last_selected_hart: u32,
339
340 hasresethaltreq: Option<bool>,
342
343 is_halted: bool,
345
346 current_dmcontrol: Dmcontrol,
348
349 memory_access_config: MemoryAccessConfig,
350
351 sw_breakpoint_debug_enabled: bool,
352
353 pub(super) xlen_64: bool,
356
357 pub(crate) force_machine_mode_progbuf: bool,
364}
365
366const RISCV_TIMEOUT: Duration = Duration::from_secs(5);
368
369const RISCV_MAX_CSR_ADDR: u16 = 0xFFF;
372
373impl RiscvCommunicationInterfaceState {
374 pub fn new() -> Self {
376 RiscvCommunicationInterfaceState {
377 progbuf_size: 0,
379 progbuf_cache: [0u32; 16],
380
381 debug_version: DebugModuleVersion::NonConforming,
382
383 implicit_ebreak: false,
385
386 data_register_count: 1,
388
389 nscratch: 0,
390
391 supports_autoexec: false,
392
393 confstrptr: None,
394
395 hartsellen: 20,
397
398 num_harts: 1,
400
401 abstract_cmd_register_info: HashMap::new(),
402
403 s0: ScratchState::default(),
404 s1: ScratchState::default(),
405 enabled_harts: 0,
406 last_selected_hart: 0,
407 hasresethaltreq: None,
408 is_halted: false,
409
410 current_dmcontrol: Dmcontrol(0),
411
412 memory_access_config: MemoryAccessConfig::default(),
413
414 sw_breakpoint_debug_enabled: false,
415
416 xlen_64: false,
417 force_machine_mode_progbuf: false,
418 }
419 }
420
421 fn memory_access_method(
424 &mut self,
425 access_width: RiscvBusAccess,
426 address: u64,
427 ) -> MemoryAccessMethod {
428 self.memory_access_config.method(address, access_width)
429 }
430
431 fn memory_range_access_method(
432 &self,
433 width: RiscvBusAccess,
434 address_range: Range<u64>,
435 ) -> MemoryAccessMethod {
436 self.memory_access_config.range_method(address_range, width)
437 }
438}
439
440impl Default for RiscvCommunicationInterfaceState {
441 fn default() -> Self {
442 Self::new()
443 }
444}
445
446pub struct RiscvDebugInterfaceState {
448 pub(crate) interface_state: RiscvCommunicationInterfaceState,
449 pub(super) dtm_state: Box<dyn Any + Send>,
450}
451
452impl RiscvDebugInterfaceState {
453 pub(crate) fn new(dtm_state: Box<dyn Any + Send>) -> Self {
454 Self {
455 interface_state: RiscvCommunicationInterfaceState::new(),
456 dtm_state,
457 }
458 }
459}
460
461pub trait RiscvInterfaceBuilder<'probe> {
463 fn create_state(&self) -> RiscvDebugInterfaceState;
468
469 fn attach<'state>(
472 self: Box<Self>,
473 state: &'state mut RiscvDebugInterfaceState,
474 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
475 where
476 'probe: 'state;
477
478 fn attach_tunneled<'state>(
481 self: Box<Self>,
482 _tunnel_ir_id: u32,
483 _tunnel_ir_width: u32,
484 _state: &'state mut RiscvDebugInterfaceState,
485 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
486 where
487 'probe: 'state,
488 {
489 Err(DebugProbeError::InterfaceNotAvailable {
490 interface_name: "Tunneled RISC-V",
491 })
492 }
493
494 fn attach_auto<'state>(
499 self: Box<Self>,
500 target: &Target,
501 state: &'state mut RiscvDebugInterfaceState,
502 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
503 where
504 'probe: 'state,
505 {
506 let maybe_tunnel = target.jtag.as_ref().and_then(|j| j.riscv_tunnel.as_ref());
507 if let Some(tunnel) = maybe_tunnel {
508 self.attach_tunneled(tunnel.ir_id, tunnel.ir_width, state)
509 } else {
510 self.attach(state)
511 }
512 }
513}
514
515#[derive(Debug)]
517pub struct RiscvCommunicationInterface<'state> {
518 dtm: Box<dyn DtmAccess + 'state>,
521 state: &'state mut RiscvCommunicationInterfaceState,
522}
523
524impl<'state> RiscvCommunicationInterface<'state> {
525 pub fn new(
527 dtm: Box<dyn DtmAccess + 'state>,
528 state: &'state mut RiscvCommunicationInterfaceState,
529 ) -> Self {
530 Self { dtm, state }
531 }
532
533 pub fn select_hart(&mut self, hart: u32) -> Result<(), RiscvError> {
535 if !self.hart_enabled(hart) {
536 return Err(RiscvError::HartUnavailable);
537 }
538
539 if self.state.last_selected_hart == hart {
540 return Ok(());
541 }
542
543 let mut control = self.read_dm_register::<Dmcontrol>()?;
545 control.set_dmactive(true);
546 control.set_hartsel(hart);
547 self.schedule_write_dm_register(control)?;
548 self.state.last_selected_hart = hart;
549 Ok(())
550 }
551
552 pub fn hart_enabled(&self, hart: u32) -> bool {
554 self.state.enabled_harts & (1 << hart) != 0
555 }
556
557 pub fn target_reset_assert(&mut self) -> Result<(), DebugProbeError> {
559 self.dtm.target_reset_assert()
560 }
561
562 pub fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError> {
564 self.dtm.target_reset_deassert()
565 }
566
567 pub fn read_idcode(&mut self) -> Result<Option<u32>, DebugProbeError> {
569 self.dtm.read_idcode()
570 }
571
572 fn save_s0(&mut self) -> Result<bool, RiscvError> {
573 let s0 = self.abstract_cmd_register_read(registers::S0)?;
574
575 self.state.s0.push(s0);
576
577 Ok(true)
578 }
579
580 fn restore_s0(&mut self, saved: bool) -> Result<(), RiscvError> {
581 if saved {
582 let s0 = self.state.s0.pop().unwrap();
583
584 self.abstract_cmd_register_write(registers::S0, s0)?;
585 }
586
587 Ok(())
588 }
589
590 fn save_s1(&mut self) -> Result<bool, RiscvError> {
591 let s1 = self.abstract_cmd_register_read(registers::S1)?;
592
593 self.state.s1.push(s1);
594
595 Ok(true)
596 }
597
598 fn restore_s1(&mut self, saved: bool) -> Result<(), RiscvError> {
599 if saved {
600 let s1 = self.state.s1.pop().unwrap();
601
602 self.abstract_cmd_register_write(registers::S1, s1)?;
603 }
604
605 Ok(())
606 }
607
608 pub fn enter_debug_mode(&mut self) -> Result<(), RiscvError> {
611 tracing::debug!("Building RISC-V interface");
612 self.dtm.init()?;
613
614 self.dtm.clear_error_state()?;
616
617 let mut control = Dmcontrol(0);
619 control.set_dmactive(true);
620 self.schedule_write_dm_register(control)?;
621
622 let status: Dmstatus = self.read_dm_register()?;
624
625 self.state.progbuf_cache.fill(0);
626 self.state.memory_access_config = MemoryAccessConfig::default();
627 self.state.debug_version = DebugModuleVersion::from(status.version() as u8);
628 self.state.is_halted = status.allhalted();
629
630 if !self.state.debug_version.is_implemented() {
631 return Err(RiscvError::UnsupportedDebugModuleVersion(
632 self.state.debug_version,
633 ));
634 }
635
636 self.state.implicit_ebreak = status.impebreak();
637
638 self.state.confstrptr = if status.confstrptrvalid() {
640 let confstrptr_0: Confstrptr0 = self.read_dm_register()?;
641 let confstrptr_1: Confstrptr1 = self.read_dm_register()?;
642 let confstrptr_2: Confstrptr2 = self.read_dm_register()?;
643 let confstrptr_3: Confstrptr3 = self.read_dm_register()?;
644 let confstrptr = (u32::from(confstrptr_0) as u128)
645 | ((u32::from(confstrptr_1) as u128) << 8)
646 | ((u32::from(confstrptr_2) as u128) << 16)
647 | ((u32::from(confstrptr_3) as u128) << 32);
648 Some(confstrptr)
649 } else {
650 None
651 };
652
653 tracing::debug!("dmstatus: {:?}", status);
654
655 let mut control = Dmcontrol(0);
658 control.set_dmactive(true);
659 control.set_hartsel(0xffff_ffff);
660
661 self.schedule_write_dm_register(control)?;
662
663 let control = self.read_dm_register::<Dmcontrol>()?;
664
665 self.state.hartsellen = control.hartsel().count_ones() as u8;
666
667 tracing::debug!("HARTSELLEN: {}", self.state.hartsellen);
668
669 let max_hart_index = 2u32.pow(self.state.hartsellen as u32);
672
673 let mut num_harts = 1;
675 self.state.enabled_harts = 1;
676
677 let mut control = Dmcontrol(0);
682 control.set_dmactive(true);
683 control.set_hartsel(max_hart_index - 1);
684 self.schedule_write_dm_register(control)?;
685
686 let status: Dmstatus = self.read_dm_register()?;
688
689 let sticky_unavail = status.stickyunavail();
692
693 if status.anynonexistent() {
694 for hart_index in 1..max_hart_index {
695 let mut control = Dmcontrol(0);
696 control.set_dmactive(true);
697 control.set_hartsel(hart_index);
698 if sticky_unavail {
700 control.set_ackunavail(true);
701 }
702
703 self.schedule_write_dm_register(control)?;
704
705 let status: Dmstatus = self.read_dm_register()?;
707
708 if status.anynonexistent() {
709 break;
710 }
711
712 if !status.allunavail() {
713 self.state.enabled_harts |= 1 << num_harts;
714 }
715
716 num_harts += 1;
717 }
718 } else {
719 tracing::debug!("anynonexistent not supported, assuming only one hart exists")
720 }
721
722 tracing::debug!("Number of harts: {}", num_harts);
723
724 self.state.num_harts = num_harts;
725
726 let mut control = Dmcontrol(0);
730 control.set_dmactive(true);
731 control.set_hartsel(0);
732 if self.state.debug_version == DebugModuleVersion::Version1_0 {
733 control.set_setkeepalive(true);
734 }
735
736 self.schedule_write_dm_register(control)?;
737
738 let abstractcs: Abstractcs = self.read_dm_register()?;
741
742 self.state.progbuf_size = abstractcs.progbufsize() as u8;
743 self.state.memory_access_config.has_program_buffer = self.state.progbuf_size != 0;
744 tracing::debug!("Program buffer size: {}", self.state.progbuf_size);
745
746 self.state.data_register_count = abstractcs.datacount() as u8;
747 tracing::debug!(
748 "Number of data registers: {}",
749 self.state.data_register_count
750 );
751
752 let hartinfo: Hartinfo = self.read_dm_register()?;
754
755 self.state.nscratch = hartinfo.nscratch() as u8;
756 tracing::debug!("Number of dscratch registers: {}", self.state.nscratch);
757
758 let mut abstractauto = Abstractauto(0);
760 abstractauto.set_autoexecprogbuf(2u32.pow(self.state.progbuf_size as u32) - 1);
761 abstractauto.set_autoexecdata(2u32.pow(self.state.data_register_count as u32) - 1);
762
763 self.schedule_write_dm_register(abstractauto)?;
764
765 let abstractauto_readback: Abstractauto = self.read_dm_register()?;
766
767 self.state.supports_autoexec = abstractauto_readback == abstractauto;
768 tracing::debug!("Support for autoexec: {}", self.state.supports_autoexec);
769
770 abstractauto = Abstractauto(0);
772 self.schedule_write_dm_register(abstractauto)?;
773
774 let sbcs = self.read_dm_register::<Sbcs>()?;
776
777 if sbcs.sbversion() == 1 {
781 if sbcs.sbaccess8() {
784 self.state
785 .memory_access_config
786 .set_default_method(RiscvBusAccess::A8, MemoryAccessMethod::SystemBus);
787 }
788
789 if sbcs.sbaccess16() {
790 self.state
791 .memory_access_config
792 .set_default_method(RiscvBusAccess::A16, MemoryAccessMethod::SystemBus);
793 }
794
795 if sbcs.sbaccess32() {
796 self.state
797 .memory_access_config
798 .set_default_method(RiscvBusAccess::A32, MemoryAccessMethod::SystemBus);
799 }
800
801 if sbcs.sbaccess64() {
802 self.state
803 .memory_access_config
804 .set_default_method(RiscvBusAccess::A64, MemoryAccessMethod::SystemBus);
805 }
806
807 if sbcs.sbaccess128() {
808 self.state
809 .memory_access_config
810 .set_default_method(RiscvBusAccess::A128, MemoryAccessMethod::SystemBus);
811 }
812 } else {
813 tracing::debug!(
814 "System bus interface version {} is not supported.",
815 sbcs.sbversion()
816 );
817 }
818
819 Ok(())
820 }
821
822 pub fn disable_debug_module(&mut self) -> Result<(), RiscvError> {
830 if let Err(e) = self.debug_on_sw_breakpoint(false) {
833 tracing::warn!(
834 "disable_debug_module: could not clear sw-breakpoint state: {:?}",
835 e
836 );
837 }
838
839 if let Err(e) = self.dtm.clear_error_state() {
843 tracing::warn!(
844 "disable_debug_module: could not clear DMI error state: {:?}",
845 e
846 );
847 }
848
849 let mut control = Dmcontrol(0);
850 control.set_dmactive(false);
851 self.write_dm_register(control)?;
852
853 Ok(())
854 }
855
856 pub fn halt(&mut self, timeout: Duration) -> Result<(), RiscvError> {
858 let mut dmcontrol = self.state.current_dmcontrol;
861 tracing::debug!(
862 "Before requesting halt, the Dmcontrol register value was: {:?}",
863 dmcontrol
864 );
865
866 dmcontrol.set_dmactive(true);
867 dmcontrol.set_haltreq(true);
868
869 self.schedule_write_dm_register(dmcontrol)?;
870
871 let result_status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
872
873 dmcontrol.set_haltreq(false);
875 self.write_dm_register(dmcontrol)?;
876
877 let result_status = Dmstatus(self.dtm.read_deferred_result(result_status_idx)?.into_u32());
878
879 if !result_status.allhalted() {
880 dmcontrol.set_haltreq(true);
884 self.write_dm_register(dmcontrol)?;
885
886 self.wait_for_core_halted(timeout)?;
888
889 dmcontrol.set_haltreq(false);
891 self.write_dm_register(dmcontrol)?;
892 }
893
894 self.state.is_halted = true;
896
897 if !self.state.sw_breakpoint_debug_enabled {
898 self.debug_on_sw_breakpoint(true)?;
899 }
900
901 Ok(())
902 }
903
904 pub(crate) fn halt_with_previous(&mut self, timeout: Duration) -> Result<bool, RiscvError> {
906 let was_running = if self.state.is_halted {
907 false
909 } else {
910 let status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
913 self.halt(timeout)?;
914 let before_status = Dmstatus(self.dtm.read_deferred_result(status_idx)?.into_u32());
915
916 !before_status.allhalted()
917 };
918
919 Ok(was_running)
920 }
921
922 pub(crate) fn core_info(&mut self) -> Result<CoreInformation, RiscvError> {
923 Ok(CoreInformation {
924 pc: self.read_csr(super::registers::PC.id().0)?,
925 })
926 }
927
928 pub fn core_halted(&mut self) -> Result<bool, RiscvError> {
930 if !self.state.is_halted {
931 let dmstatus: Dmstatus = self.read_dm_register()?;
932
933 tracing::trace!("{:?}", dmstatus);
934
935 self.state.is_halted = dmstatus.allhalted();
936 }
937
938 Ok(self.state.is_halted)
939 }
940
941 pub(crate) fn wait_for_core_halted(&mut self, timeout: Duration) -> Result<(), RiscvError> {
942 let start = Instant::now();
944
945 while !self.core_halted()? {
946 if start.elapsed() >= timeout {
947 return Err(RiscvError::Timeout);
948 }
949 std::thread::sleep(Duration::from_millis(1));
951 }
952
953 Ok(())
954 }
955
956 const DCSR_REGNO: u16 = 0x7b0;
959 const PRV_MASK: u32 = 0x3;
960 const PRV_M: u32 = 0x3;
961 const EBREAKM: u32 = 1 << 15;
966
967 pub fn halted_access<R>(
969 &mut self,
970 op: impl FnOnce(&mut Self) -> Result<R, RiscvError>,
971 ) -> Result<R, RiscvError> {
972 let was_running = self.halt_with_previous(Duration::from_millis(100))?;
973
974 let saved_prv: Option<u32> = if self.state.force_machine_mode_progbuf {
991 match self.read_dcsr_inline() {
993 Ok(dcsr) => {
994 let prv = dcsr & Self::PRV_MASK;
995 let need_prv = prv != Self::PRV_M;
996 let need_ebreakm = (dcsr & Self::EBREAKM) == 0;
997 if need_prv || need_ebreakm {
998 let dcsr_new =
999 (dcsr & !Self::PRV_MASK & !Self::EBREAKM) | Self::PRV_M | Self::EBREAKM;
1000 tracing::trace!(
1001 "halted_access: updating DCSR {:#010x} -> {:#010x}",
1002 dcsr,
1003 dcsr_new,
1004 );
1005 if let Err(e) = self.write_dcsr_inline(dcsr_new) {
1006 tracing::warn!("halted_access: could not update DCSR: {:?}", e);
1007 None
1010 } else {
1011 Some(prv)
1012 }
1013 } else {
1014 Some(prv)
1015 }
1016 }
1017 Err(e) => {
1018 tracing::warn!("halted_access: could not read DCSR: {:?}", e);
1019 None
1020 }
1021 }
1022 } else {
1023 None
1024 };
1025
1026 let result = op(self);
1027
1028 if let Some(prv) = saved_prv
1032 && prv != Self::PRV_M
1033 {
1034 match self.read_dcsr_inline() {
1035 Ok(dcsr) => {
1036 let new_dcsr = (dcsr & !Self::PRV_MASK) | prv;
1037 let _ = self.write_dcsr_inline(new_dcsr);
1038 }
1039 Err(e) => {
1040 tracing::warn!(
1041 "Failed to restore dcsr.prv after halted_access: {e}. \
1042 Core may resume with incorrect privilege level."
1043 );
1044 }
1045 }
1046 }
1047
1048 if was_running {
1049 self.resume_core()?;
1050 }
1051
1052 result
1053 }
1054
1055 fn read_dcsr_inline(&mut self) -> Result<u32, RiscvError> {
1064 match self.abstract_cmd_csr_read(Self::DCSR_REGNO) {
1065 Ok(v) => return Ok(v),
1066 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {}
1067 Err(e) => return Err(e),
1068 }
1069
1070 let csrr_cmd = assembly::csrr(8, Self::DCSR_REGNO);
1071 self.schedule_setup_program_buffer(&[csrr_cmd])?;
1072
1073 let postexec_cmd = self.postexec_command();
1074
1075 self.run_with_s0_saved(|core| {
1076 core.execute_abstract_command(postexec_cmd.0)?;
1077 core.save_s0_xlen().map(|v| v as u32)
1078 })
1079 }
1080
1081 fn write_dcsr_inline(&mut self, value: u32) -> Result<(), RiscvError> {
1086 match self.abstract_cmd_csr_write(Self::DCSR_REGNO, value) {
1087 Ok(()) => return Ok(()),
1088 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {}
1089 Err(e) => return Err(e),
1090 }
1091
1092 let csrw_cmd = assembly::csrw(Self::DCSR_REGNO, 8);
1093 self.schedule_setup_program_buffer(&[csrw_cmd])?;
1094
1095 let postexec_cmd = self.postexec_command();
1096
1097 self.run_with_s0_saved(|core| {
1098 core.restore_s0_xlen(value as u64)?;
1099 core.execute_abstract_command(postexec_cmd.0)
1100 })
1101 }
1102
1103 pub(super) fn read_csr(&mut self, address: u16) -> Result<u64, RiscvError> {
1109 tracing::debug!("Reading CSR {:#x}", address);
1112 let result = if self.state.xlen_64 {
1115 self.abstract_cmd_register_read_64(address)
1116 } else {
1117 self.abstract_cmd_register_read(address).map(u64::from)
1118 };
1119
1120 match result {
1121 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1122 tracing::debug!(
1123 "Could not read CSR {:#x} with abstract command, falling back to program buffer",
1124 address
1125 );
1126 self.read_csr_progbuf(address)
1127 }
1128 other => other,
1129 }
1130 }
1131
1132 pub(super) fn write_csr(&mut self, address: u16, value: u64) -> Result<(), RiscvError> {
1137 tracing::debug!("Writing CSR {:#x}", address);
1138 let result = if self.state.xlen_64 {
1139 self.abstract_cmd_register_write_64(address, value)
1140 } else {
1141 self.abstract_cmd_register_write(address, value as u32)
1142 };
1143 match result {
1144 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1145 tracing::debug!(
1146 "Could not write CSR {:#x} with abstract command, falling back to program buffer",
1147 address
1148 );
1149 self.write_csr_progbuf(address, value)
1150 }
1151 other => other,
1152 }
1153 }
1154
1155 pub(super) fn abstract_cmd_register_read_64(
1159 &mut self,
1160 regno: impl Into<RegisterId>,
1161 ) -> Result<u64, RiscvError> {
1162 let regno = regno.into();
1163
1164 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::READ) {
1165 return Err(RiscvError::AbstractCommand(
1166 AbstractCommandErrorKind::NotSupported,
1167 ));
1168 }
1169
1170 let mut command = AccessRegisterCommand(0);
1171 command.set_cmd_type(0);
1172 command.set_transfer(true);
1173 command.set_aarsize(RiscvBusAccess::A64);
1174 command.set_regno(regno.0 as u32);
1175
1176 match self.execute_abstract_command(command.0) {
1177 Ok(_) => (),
1178 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1179 self.set_abstract_cmd_register_unsupported(
1180 regno,
1181 CoreRegisterAbstractCmdSupport::READ,
1182 );
1183 err?;
1184 }
1185 Err(e) => return Err(e),
1186 }
1187
1188 let data0: Data0 = self.read_dm_register()?;
1189 let data1: Data1 = self.read_dm_register()?;
1190 let low: u32 = data0.into();
1191 let high: u32 = data1.into();
1192
1193 Ok(((high as u64) << 32) | (low as u64))
1194 }
1195
1196 pub(super) fn abstract_cmd_register_write_64(
1198 &mut self,
1199 regno: impl Into<RegisterId>,
1200 value: u64,
1201 ) -> Result<(), RiscvError> {
1202 let regno = regno.into();
1203
1204 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::WRITE) {
1205 return Err(RiscvError::AbstractCommand(
1206 AbstractCommandErrorKind::NotSupported,
1207 ));
1208 }
1209
1210 let low = (value & 0xffff_ffff) as u32;
1211 let high = (value >> 32) as u32;
1212
1213 self.schedule_write_dm_register(Data1(high))?;
1215 self.schedule_write_dm_register(Data0(low))?;
1216
1217 let mut command = AccessRegisterCommand(0);
1218 command.set_cmd_type(0);
1219 command.set_transfer(true);
1220 command.set_write(true);
1221 command.set_aarsize(RiscvBusAccess::A64);
1222 command.set_regno(regno.0 as u32);
1223
1224 match self.execute_abstract_command(command.0) {
1225 Ok(()) => Ok(()),
1226 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1227 self.set_abstract_cmd_register_unsupported(
1228 regno,
1229 CoreRegisterAbstractCmdSupport::WRITE,
1230 );
1231 err
1232 }
1233 Err(e) => Err(e),
1234 }
1235 }
1236
1237 fn abstract_cmd_csr_read(&mut self, csr: u16) -> Result<u32, RiscvError> {
1238 if self.state.xlen_64 {
1239 self.abstract_cmd_register_read_64(csr).map(|v| v as u32)
1240 } else {
1241 self.abstract_cmd_register_read(csr)
1242 }
1243 }
1244
1245 fn abstract_cmd_csr_write(&mut self, csr: u16, value: u32) -> Result<(), RiscvError> {
1246 if self.state.xlen_64 {
1247 self.abstract_cmd_register_write_64(csr, value as u64)
1248 } else {
1249 self.abstract_cmd_register_write(csr, value)
1250 }
1251 }
1252
1253 fn save_s0_xlen(&mut self) -> Result<u64, RiscvError> {
1254 if self.state.xlen_64 {
1255 self.abstract_cmd_register_read_64(registers::S0)
1256 } else {
1257 self.abstract_cmd_register_read(registers::S0)
1258 .map(|v| v as u64)
1259 }
1260 }
1261
1262 fn restore_s0_xlen(&mut self, value: u64) -> Result<(), RiscvError> {
1263 if self.state.xlen_64 {
1264 self.abstract_cmd_register_write_64(registers::S0, value)
1265 } else {
1266 self.abstract_cmd_register_write(registers::S0, value as u32)
1267 }
1268 }
1269
1270 fn read_s0_xlen(&mut self) -> Result<u64, RiscvError> {
1276 self.save_s0_xlen()
1277 }
1278
1279 fn write_s0_xlen(&mut self, value: u64) -> Result<(), RiscvError> {
1285 self.restore_s0_xlen(value)
1286 }
1287
1288 fn run_with_s0_saved<R>(
1294 &mut self,
1295 op: impl FnOnce(&mut Self) -> Result<R, RiscvError>,
1296 ) -> Result<R, RiscvError> {
1297 let saved = self.save_s0_xlen()?;
1298 let result = op(self);
1299 let _ = self.restore_s0_xlen(saved);
1300 result
1301 }
1302
1303 fn write_address_to_s0(&mut self, address: u64) -> Result<(), RiscvError> {
1310 if self.state.xlen_64 {
1311 self.abstract_cmd_register_write_64(registers::S0, address)
1312 } else {
1313 self.abstract_cmd_register_write(registers::S0, address as u32)
1314 }
1315 }
1316
1317 fn schedule_write_address_to_s0_and_exec(&mut self, address: u64) -> Result<(), RiscvError> {
1327 if self.state.xlen_64 {
1328 self.abstract_cmd_register_write_64(registers::S0, address)?;
1329 let mut command = AccessRegisterCommand(0);
1330 command.set_cmd_type(0);
1331 command.set_transfer(false);
1332 command.set_postexec(true);
1333 command.set_regno(registers::S0.id.0 as u32);
1334 self.schedule_write_dm_register(command)
1335 } else {
1336 self.schedule_write_dm_register(Data0(address as u32))?;
1337 let mut command = AccessRegisterCommand(0);
1338 command.set_cmd_type(0);
1339 command.set_transfer(true);
1340 command.set_write(true);
1341 command.set_aarsize(RiscvBusAccess::A32);
1342 command.set_postexec(true);
1343 command.set_regno(registers::S0.id.0 as u32);
1344 self.schedule_write_dm_register(command)
1345 }
1346 }
1347
1348 pub(crate) fn set_xlen_64(&mut self, is_64: bool) {
1353 self.state.xlen_64 = is_64;
1354 }
1355
1356 pub(crate) fn set_force_machine_mode_progbuf(&mut self, force: bool) {
1362 self.state.force_machine_mode_progbuf = force;
1363 }
1364
1365 pub fn read_dm_register<R: MemoryMappedRegister<u32>>(&mut self) -> Result<R, RiscvError> {
1367 tracing::debug!(
1368 "Reading DM register '{}' at {:#010x}",
1369 R::NAME,
1370 R::get_mmio_address()
1371 );
1372
1373 let register_value = self.read_dm_register_untyped(R::get_mmio_address())?.into();
1374
1375 tracing::debug!(
1376 "Read DM register '{}' at {:#010x} = {:x?}",
1377 R::NAME,
1378 R::get_mmio_address(),
1379 register_value
1380 );
1381
1382 Ok(register_value)
1383 }
1384
1385 fn read_dm_register_untyped(&mut self, address: u64) -> Result<u32, RiscvError> {
1389 let read_idx = self.schedule_read_dm_register_untyped(address)?;
1390 let register_value = self.dtm.read_deferred_result(read_idx)?.into_u32();
1391
1392 Ok(register_value)
1393 }
1394
1395 pub fn write_dm_register<R: MemoryMappedRegister<u32>>(
1397 &mut self,
1398 register: R,
1399 ) -> Result<(), RiscvError> {
1400 tracing::debug!(
1403 "Write DM register '{}' at {:#010x} = {:x?}",
1404 R::NAME,
1405 R::get_mmio_address(),
1406 register
1407 );
1408
1409 self.write_dm_register_untyped(R::get_mmio_address(), register.into())
1410 }
1411
1412 fn write_dm_register_untyped(&mut self, address: u64, value: u32) -> Result<(), RiscvError> {
1416 self.cache_write(address, value);
1417 self.dtm.write_with_timeout(address, value, RISCV_TIMEOUT)?;
1418
1419 Ok(())
1420 }
1421
1422 fn cache_write(&mut self, address: u64, value: u32) {
1423 if address == Dmcontrol::ADDRESS_OFFSET {
1424 self.state.current_dmcontrol = Dmcontrol(value);
1425 }
1426 }
1427
1428 fn schedule_write_progbuf(&mut self, index: usize, value: u32) -> Result<(), RiscvError> {
1429 match index {
1430 0 => self.schedule_write_dm_register(Progbuf0(value)),
1431 1 => self.schedule_write_dm_register(Progbuf1(value)),
1432 2 => self.schedule_write_dm_register(Progbuf2(value)),
1433 3 => self.schedule_write_dm_register(Progbuf3(value)),
1434 4 => self.schedule_write_dm_register(Progbuf4(value)),
1435 5 => self.schedule_write_dm_register(Progbuf5(value)),
1436 6 => self.schedule_write_dm_register(Progbuf6(value)),
1437 7 => self.schedule_write_dm_register(Progbuf7(value)),
1438 8 => self.schedule_write_dm_register(Progbuf8(value)),
1439 9 => self.schedule_write_dm_register(Progbuf9(value)),
1440 10 => self.schedule_write_dm_register(Progbuf10(value)),
1441 11 => self.schedule_write_dm_register(Progbuf11(value)),
1442 12 => self.schedule_write_dm_register(Progbuf12(value)),
1443 13 => self.schedule_write_dm_register(Progbuf13(value)),
1444 14 => self.schedule_write_dm_register(Progbuf14(value)),
1445 15 => self.schedule_write_dm_register(Progbuf15(value)),
1446 e => Err(RiscvError::UnsupportedProgramBufferRegister(e)),
1447 }
1448 }
1449
1450 pub(crate) fn schedule_setup_program_buffer(&mut self, data: &[u32]) -> Result<(), RiscvError> {
1451 let required_len = if self.state.implicit_ebreak {
1452 data.len()
1453 } else {
1454 data.len() + 1
1455 };
1456
1457 if required_len > self.state.progbuf_size as usize {
1458 return Err(RiscvError::ProgramBufferTooSmall {
1459 required: required_len,
1460 actual: self.state.progbuf_size as usize,
1461 });
1462 }
1463
1464 if data == &self.state.progbuf_cache[..data.len()] {
1465 tracing::debug!("Program buffer is up-to-date, skipping write.");
1467 return Ok(());
1468 }
1469
1470 for (index, word) in data.iter().enumerate() {
1471 self.schedule_write_progbuf(index, *word)?;
1472 }
1473
1474 if !self.state.implicit_ebreak || data.len() < self.state.progbuf_size as usize {
1479 self.schedule_write_progbuf(data.len(), assembly::EBREAK)?;
1480 }
1481
1482 self.state.progbuf_cache[..data.len()].copy_from_slice(data);
1484
1485 Ok(())
1486 }
1487
1488 fn perform_memory_read_sysbus<V: RiscvValue32>(
1490 &mut self,
1491 address: u64,
1492 ) -> Result<V, RiscvError> {
1493 loop {
1494 let mut sbcs = Sbcs(0);
1495
1496 sbcs.set_sbbusyerror(true);
1498
1499 sbcs.set_sbaccess(V::WIDTH as u32);
1500
1501 sbcs.set_sbreadonaddr(true);
1502
1503 self.schedule_write_dm_register(sbcs)?;
1504 if self.state.xlen_64 {
1505 self.schedule_write_dm_register(Sbaddress1((address >> 32) as u32))?;
1506 }
1507 self.schedule_write_dm_register(Sbaddress0(address as u32))?;
1508
1509 let mut results = vec![];
1510 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut results)?;
1511
1512 let sbcs = self.read_dm_register::<Sbcs>()?;
1514 if sbcs.sberror() != 0 {
1515 break Err(RiscvError::SystemBusAccess);
1516 }
1517 if !sbcs.sbbusyerror() {
1518 break V::read_scheduled_result(self, &mut results);
1519 }
1520 tracing::debug!("System bus was busy while reading, repeating operation");
1521 }
1522 }
1523
1524 fn perform_memory_read_multiple_sysbus<V: RiscvValue32>(
1528 &mut self,
1529 address: u64,
1530 data: &mut [V],
1531 ) -> Result<(), RiscvError> {
1532 if data.is_empty() {
1533 return Ok(());
1534 }
1535 loop {
1536 let mut sbcs = Sbcs(0);
1537
1538 sbcs.set_sbbusyerror(true);
1540
1541 sbcs.set_sbaccess(V::WIDTH as u32);
1542
1543 sbcs.set_sbreadonaddr(true);
1544
1545 sbcs.set_sbreadondata(true);
1546 sbcs.set_sbautoincrement(true);
1547
1548 self.schedule_write_dm_register(sbcs)?;
1549
1550 if self.state.xlen_64 {
1551 self.schedule_write_dm_register(Sbaddress1((address >> 32) as u32))?;
1552 }
1553 self.schedule_write_dm_register(Sbaddress0(address as u32))?;
1554
1555 let data_len = data.len();
1556
1557 let mut read_results = Vec::with_capacity(data_len);
1558 for _ in data[..data_len - 1].iter() {
1559 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut read_results)?;
1560 }
1561
1562 self.schedule_write_dm_register(Sbcs(0))?;
1563
1564 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut read_results)?;
1566
1567 let sbcs = self.read_dm_register::<Sbcs>()?;
1568
1569 for out in data.iter_mut() {
1570 *out = V::read_scheduled_result(self, &mut read_results)?;
1571 }
1572
1573 if sbcs.sberror() != 0 {
1575 break Err(RiscvError::SystemBusAccess);
1576 }
1577 if !sbcs.sbbusyerror() {
1578 break Ok(());
1579 }
1580 tracing::debug!("System bus was busy while reading, repeating operation");
1581 }
1582 }
1583
1584 fn wait_for_idle(&mut self, timeout: Duration) -> Result<(), RiscvError> {
1586 let start = Instant::now();
1587 loop {
1588 let status: Abstractcs = self.read_dm_register()?;
1589 match AbstractCommandErrorKind::parse(status) {
1590 Ok(_) => return Ok(()),
1591 Err(AbstractCommandErrorKind::Busy) => {}
1592 Err(other) => return Err(other.into()),
1593 }
1594
1595 if start.elapsed() > timeout {
1596 return Err(RiscvError::Timeout);
1597 }
1598 }
1599 }
1600
1601 fn wait_for_abstract_idle(&mut self, timeout: Duration) -> Result<(), RiscvError> {
1610 let start = Instant::now();
1611 loop {
1612 let status: Abstractcs = self.read_dm_register()?;
1613 if !status.busy() {
1614 AbstractCommandErrorKind::parse(status)?;
1615 return Ok(());
1616 }
1617 if start.elapsed() > timeout {
1618 return Err(RiscvError::Timeout);
1619 }
1620 }
1621 }
1622
1623 fn perform_memory_read_progbuf<V: RiscvValue32>(
1626 &mut self,
1627 address: u64,
1628 wait_for_idle: bool,
1629 ) -> Result<V, RiscvError> {
1630 self.halted_access(|core| {
1631 let s0 = core.save_s0()?;
1635
1636 let lw_command = assembly::lw(0, 8, V::WIDTH as u8, 8);
1637
1638 core.schedule_setup_program_buffer(&[lw_command])?;
1639
1640 core.schedule_write_address_to_s0_and_exec(address)?;
1641
1642 if wait_for_idle {
1643 core.wait_for_idle(Duration::from_millis(10))?;
1644 }
1645
1646 let value = core.abstract_cmd_register_read(registers::S0)?;
1648
1649 core.restore_s0(s0)?;
1651
1652 Ok(V::from_register_value(value))
1653 })
1654 }
1655
1656 fn autoexec_prime_pipeline(&mut self, address: u64) -> Result<(), RiscvError> {
1669 self.write_address_to_s0(address)?;
1671
1672 let aarsize = if self.state.xlen_64 {
1676 RiscvBusAccess::A64
1677 } else {
1678 RiscvBusAccess::A32
1679 };
1680 let mut cmd = AccessRegisterCommand(0);
1681 cmd.set_cmd_type(0);
1682 cmd.set_transfer(true);
1683 cmd.set_write(false);
1684 cmd.set_aarsize(aarsize);
1685 cmd.set_postexec(true);
1686 cmd.set_regno((registers::S1).id.0 as u32);
1687 self.execute_abstract_command(cmd.0)?;
1688
1689 let mut abstractauto = Abstractauto(0);
1691 abstractauto.set_autoexecdata(1);
1692 self.write_dm_register(abstractauto)?;
1693
1694 let _: Data0 = self.read_dm_register()?;
1698
1699 self.wait_for_abstract_idle(Duration::from_millis(100))?;
1701
1702 Ok(())
1703 }
1704
1705 fn read_multiple_autoexec<V: RiscvValue32>(
1706 &mut self,
1707 address: u64,
1708 data: &mut [V],
1709 ) -> Result<(), RiscvError> {
1710 let data_len = data.len();
1711
1712 self.autoexec_prime_pipeline(address)?;
1718
1719 let loop_count = data_len.saturating_sub(2);
1726 let chunk_size: usize = 256;
1727 let mut out_idx = 0;
1728
1729 while out_idx < loop_count {
1730 let batch_end = core::cmp::min(out_idx + chunk_size, loop_count);
1731 let batch_len = batch_end - out_idx;
1732
1733 let mut result_idxs = Vec::with_capacity(batch_len);
1734 for _ in 0..batch_len {
1735 let idx = self.schedule_read_dm_register::<Data0>()?;
1736 result_idxs.push(idx);
1737 }
1738
1739 for (i, idx) in result_idxs.into_iter().enumerate() {
1740 let value = self.dtm.read_deferred_result(idx)?.into_u32();
1741 data[out_idx + i] = V::from_register_value(value);
1742 }
1743
1744 match self.wait_for_abstract_idle(Duration::from_millis(100)) {
1745 Ok(()) => {
1746 out_idx = batch_end;
1747 }
1748 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::Busy)) => {
1749 let mut cs = Abstractcs(0);
1750 cs.set_cmderr(0x7);
1751 self.write_dm_register(cs)?;
1752 self.write_dm_register(Abstractauto(0))?;
1753
1754 let current_addr = if self.state.xlen_64 {
1755 self.abstract_cmd_register_read_64(registers::S0)?
1756 } else {
1757 self.abstract_cmd_register_read(registers::S0)? as u64
1758 };
1759 let width = V::WIDTH.byte_width() as u64;
1760 let progress = ((current_addr - address) / width) as usize;
1761 let reliable = progress.saturating_sub(2);
1762
1763 tracing::warn!(
1764 "Autoexec Busy during chunk [{}, {}). \
1765 S0={:#x}, progress={}, reliable={}",
1766 out_idx,
1767 batch_end,
1768 current_addr,
1769 progress,
1770 reliable,
1771 );
1772
1773 if reliable <= out_idx {
1774 return Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::Busy));
1775 }
1776
1777 let new_addr = address + reliable as u64 * width;
1778 self.autoexec_prime_pipeline(new_addr)?;
1779 out_idx = reliable;
1780 }
1781 Err(e) => return Err(e),
1782 }
1783 }
1784
1785 self.write_dm_register(Abstractauto(0))?;
1787
1788 let penult: Data0 = self.read_dm_register()?;
1789 data[data_len - 2] = V::from_register_value(penult.0);
1790
1791 let last_val = if self.state.xlen_64 {
1792 self.abstract_cmd_register_read_64(registers::S1)? as u32
1793 } else {
1794 self.abstract_cmd_register_read(registers::S1)?
1795 };
1796 data[data_len - 1] = V::from_register_value(last_val);
1797
1798 Ok(())
1799 }
1800
1801 fn read_multiple_no_autoexec<V: RiscvValue32>(
1802 &mut self,
1803 address: u64,
1804 data: &mut [V],
1805 wait_for_idle: bool,
1806 ) -> Result<(), RiscvError> {
1807 let data_len = data.len();
1808
1809 self.schedule_write_address_to_s0_and_exec(address)?;
1810
1811 if wait_for_idle {
1812 self.wait_for_idle(Duration::from_millis(10))?;
1813 }
1814
1815 let aarsize = if self.state.xlen_64 {
1816 RiscvBusAccess::A64
1817 } else {
1818 RiscvBusAccess::A32
1819 };
1820 let mut result_idxs = Vec::with_capacity(data_len - 1);
1821 for out_idx in 0..data_len - 1 {
1822 let mut command = AccessRegisterCommand(0);
1823 command.set_cmd_type(0);
1824 command.set_transfer(true);
1825 command.set_write(false);
1826 command.set_aarsize(aarsize);
1827 command.set_postexec(true);
1828 command.set_regno((registers::S1).id.0 as u32);
1829
1830 self.schedule_write_dm_register(command)?;
1831 let value_idx = self.schedule_read_dm_register::<Data0>()?;
1832 result_idxs.push((out_idx, value_idx));
1833
1834 if wait_for_idle {
1835 self.wait_for_idle(Duration::from_millis(10))?;
1836 }
1837 }
1838
1839 let last_value = if self.state.xlen_64 {
1840 self.abstract_cmd_register_read_64(registers::S1)? as u32
1841 } else {
1842 self.abstract_cmd_register_read(registers::S1)?
1843 };
1844 data[data.len() - 1] = V::from_register_value(last_value);
1845
1846 for (out_idx, value_idx) in result_idxs {
1847 let value = self.dtm.read_deferred_result(value_idx)?.into_u32();
1848 data[out_idx] = V::from_register_value(value);
1849 }
1850
1851 Ok(())
1852 }
1853
1854 fn perform_memory_read_multiple_progbuf<V: RiscvValue32>(
1855 &mut self,
1856 address: u64,
1857 data: &mut [V],
1858 wait_for_idle: bool,
1859 ) -> Result<(), RiscvError> {
1860 if data.is_empty() {
1861 return Ok(());
1862 }
1863
1864 if data.len() == 1 {
1865 data[0] = self.perform_memory_read_progbuf(address, wait_for_idle)?;
1866 return Ok(());
1867 }
1868
1869 self.halted_access(|core| {
1870 let s0 = core.save_s0()?;
1871 let s1 = core.save_s1()?;
1872
1873 let lw_command: u32 = assembly::lw(0, 8, V::WIDTH as u8, 9);
1874
1875 core.schedule_setup_program_buffer(&[
1876 lw_command,
1877 assembly::addi(8, 8, V::WIDTH.byte_width() as i16),
1878 ])?;
1879
1880 let use_autoexec = core.state.supports_autoexec && data.len() >= 16;
1881
1882 let read_result: Result<(), RiscvError> = if use_autoexec {
1883 core.read_multiple_autoexec(address, data)
1884 } else {
1885 core.read_multiple_no_autoexec(address, data, wait_for_idle)
1886 };
1887
1888 let _ = core.write_dm_register(Abstractauto(0));
1889 let mut cs_clear = Abstractcs(0);
1890 cs_clear.set_cmderr(0x7);
1891 let _ = core.write_dm_register(cs_clear);
1892 core.state.progbuf_cache = [0u32; 16];
1893 let _ = core.restore_s0(s0);
1894 let _ = core.restore_s1(s1);
1895
1896 read_result
1897 })
1898 }
1899
1900 fn perform_memory_write_sysbus<V: RiscvValue>(
1902 &mut self,
1903 address: u64,
1904 data: &[V],
1905 ) -> Result<(), RiscvError> {
1906 if data.is_empty() {
1907 return Ok(());
1908 }
1909
1910 loop {
1911 let mut sbcs = Sbcs(0);
1912 sbcs.set_sbbusyerror(true);
1914 sbcs.set_sbaccess(V::WIDTH as u32);
1916 sbcs.set_sbautoincrement(true);
1917
1918 self.schedule_write_dm_register(sbcs)?;
1919
1920 if self.state.xlen_64 {
1921 self.schedule_write_dm_register(Sbaddress1((address >> 32) as u32))?;
1922 }
1923 self.schedule_write_dm_register(Sbaddress0(address as u32))?;
1924 for value in data {
1925 self.schedule_write_large_dtm_register::<V, Sbdata>(*value)?;
1926 }
1927
1928 let sbcs = self.read_dm_register::<Sbcs>()?;
1930 if sbcs.sberror() != 0 {
1931 break Err(RiscvError::SystemBusAccess);
1932 }
1933 if !sbcs.sbbusyerror() {
1934 break Ok(());
1935 }
1936 tracing::debug!("System bus was busy while writing, repeating write");
1937 }
1938 }
1939
1940 fn perform_memory_write_progbuf<V: RiscvValue32>(
1943 &mut self,
1944 address: u64,
1945 data: V,
1946 wait_for_idle: bool,
1947 ) -> Result<(), RiscvError> {
1948 self.halted_access(|core| {
1949 tracing::debug!(
1950 "Memory write using progbuf - {:#010x} = {:#?}",
1951 address,
1952 data
1953 );
1954
1955 let s0 = core.save_s0()?;
1957 let s1 = core.save_s1()?;
1958
1959 let sw_command = assembly::sw(0, 8, V::WIDTH as u32, 9);
1960
1961 core.schedule_setup_program_buffer(&[sw_command])?;
1962
1963 core.write_address_to_s0(address)?;
1965
1966 core.schedule_write_dm_register(Data0(data.into()))?;
1968
1969 let mut command = AccessRegisterCommand(0);
1971 command.set_cmd_type(0);
1972 command.set_transfer(true);
1973 command.set_write(true);
1974
1975 command.set_aarsize(RiscvBusAccess::A32);
1977 command.set_postexec(true);
1978
1979 command.set_regno((registers::S1).id.0 as u32);
1981
1982 core.schedule_write_dm_register(command)?;
1983
1984 if wait_for_idle && let Err(error) = core.wait_for_idle(Duration::from_millis(10)) {
1985 tracing::error!(
1986 "Executing the abstract command for write_{} failed: {:?}",
1987 V::WIDTH.byte_width() * 8,
1988 error
1989 );
1990
1991 return Err(error);
1992 }
1993
1994 core.restore_s0(s0)?;
1995 core.restore_s1(s1)?;
1996
1997 Ok(())
1998 })
1999 }
2000
2001 fn perform_memory_write_multiple_progbuf<V: RiscvValue32>(
2004 &mut self,
2005 address: u64,
2006 data: &[V],
2007 wait_for_idle: bool,
2008 ) -> Result<(), RiscvError> {
2009 if data.is_empty() {
2010 return Ok(());
2011 }
2012
2013 if data.len() == 1 {
2014 self.perform_memory_write_progbuf(address, data[0], wait_for_idle)?;
2015 return Ok(());
2016 }
2017
2018 self.halted_access(|core| {
2019 let s0 = core.save_s0()?;
2020 let s1 = core.save_s1()?;
2021
2022 core.schedule_setup_program_buffer(&[
2026 assembly::sw(0, 8, V::WIDTH as u32, 9),
2027 assembly::addi(8, 8, V::WIDTH.byte_width() as i16),
2028 ])?;
2029
2030 core.write_address_to_s0(address)?;
2031
2032 for value in data {
2033 core.schedule_write_dm_register(Data0((*value).into()))?;
2035
2036 let mut command = AccessRegisterCommand(0);
2038 command.set_cmd_type(0);
2039 command.set_transfer(true);
2040 command.set_write(true);
2041
2042 command.set_aarsize(RiscvBusAccess::A32);
2044 command.set_postexec(true);
2045
2046 command.set_regno((registers::S1).id.0 as u32);
2048
2049 core.schedule_write_dm_register(command)?;
2050
2051 if wait_for_idle && let Err(error) = core.wait_for_idle(Duration::from_millis(10)) {
2052 tracing::error!(
2053 "Executing the abstract command for write_multiple_{} failed: {:?}",
2054 V::WIDTH.byte_width() * 8,
2055 error,
2056 );
2057
2058 return Err(error);
2059 }
2060 }
2061
2062 core.restore_s0(s0)?;
2065 core.restore_s1(s1)?;
2066
2067 Ok(())
2068 })
2069 }
2070
2071 fn postexec_command(&self) -> AccessRegisterCommand {
2079 let mut cmd = AccessRegisterCommand(0);
2080 cmd.set_cmd_type(0);
2081 cmd.set_postexec(true);
2082 cmd.set_transfer(false);
2083 cmd.set_aarsize(if self.state.xlen_64 {
2084 RiscvBusAccess::A64
2085 } else {
2086 RiscvBusAccess::A32
2087 });
2088 cmd.set_regno(0x1000); cmd
2090 }
2091
2092 pub(crate) fn execute_abstract_command(&mut self, command: u32) -> Result<(), RiscvError> {
2093 let mut dmcontrol = self.state.current_dmcontrol;
2099 dmcontrol.set_dmactive(true);
2100 dmcontrol.set_haltreq(false);
2101 dmcontrol.set_resumereq(false);
2102 dmcontrol.set_ackhavereset(false);
2103 self.schedule_write_dm_register(dmcontrol)?;
2104
2105 fn do_execute_abstract_command(
2106 core: &mut RiscvCommunicationInterface,
2107 command: Command,
2108 ) -> Result<(), RiscvError> {
2109 let mut abstractcs_clear = Abstractcs(0);
2111 abstractcs_clear.set_cmderr(0x7);
2112
2113 core.schedule_write_dm_register(abstractcs_clear)?;
2114 core.schedule_write_dm_register(command)?;
2115
2116 let start_time = Instant::now();
2117
2118 let mut abstractcs;
2120 loop {
2121 abstractcs = core.read_dm_register::<Abstractcs>()?;
2122
2123 if !abstractcs.busy() {
2124 break;
2125 }
2126
2127 if start_time.elapsed() > RISCV_TIMEOUT {
2128 return Err(RiscvError::Timeout);
2129 }
2130 }
2131
2132 tracing::debug!("abstracts: {:?}", abstractcs);
2133
2134 AbstractCommandErrorKind::parse(abstractcs)?;
2136
2137 Ok(())
2138 }
2139
2140 match do_execute_abstract_command(self, Command(command)) {
2141 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::HaltResume)) => {
2142 self.state.is_halted = false;
2145 if !self.core_halted()? {
2146 self.halted_access(|core| do_execute_abstract_command(core, Command(command)))
2149 } else {
2150 err
2153 }
2154 }
2155 other => other,
2156 }
2157 }
2158
2159 fn check_abstract_cmd_register_support(
2161 &self,
2162 regno: RegisterId,
2163 rw: CoreRegisterAbstractCmdSupport,
2164 ) -> bool {
2165 if let Some(status) = self.state.abstract_cmd_register_info.get(®no) {
2166 status.supports(rw)
2167 } else {
2168 true
2170 }
2171 }
2172
2173 fn set_abstract_cmd_register_unsupported(
2175 &mut self,
2176 regno: RegisterId,
2177 rw: CoreRegisterAbstractCmdSupport,
2178 ) {
2179 let entry = self
2180 .state
2181 .abstract_cmd_register_info
2182 .entry(regno)
2183 .or_insert(CoreRegisterAbstractCmdSupport::BOTH);
2184
2185 entry.unset(rw);
2186 }
2187
2188 pub(crate) fn abstract_cmd_register_read(
2190 &mut self,
2191 regno: impl Into<RegisterId>,
2192 ) -> Result<u32, RiscvError> {
2193 let regno = regno.into();
2194
2195 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::READ) {
2197 return Err(RiscvError::AbstractCommand(
2198 AbstractCommandErrorKind::NotSupported,
2199 ));
2200 }
2201
2202 let mut command = AccessRegisterCommand(0);
2204 command.set_cmd_type(0);
2205 command.set_transfer(true);
2206 command.set_aarsize(RiscvBusAccess::A32);
2207
2208 command.set_regno(regno.0 as u32);
2209
2210 match self.execute_abstract_command(command.0) {
2211 Ok(_) => (),
2212 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
2213 self.set_abstract_cmd_register_unsupported(
2215 regno,
2216 CoreRegisterAbstractCmdSupport::READ,
2217 );
2218 err?;
2219 }
2220 Err(e) => return Err(e),
2221 }
2222
2223 let register_value: Data0 = self.read_dm_register()?;
2224
2225 Ok(register_value.into())
2226 }
2227
2228 pub(crate) fn abstract_cmd_register_write<V: RiscvValue>(
2229 &mut self,
2230 regno: impl Into<RegisterId>,
2231 value: V,
2232 ) -> Result<(), RiscvError> {
2233 let regno = regno.into();
2234
2235 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::WRITE) {
2237 return Err(RiscvError::AbstractCommand(
2238 AbstractCommandErrorKind::NotSupported,
2239 ));
2240 }
2241
2242 let mut command = AccessRegisterCommand(0);
2244 command.set_cmd_type(0);
2245 command.set_transfer(true);
2246 command.set_write(true);
2247 command.set_aarsize(V::WIDTH);
2248
2249 command.set_regno(regno.0 as u32);
2250
2251 self.schedule_write_large_dtm_register::<V, Arg0>(value)?;
2252
2253 match self.execute_abstract_command(command.0) {
2254 Ok(_) => Ok(()),
2255 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
2256 self.set_abstract_cmd_register_unsupported(
2258 regno,
2259 CoreRegisterAbstractCmdSupport::WRITE,
2260 );
2261 err
2262 }
2263 Err(e) => Err(e),
2264 }
2265 }
2266
2267 pub fn read_csr_progbuf(&mut self, address: u16) -> Result<u64, RiscvError> {
2272 self.halted_access(|core| {
2273 if address > RISCV_MAX_CSR_ADDR {
2275 return Err(RiscvError::UnsupportedCsrAddress(address));
2276 }
2277 let csrr_cmd = assembly::csrr(8, address);
2279 core.schedule_setup_program_buffer(&[csrr_cmd])?;
2280 let postexec_cmd = core.postexec_command();
2281 core.run_with_s0_saved(|c| {
2282 c.execute_abstract_command(postexec_cmd.0)?;
2283 c.read_s0_xlen()
2284 })
2285 })
2286 }
2287
2288 pub(crate) fn read_csr_progbuf_64(&mut self, address: u16) -> Result<u64, RiscvError> {
2300 let saved_xlen = self.state.xlen_64;
2301 self.state.xlen_64 = true;
2302 let result = self.read_csr_progbuf(address);
2303 self.state.xlen_64 = saved_xlen;
2304 result
2305 }
2306
2307 pub fn write_csr_progbuf(&mut self, address: u16, value: u64) -> Result<(), RiscvError> {
2312 self.halted_access(|core| {
2313 if address > RISCV_MAX_CSR_ADDR {
2314 return Err(RiscvError::UnsupportedCsrAddress(address));
2315 }
2316 let csrw_cmd = assembly::csrw(address, 8);
2317 core.schedule_setup_program_buffer(&[csrw_cmd])?;
2318 let postexec_cmd = core.postexec_command();
2319 core.run_with_s0_saved(|c| {
2320 c.write_s0_xlen(value)?;
2321 c.execute_abstract_command(postexec_cmd.0)
2322 })
2323 })
2324 }
2325
2326 fn read_word<V: RiscvValue32>(&mut self, address: u64) -> Result<V, crate::Error> {
2327 if !self.state.xlen_64 {
2328 valid_32bit_address(address)?;
2329 }
2330 let result = match self.state.memory_access_method(V::WIDTH, address) {
2331 MemoryAccessMethod::ProgramBuffer => {
2332 self.perform_memory_read_progbuf(address, false)?
2333 }
2334 MemoryAccessMethod::WaitingProgramBuffer => {
2335 self.perform_memory_read_progbuf(address, true)?
2336 }
2337 MemoryAccessMethod::SystemBus => self.perform_memory_read_sysbus(address)?,
2338 MemoryAccessMethod::AbstractCommand => {
2339 return Err(crate::Error::NotImplemented(
2340 "Memory access using abstract commands is not implemented",
2341 ));
2342 }
2343 };
2344
2345 Ok(result)
2346 }
2347
2348 fn read_multiple<V: RiscvValue32>(
2349 &mut self,
2350 address: u64,
2351 data: &mut [V],
2352 ) -> Result<(), crate::Error> {
2353 if !self.state.xlen_64 {
2354 valid_32bit_address(address)?;
2355 }
2356 let address_range = address..(address + (data.len() * V::WIDTH.byte_width()) as u64);
2357 let access_method = self
2358 .state
2359 .memory_range_access_method(V::WIDTH, address_range);
2360 tracing::debug!(
2361 "read_multiple({:?}) from {:#08x} using {:?}",
2362 V::WIDTH,
2363 address,
2364 access_method
2365 );
2366
2367 match access_method {
2368 MemoryAccessMethod::ProgramBuffer => {
2369 self.perform_memory_read_multiple_progbuf(address, data, false)?;
2370 }
2371 MemoryAccessMethod::WaitingProgramBuffer => {
2372 self.perform_memory_read_multiple_progbuf(address, data, true)?;
2373 }
2374 MemoryAccessMethod::SystemBus => {
2375 self.perform_memory_read_multiple_sysbus(address, data)?;
2376 }
2377 MemoryAccessMethod::AbstractCommand => {
2378 return Err(crate::Error::NotImplemented(
2379 "Memory access using abstract commands is not implemented",
2380 ));
2381 }
2382 };
2383
2384 Ok(())
2385 }
2386
2387 fn write_word<V: RiscvValue32>(&mut self, address: u64, data: V) -> Result<(), crate::Error> {
2388 if !self.state.xlen_64 {
2389 valid_32bit_address(address)?;
2390 }
2391 match self.state.memory_access_method(V::WIDTH, address) {
2392 MemoryAccessMethod::ProgramBuffer => {
2393 self.perform_memory_write_progbuf(address, data, false)?
2394 }
2395 MemoryAccessMethod::WaitingProgramBuffer => {
2396 self.perform_memory_write_progbuf(address, data, true)?
2397 }
2398 MemoryAccessMethod::SystemBus => self.perform_memory_write_sysbus(address, &[data])?,
2399 MemoryAccessMethod::AbstractCommand => {
2400 return Err(crate::Error::NotImplemented(
2401 "Memory access using abstract commands is not implemented",
2402 ));
2403 }
2404 };
2405
2406 Ok(())
2407 }
2408
2409 fn write_multiple<V: RiscvValue32>(
2410 &mut self,
2411 address: u64,
2412 data: &[V],
2413 ) -> Result<(), crate::Error> {
2414 if !self.state.xlen_64 {
2415 valid_32bit_address(address)?;
2416 }
2417 let address_range = address..(address + (data.len() * V::WIDTH.byte_width()) as u64);
2418 let access_method = self
2419 .state
2420 .memory_range_access_method(V::WIDTH, address_range);
2421 match access_method {
2422 MemoryAccessMethod::SystemBus => self.perform_memory_write_sysbus(address, data)?,
2423 MemoryAccessMethod::ProgramBuffer => {
2424 self.perform_memory_write_multiple_progbuf(address, data, false)?
2425 }
2426 MemoryAccessMethod::WaitingProgramBuffer => {
2427 self.perform_memory_write_multiple_progbuf(address, data, true)?
2428 }
2429 MemoryAccessMethod::AbstractCommand => {
2430 return Err(crate::Error::NotImplemented(
2431 "Memory access using abstract commands is not implemented",
2432 ));
2433 }
2434 }
2435
2436 Ok(())
2437 }
2438
2439 pub(crate) fn schedule_write_dm_register<R: MemoryMappedRegister<u32>>(
2440 &mut self,
2441 register: R,
2442 ) -> Result<(), RiscvError> {
2443 tracing::debug!(
2446 "Write DM register '{}' at {:#010x} = {:x?}",
2447 R::NAME,
2448 R::get_mmio_address(),
2449 register
2450 );
2451
2452 self.schedule_write_dm_register_untyped(R::get_mmio_address(), register.into())?;
2453 Ok(())
2454 }
2455
2456 fn schedule_write_dm_register_untyped(
2460 &mut self,
2461 address: u64,
2462 value: u32,
2463 ) -> Result<Option<DeferredResultIndex>, RiscvError> {
2464 self.cache_write(address, value);
2465 self.dtm.schedule_write(address, value)
2466 }
2467
2468 pub(super) fn schedule_read_dm_register<R: MemoryMappedRegister<u32>>(
2469 &mut self,
2470 ) -> Result<DeferredResultIndex, RiscvError> {
2471 tracing::debug!(
2472 "Reading DM register '{}' at {:#010x}",
2473 R::NAME,
2474 R::get_mmio_address()
2475 );
2476
2477 self.schedule_read_dm_register_untyped(R::get_mmio_address())
2478 }
2479
2480 fn schedule_read_dm_register_untyped(
2484 &mut self,
2485 address: u64,
2486 ) -> Result<DeferredResultIndex, RiscvError> {
2487 self.dtm.schedule_read(address)
2489 }
2490
2491 fn schedule_read_large_dtm_register<V, R>(
2492 &mut self,
2493 results: &mut Vec<DeferredResultIndex>,
2494 ) -> Result<(), RiscvError>
2495 where
2496 V: RiscvValue,
2497 R: LargeRegister,
2498 {
2499 V::schedule_read_from_register::<R>(self, results)
2500 }
2501
2502 fn schedule_write_large_dtm_register<V, R>(
2503 &mut self,
2504 value: V,
2505 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2506 where
2507 V: RiscvValue,
2508 R: LargeRegister,
2509 {
2510 V::schedule_write_to_register::<R>(self, value)
2511 }
2512
2513 pub(crate) fn supports_reset_halt_req(&mut self) -> Result<bool, RiscvError> {
2518 if let Some(has_reset_halt_req) = self.state.hasresethaltreq {
2519 Ok(has_reset_halt_req)
2520 } else {
2521 let dmstatus: Dmstatus = self.read_dm_register()?;
2522
2523 self.state.hasresethaltreq = Some(dmstatus.hasresethaltreq());
2524
2525 Ok(dmstatus.hasresethaltreq())
2526 }
2527 }
2528
2529 pub fn resume_core(&mut self) -> Result<(), RiscvError> {
2531 self.state.is_halted = false; let mut dmcontrol = self.state.current_dmcontrol;
2535 dmcontrol.set_dmactive(true);
2536 dmcontrol.set_resumereq(true);
2537 self.schedule_write_dm_register(dmcontrol)?;
2538
2539 let status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
2541
2542 dmcontrol.set_resumereq(false);
2544 self.write_dm_register(dmcontrol)?;
2545
2546 let status = Dmstatus(self.dtm.read_deferred_result(status_idx)?.into_u32());
2547 if status.allresumeack() || status.allrunning() {
2548 return Ok(());
2549 }
2550 self.wait_for_resume_ack(Duration::from_millis(50))
2551 }
2552
2553 fn wait_for_resume_ack(&mut self, timeout: Duration) -> Result<(), RiscvError> {
2556 let start = Instant::now();
2557 loop {
2558 let dmstatus: Dmstatus = self.read_dm_register()?;
2559 if dmstatus.allresumeack() || dmstatus.allrunning() {
2560 return Ok(());
2561 }
2562 if start.elapsed() >= timeout {
2563 return Err(RiscvError::RequestNotAcknowledged);
2564 }
2565 std::thread::sleep(Duration::from_millis(1));
2566 }
2567 }
2568
2569 pub fn reset_hart_and_halt(&mut self, timeout: Duration) -> Result<(), RiscvError> {
2571 tracing::debug!("Resetting core, setting hartreset bit");
2572
2573 let mut dmcontrol = self.state.current_dmcontrol;
2574 dmcontrol.set_dmactive(true);
2575 dmcontrol.set_hartreset(true);
2576 dmcontrol.set_haltreq(true);
2577
2578 self.write_dm_register(dmcontrol)?;
2579
2580 let readback: Dmcontrol = self.read_dm_register()?;
2582
2583 if readback.hartreset() {
2584 tracing::debug!("Clearing hartreset bit");
2585 let mut dmcontrol = readback;
2587 dmcontrol.set_dmactive(true);
2588 dmcontrol.set_haltreq(true);
2589 dmcontrol.set_hartreset(false);
2590
2591 self.write_dm_register(dmcontrol)?;
2592 } else {
2593 tracing::debug!("Hartreset bit not supported, using ndmreset");
2597 dmcontrol.set_hartreset(false);
2598 dmcontrol.set_ndmreset(true);
2599 dmcontrol.set_haltreq(true);
2600
2601 self.write_dm_register(dmcontrol)?;
2602
2603 tracing::debug!("Clearing ndmreset bit");
2604 dmcontrol.set_ndmreset(false);
2605 dmcontrol.set_haltreq(true);
2606
2607 self.write_dm_register(dmcontrol)?;
2608 }
2609
2610 let start = Instant::now();
2611
2612 loop {
2613 let readback: Dmstatus = self.read_dm_register()?;
2615
2616 if self.state.debug_version == DebugModuleVersion::Version1_0
2618 && readback.ndmresetpending()
2619 {
2620 if start.elapsed() > timeout {
2621 return Err(RiscvError::RequestNotAcknowledged);
2622 }
2623 continue;
2624 }
2625
2626 if readback.allhavereset() && readback.allhalted() {
2627 break;
2628 }
2629
2630 if start.elapsed() > timeout {
2631 return Err(RiscvError::RequestNotAcknowledged);
2632 }
2633 self.write_dm_register(dmcontrol)?;
2634 }
2635
2636 dmcontrol.set_haltreq(false);
2638 dmcontrol.set_ackhavereset(true);
2639 dmcontrol.set_hartreset(false);
2640 dmcontrol.set_ndmreset(false);
2641
2642 self.write_dm_register(dmcontrol)?;
2643
2644 self.debug_on_sw_breakpoint(true)?;
2646
2647 Ok(())
2648 }
2649
2650 fn debug_on_sw_breakpoint(&mut self, enabled: bool) -> Result<(), RiscvError> {
2651 let raw = self.read_csr(0x7b0)?;
2652 let mut dcsr = Dcsr(raw as u32);
2653 tracing::debug!(
2654 "debug_on_sw_breakpoint({}): DCSR before = {:#010x}",
2655 enabled,
2656 raw
2657 );
2658
2659 dcsr.set_ebreakm(enabled);
2660 dcsr.set_ebreaks(enabled);
2661 dcsr.set_ebreaku(enabled);
2662
2663 tracing::debug!(
2664 "debug_on_sw_breakpoint({}): DCSR to write = {:#010x}",
2665 enabled,
2666 dcsr.0
2667 );
2668
2669 self.write_csr(0x7b0, u64::from(dcsr.0))?;
2670 self.state.sw_breakpoint_debug_enabled = enabled;
2671 Ok(())
2672 }
2673
2674 pub fn memory_access_config(&mut self) -> &mut MemoryAccessConfig {
2676 &mut self.state.memory_access_config
2677 }
2678
2679 pub fn clear_abstractauto(&mut self) {
2685 if let Err(e) = self.write_dm_register(Abstractauto(0)) {
2686 tracing::debug!("Failed to clear abstractauto: {:?}", e);
2687 }
2688 let mut abstractcs_clear = Abstractcs(0);
2690 abstractcs_clear.set_cmderr(0x7);
2691 if let Err(e) = self.write_dm_register(abstractcs_clear) {
2692 tracing::debug!("Failed to clear abstractcs cmderr: {:?}", e);
2693 }
2694 self.state.progbuf_cache = [0u32; 16];
2696 }
2697}
2698
2699pub(crate) trait LargeRegister {
2700 const R0_ADDRESS: u8;
2701 const R1_ADDRESS: u8;
2702 const R2_ADDRESS: u8;
2703 const R3_ADDRESS: u8;
2704}
2705
2706struct Sbdata {}
2707
2708impl LargeRegister for Sbdata {
2709 const R0_ADDRESS: u8 = Sbdata0::ADDRESS_OFFSET as u8;
2710 const R1_ADDRESS: u8 = Sbdata1::ADDRESS_OFFSET as u8;
2711 const R2_ADDRESS: u8 = Sbdata2::ADDRESS_OFFSET as u8;
2712 const R3_ADDRESS: u8 = Sbdata3::ADDRESS_OFFSET as u8;
2713}
2714
2715struct Arg0 {}
2716
2717impl LargeRegister for Arg0 {
2718 const R0_ADDRESS: u8 = Data0::ADDRESS_OFFSET as u8;
2719 const R1_ADDRESS: u8 = Data1::ADDRESS_OFFSET as u8;
2720 const R2_ADDRESS: u8 = Data2::ADDRESS_OFFSET as u8;
2721 const R3_ADDRESS: u8 = Data3::ADDRESS_OFFSET as u8;
2722}
2723
2724pub(crate) trait RiscvValue32: RiscvValue + Into<u32> {
2726 fn from_register_value(value: u32) -> Self;
2727}
2728
2729impl RiscvValue32 for u8 {
2730 fn from_register_value(value: u32) -> Self {
2731 value as u8
2732 }
2733}
2734impl RiscvValue32 for u16 {
2735 fn from_register_value(value: u32) -> Self {
2736 value as u16
2737 }
2738}
2739impl RiscvValue32 for u32 {
2740 fn from_register_value(value: u32) -> Self {
2741 value
2742 }
2743}
2744
2745pub(crate) trait RiscvValue: std::fmt::Debug + Copy + Sized {
2748 const WIDTH: RiscvBusAccess;
2749
2750 fn schedule_read_from_register<R>(
2751 interface: &mut RiscvCommunicationInterface,
2752 results: &mut Vec<DeferredResultIndex>,
2753 ) -> Result<(), RiscvError>
2754 where
2755 R: LargeRegister;
2756
2757 fn read_scheduled_result(
2758 interface: &mut RiscvCommunicationInterface,
2759 results: &mut Vec<DeferredResultIndex>,
2760 ) -> Result<Self, RiscvError>;
2761
2762 fn schedule_write_to_register<R>(
2763 interface: &mut RiscvCommunicationInterface,
2764 value: Self,
2765 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2766 where
2767 R: LargeRegister;
2768}
2769
2770impl RiscvValue for u8 {
2771 const WIDTH: RiscvBusAccess = RiscvBusAccess::A8;
2772
2773 fn schedule_read_from_register<R>(
2774 interface: &mut RiscvCommunicationInterface,
2775 results: &mut Vec<DeferredResultIndex>,
2776 ) -> Result<(), RiscvError>
2777 where
2778 R: LargeRegister,
2779 {
2780 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2781 Ok(())
2782 }
2783
2784 fn read_scheduled_result(
2785 interface: &mut RiscvCommunicationInterface,
2786 results: &mut Vec<DeferredResultIndex>,
2787 ) -> Result<Self, RiscvError> {
2788 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2789
2790 Ok(result.into_u32() as u8)
2791 }
2792
2793 fn schedule_write_to_register<R>(
2794 interface: &mut RiscvCommunicationInterface,
2795 value: Self,
2796 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2797 where
2798 R: LargeRegister,
2799 {
2800 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value as u32)
2801 }
2802}
2803
2804impl RiscvValue for u16 {
2805 const WIDTH: RiscvBusAccess = RiscvBusAccess::A16;
2806
2807 fn schedule_read_from_register<R>(
2808 interface: &mut RiscvCommunicationInterface,
2809 results: &mut Vec<DeferredResultIndex>,
2810 ) -> Result<(), RiscvError>
2811 where
2812 R: LargeRegister,
2813 {
2814 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2815 Ok(())
2816 }
2817
2818 fn read_scheduled_result(
2819 interface: &mut RiscvCommunicationInterface,
2820 results: &mut Vec<DeferredResultIndex>,
2821 ) -> Result<Self, RiscvError> {
2822 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2823
2824 Ok(result.into_u32() as u16)
2825 }
2826
2827 fn schedule_write_to_register<R>(
2828 interface: &mut RiscvCommunicationInterface,
2829 value: Self,
2830 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2831 where
2832 R: LargeRegister,
2833 {
2834 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value as u32)
2835 }
2836}
2837
2838impl RiscvValue for u32 {
2839 const WIDTH: RiscvBusAccess = RiscvBusAccess::A32;
2840
2841 fn schedule_read_from_register<R>(
2842 interface: &mut RiscvCommunicationInterface,
2843 results: &mut Vec<DeferredResultIndex>,
2844 ) -> Result<(), RiscvError>
2845 where
2846 R: LargeRegister,
2847 {
2848 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2849 Ok(())
2850 }
2851
2852 fn read_scheduled_result(
2853 interface: &mut RiscvCommunicationInterface,
2854 results: &mut Vec<DeferredResultIndex>,
2855 ) -> Result<Self, RiscvError> {
2856 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2857
2858 Ok(result.into_u32())
2859 }
2860
2861 fn schedule_write_to_register<R>(
2862 interface: &mut RiscvCommunicationInterface,
2863 value: Self,
2864 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2865 where
2866 R: LargeRegister,
2867 {
2868 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value)
2869 }
2870}
2871
2872impl RiscvValue for u64 {
2873 const WIDTH: RiscvBusAccess = RiscvBusAccess::A64;
2874
2875 fn schedule_read_from_register<R>(
2876 interface: &mut RiscvCommunicationInterface,
2877 results: &mut Vec<DeferredResultIndex>,
2878 ) -> Result<(), RiscvError>
2879 where
2880 R: LargeRegister,
2881 {
2882 results.push(interface.schedule_read_dm_register_untyped(R::R1_ADDRESS as u64)?);
2883 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2884 Ok(())
2885 }
2886
2887 fn read_scheduled_result(
2888 interface: &mut RiscvCommunicationInterface,
2889 results: &mut Vec<DeferredResultIndex>,
2890 ) -> Result<Self, RiscvError> {
2891 let r1 = interface.dtm.read_deferred_result(results.remove(0))?;
2892 let r0 = interface.dtm.read_deferred_result(results.remove(0))?;
2893
2894 Ok(((r1.into_u32() as u64) << 32) | (r0.into_u32() as u64))
2895 }
2896
2897 fn schedule_write_to_register<R>(
2898 interface: &mut RiscvCommunicationInterface,
2899 value: Self,
2900 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2901 where
2902 R: LargeRegister,
2903 {
2904 let upper_bits = (value >> 32) as u32;
2905 let lower_bits = (value & 0xffff_ffff) as u32;
2906
2907 interface.schedule_write_dm_register_untyped(R::R1_ADDRESS as u64, upper_bits)?;
2911 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, lower_bits)
2912 }
2913}
2914
2915impl RiscvValue for u128 {
2916 const WIDTH: RiscvBusAccess = RiscvBusAccess::A128;
2917
2918 fn schedule_read_from_register<R>(
2919 interface: &mut RiscvCommunicationInterface,
2920 results: &mut Vec<DeferredResultIndex>,
2921 ) -> Result<(), RiscvError>
2922 where
2923 R: LargeRegister,
2924 {
2925 results.push(interface.schedule_read_dm_register_untyped(R::R3_ADDRESS as u64)?);
2926 results.push(interface.schedule_read_dm_register_untyped(R::R2_ADDRESS as u64)?);
2927 results.push(interface.schedule_read_dm_register_untyped(R::R1_ADDRESS as u64)?);
2928 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2929 Ok(())
2930 }
2931
2932 fn read_scheduled_result(
2933 interface: &mut RiscvCommunicationInterface,
2934 results: &mut Vec<DeferredResultIndex>,
2935 ) -> Result<Self, RiscvError> {
2936 let r3 = interface.dtm.read_deferred_result(results.remove(0))?;
2937 let r2 = interface.dtm.read_deferred_result(results.remove(0))?;
2938 let r1 = interface.dtm.read_deferred_result(results.remove(0))?;
2939 let r0 = interface.dtm.read_deferred_result(results.remove(0))?;
2940
2941 Ok(((r3.into_u32() as u128) << 96)
2942 | ((r2.into_u32() as u128) << 64)
2943 | ((r1.into_u32() as u128) << 32)
2944 | (r0.into_u32() as u128))
2945 }
2946
2947 fn schedule_write_to_register<R>(
2948 interface: &mut RiscvCommunicationInterface,
2949 value: Self,
2950 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2951 where
2952 R: LargeRegister,
2953 {
2954 let bits_3 = (value >> 96) as u32;
2955 let bits_2 = (value >> 64) as u32;
2956 let bits_1 = (value >> 32) as u32;
2957 let bits_0 = (value & 0xffff_ffff) as u32;
2958
2959 interface.schedule_write_dm_register_untyped(R::R3_ADDRESS as u64, bits_3)?;
2963 interface.schedule_write_dm_register_untyped(R::R2_ADDRESS as u64, bits_2)?;
2964 interface.schedule_write_dm_register_untyped(R::R1_ADDRESS as u64, bits_1)?;
2965 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, bits_0)
2966 }
2967}
2968
2969impl MemoryInterface for RiscvCommunicationInterface<'_> {
2970 fn supports_native_64bit_access(&mut self) -> bool {
2971 self.state.xlen_64
2972 }
2973
2974 fn read_word_64(&mut self, address: u64) -> Result<u64, crate::error::Error> {
2975 let mut ret = self.read_word::<u32>(address)? as u64;
2976 ret |= (self.read_word::<u32>(address + 4)? as u64) << 32;
2977
2978 Ok(ret)
2979 }
2980
2981 fn read_word_32(&mut self, address: u64) -> Result<u32, crate::Error> {
2982 tracing::debug!("read_word_32 from {:#08x}", address);
2983 self.read_word(address)
2984 }
2985
2986 fn read_word_16(&mut self, address: u64) -> Result<u16, crate::Error> {
2987 tracing::debug!("read_word_16 from {:#08x}", address);
2988 self.read_word(address)
2989 }
2990
2991 fn read_word_8(&mut self, address: u64) -> Result<u8, crate::Error> {
2992 tracing::debug!("read_word_8 from {:#08x}", address);
2993 self.read_word(address)
2994 }
2995
2996 fn read_64(&mut self, address: u64, data: &mut [u64]) -> Result<(), crate::error::Error> {
2997 tracing::debug!("read_64 from {:#08x}", address);
2998
2999 for (i, d) in data.iter_mut().enumerate() {
3000 *d = self.read_word_64(address + i as u64 * 8)?;
3001 }
3002
3003 Ok(())
3004 }
3005
3006 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), crate::Error> {
3007 tracing::debug!("read_32 from {:#08x}", address);
3008 self.read_multiple(address, data)
3009 }
3010
3011 fn read_16(&mut self, address: u64, data: &mut [u16]) -> Result<(), crate::Error> {
3012 tracing::debug!("read_16 from {:#08x}", address);
3013 self.read_multiple(address, data)
3014 }
3015
3016 fn read_8(&mut self, address: u64, data: &mut [u8]) -> Result<(), crate::Error> {
3017 tracing::debug!("read_8 from {:#08x}", address);
3018 self.read_multiple(address, data)
3019 }
3020
3021 fn write_word_64(&mut self, address: u64, data: u64) -> Result<(), crate::error::Error> {
3022 self.write_word(address, data as u32)?;
3023 self.write_word(address + 4, (data >> 32) as u32)
3024 }
3025
3026 fn write_word_32(&mut self, address: u64, data: u32) -> Result<(), crate::Error> {
3027 self.write_word(address, data)
3028 }
3029
3030 fn write_word_16(&mut self, address: u64, data: u16) -> Result<(), crate::Error> {
3031 self.write_word(address, data)
3032 }
3033
3034 fn write_word_8(&mut self, address: u64, data: u8) -> Result<(), crate::Error> {
3035 self.write_word(address, data)
3036 }
3037
3038 fn write_64(&mut self, address: u64, data: &[u64]) -> Result<(), crate::error::Error> {
3039 tracing::debug!("write_64 to {:#08x}", address);
3040
3041 for (i, d) in data.iter().enumerate() {
3042 self.write_word_64(address + i as u64 * 8, *d)?;
3043 }
3044
3045 Ok(())
3046 }
3047
3048 fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), crate::Error> {
3049 tracing::debug!("write_32 to {:#08x}", address);
3050 self.write_multiple(address, data)
3051 }
3052
3053 fn write_16(&mut self, address: u64, data: &[u16]) -> Result<(), crate::Error> {
3054 tracing::debug!("write_16 to {:#08x}", address);
3055 self.write_multiple(address, data)
3056 }
3057
3058 fn write_8(&mut self, address: u64, data: &[u8]) -> Result<(), crate::Error> {
3059 tracing::debug!("write_8 to {:#08x}", address);
3060 self.write_multiple(address, data)
3061 }
3062
3063 fn supports_8bit_transfers(&self) -> Result<bool, crate::Error> {
3064 Ok(true)
3065 }
3066
3067 fn flush(&mut self) -> Result<(), crate::Error> {
3068 Ok(())
3069 }
3070}
3071
3072#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, Eq, Debug)]
3076pub enum RiscvBusAccess {
3077 A8 = 0,
3079 A16 = 1,
3081 A32 = 2,
3083 A64 = 3,
3085 A128 = 4,
3087}
3088
3089impl RiscvBusAccess {
3090 const fn byte_width(&self) -> usize {
3092 match self {
3093 RiscvBusAccess::A8 => 1,
3094 RiscvBusAccess::A16 => 2,
3095 RiscvBusAccess::A32 => 4,
3096 RiscvBusAccess::A64 => 8,
3097 RiscvBusAccess::A128 => 16,
3098 }
3099 }
3100}
3101
3102impl From<RiscvBusAccess> for u8 {
3103 fn from(value: RiscvBusAccess) -> Self {
3104 value as u8
3105 }
3106}
3107
3108#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
3113pub enum MemoryAccessMethod {
3114 AbstractCommand,
3116 WaitingProgramBuffer,
3118 ProgramBuffer,
3120 SystemBus,
3122}
3123
3124memory_mapped_bitfield_register! {
3125 pub struct AccessRegisterCommand(u32);
3129 0x17, "command",
3130 impl From;
3131 pub _, set_cmd_type: 31, 24;
3133 pub u8, from into RiscvBusAccess, _, set_aarsize: 22, 20;
3143 pub _, set_aarpostincrement: 19;
3147 pub _, set_postexec: 18;
3153 pub _, set_transfer: 17;
3157 pub _, set_write: 16;
3161 pub _, set_regno: 15, 0;
3165}
3166
3167memory_mapped_bitfield_register! {
3168 pub struct Sbcs(u32);
3170 0x38, "sbcs",
3171 impl From;
3172 sbversion, _: 31, 29;
3178 sbbusyerror, set_sbbusyerror: 22;
3185 sbbusy, _: 21;
3194 sbreadonaddr, set_sbreadonaddr: 20;
3197 sbaccess, set_sbaccess: 19, 17;
3208 sbautoincrement, set_sbautoincrement: 16;
3211 sbreadondata, set_sbreadondata: 15;
3214 sberror, set_sberror: 14, 12;
3227 sbasize, _: 11, 5;
3229 sbaccess128, _: 4;
3231 sbaccess64, _: 3;
3233 sbaccess32, _: 2;
3235 sbaccess16, _: 1;
3237 sbaccess8, _: 0;
3239}
3240
3241memory_mapped_bitfield_register! {
3242 #[derive(Eq, PartialEq)]
3244 pub struct Abstractauto(u32);
3245 0x18, "abstractauto",
3246 impl From;
3247 autoexecprogbuf, set_autoexecprogbuf: 31, 16;
3250 autoexecdata, set_autoexecdata: 11, 0;
3253}
3254
3255memory_mapped_bitfield_register! {
3256 pub struct AccessMemoryCommand(u32);
3260 0x17, "command",
3261 _, set_cmd_type: 31, 24;
3263 pub _, set_aamvirtual: 23;
3272 pub _, set_aamsize: 22,20;
3278 pub _, set_aampostincrement: 19;
3282 pub _, set_write: 16;
3287 pub _, set_target_specific: 15, 14;
3289}
3290
3291impl From<AccessMemoryCommand> for u32 {
3292 fn from(register: AccessMemoryCommand) -> Self {
3293 let mut reg = register;
3294 reg.set_cmd_type(2);
3295 reg.0
3296 }
3297}
3298
3299impl From<u32> for AccessMemoryCommand {
3300 fn from(value: u32) -> Self {
3301 Self(value)
3302 }
3303}
3304
3305memory_mapped_bitfield_register! { pub struct Sbaddress0(u32); 0x39, "sbaddress0", impl From; }
3306memory_mapped_bitfield_register! { pub struct Sbaddress1(u32); 0x3a, "sbaddress1", impl From; }
3307memory_mapped_bitfield_register! { pub struct Sbaddress2(u32); 0x3b, "sbaddress2", impl From; }
3308memory_mapped_bitfield_register! { pub struct Sbaddress3(u32); 0x37, "sbaddress3", impl From; }
3309
3310memory_mapped_bitfield_register! { pub struct Sbdata0(u32); 0x3c, "sbdata0", impl From; }
3311memory_mapped_bitfield_register! { pub struct Sbdata1(u32); 0x3d, "sbdata1", impl From; }
3312memory_mapped_bitfield_register! { pub struct Sbdata2(u32); 0x3e, "sbdata2", impl From; }
3313memory_mapped_bitfield_register! { pub struct Sbdata3(u32); 0x3f, "sbdata3", impl From; }
3314
3315memory_mapped_bitfield_register! { pub struct Confstrptr0(u32); 0x19, "confstrptr0", impl From; }
3316memory_mapped_bitfield_register! { pub struct Confstrptr1(u32); 0x1a, "confstrptr1", impl From; }
3317memory_mapped_bitfield_register! { pub struct Confstrptr2(u32); 0x1b, "confstrptr2", impl From; }
3318memory_mapped_bitfield_register! { pub struct Confstrptr3(u32); 0x1c, "confstrptr3", impl From; }