1use crate::architecture::riscv::dtm::dtm_access::DtmAccess;
8use crate::{
9 Error as ProbeRsError, architecture::riscv::*, config::Target, memory_mapped_bitfield_register,
10 probe::DeferredResultIndex,
11};
12use std::any::Any;
13use std::collections::HashMap;
14use std::ops::Range;
15
16#[derive(thiserror::Error, Debug)]
18pub enum RiscvError {
19 #[error("Error during transport")]
21 DtmOperationFailed,
22 #[error("Transport operation in progress")]
24 DtmOperationInProcess,
25 #[error("Debug Probe Error")]
27 DebugProbe(#[from] DebugProbeError),
28 #[error("Timeout during DMI access.")]
30 Timeout,
31 #[error("Error occurred during execution of an abstract command: {0:?}")]
33 AbstractCommand(AbstractCommandErrorKind),
34 #[error("The core did not acknowledge a request for reset, resume or halt")]
36 RequestNotAcknowledged,
37 #[error("The version '{0}' of the debug transport module (DTM) is currently not supported.")]
39 UnsupportedDebugTransportModuleVersion(u8),
40 #[error("The version '{0:?}' of the debug module is currently not supported.")]
42 UnsupportedDebugModuleVersion(DebugModuleVersion),
43 #[error("CSR at address '{0:x}' is unsupported.")]
45 UnsupportedCsrAddress(u16),
46 #[error("Program buffer register '{0}' is currently not supported.")]
48 UnsupportedProgramBufferRegister(usize),
49 #[error(
51 "Program buffer is too small for supplied program. Required: {required}, Actual: {actual}"
52 )]
53 ProgramBufferTooSmall {
54 required: usize,
56 actual: usize,
58 },
59 #[error("Memory width larger than 32 bits is not supported yet.")]
61 UnsupportedBusAccessWidth(RiscvBusAccess),
62 #[error("Error using system bus")]
64 SystemBusAccess,
65 #[error("Unexpected trigger type {0} for address breakpoint.")]
67 UnexpectedTriggerType(u32),
68 #[error("Connected target is not a RISC-V device.")]
70 NoRiscvTarget,
71 #[error("The target does not support halt after reset.")]
73 ResetHaltRequestNotSupported,
74 #[error("The requested data is not available due to a previous error.")]
76 BatchedResultNotAvailable,
77 #[error("The requested hart is unavailable.")]
79 HartUnavailable,
80}
81
82impl From<RiscvError> for ProbeRsError {
83 fn from(err: RiscvError) -> Self {
84 match err {
85 RiscvError::DebugProbe(e) => e.into(),
86 other => ProbeRsError::Riscv(other),
87 }
88 }
89}
90
91#[derive(Debug)]
93pub enum AbstractCommandErrorKind {
94 Busy = 1,
100 NotSupported = 2,
102 Exception = 3,
104 HaltResume = 4,
108 Bus = 5,
111 _Reserved = 6,
113 Other = 7,
115}
116
117impl From<AbstractCommandErrorKind> for RiscvError {
118 fn from(err: AbstractCommandErrorKind) -> Self {
119 RiscvError::AbstractCommand(err)
120 }
121}
122
123impl AbstractCommandErrorKind {
124 fn parse(status: Abstractcs) -> Result<(), Self> {
125 let err = match status.cmderr() {
126 0 => return Ok(()),
127 1 => Self::Busy,
128 2 => Self::NotSupported,
129 3 => Self::Exception,
130 4 => Self::HaltResume,
131 5 => Self::Bus,
132 6 => Self::_Reserved,
133 7 => Self::Other,
134 _ => unreachable!("cmderr is a 3 bit value, values higher than 7 should not occur."),
135 };
136
137 Err(err)
138 }
139}
140
141#[derive(Debug, Copy, Clone, PartialEq, Eq)]
146pub enum DebugModuleVersion {
147 NoModule,
149 Version0_11,
151 Version0_13,
153 NonConforming,
155 Unknown(u8),
157}
158
159impl From<u8> for DebugModuleVersion {
160 fn from(raw: u8) -> Self {
161 match raw {
162 0 => Self::NoModule,
163 1 => Self::Version0_11,
164 2 => Self::Version0_13,
165 15 => Self::NonConforming,
166 other => Self::Unknown(other),
167 }
168 }
169}
170
171#[derive(Copy, Clone, Debug)]
172struct CoreRegisterAbstractCmdSupport(u8);
173
174impl CoreRegisterAbstractCmdSupport {
175 const READ: Self = Self(1 << 0);
176 const WRITE: Self = Self(1 << 1);
177 const BOTH: Self = Self(Self::READ.0 | Self::WRITE.0);
178
179 fn supports(&self, o: Self) -> bool {
180 self.0 & o.0 == o.0
181 }
182
183 fn unset(&mut self, o: Self) {
184 self.0 &= !(o.0);
185 }
186}
187
188#[derive(Debug, Default)]
191struct ScratchState {
192 stack: Vec<u32>,
193}
194
195impl ScratchState {
196 fn push(&mut self, value: u32) {
197 self.stack.push(value);
198 }
199
200 fn pop(&mut self) -> Option<u32> {
201 self.stack.pop()
202 }
203}
204
205#[derive(Default, Debug)]
207pub struct MemoryAccessConfig {
208 default_method: HashMap<RiscvBusAccess, MemoryAccessMethod>,
210
211 region_override: HashMap<(Range<u64>, RiscvBusAccess), MemoryAccessMethod>,
212}
213
214impl MemoryAccessConfig {
215 pub fn set_default_method(&mut self, access: RiscvBusAccess, method: MemoryAccessMethod) {
217 self.default_method.insert(access, method);
218 }
219
220 pub fn set_region_override(
222 &mut self,
223 access: RiscvBusAccess,
224 range: Range<u64>,
225 method: MemoryAccessMethod,
226 ) {
227 self.region_override.insert((range, access), method);
228 }
229
230 pub fn default_method(&self, access: RiscvBusAccess) -> MemoryAccessMethod {
232 self.default_method
233 .get(&access)
234 .copied()
235 .unwrap_or(MemoryAccessMethod::ProgramBuffer)
236 }
237
238 pub fn method(&self, address: u64, access: RiscvBusAccess) -> MemoryAccessMethod {
240 for ((range, method_access), method) in &self.region_override {
241 if range.contains(&address) && method_access == &access {
242 return *method;
243 }
244 }
245
246 self.default_method(access)
247 }
248
249 pub fn range_method(
251 &self,
252 address_range: Range<u64>,
253 access: RiscvBusAccess,
254 ) -> MemoryAccessMethod {
255 fn range_overlaps(range: &Range<u64>, address_range: &Range<u64>) -> bool {
256 range.start < address_range.end && address_range.start < range.end
257 }
258
259 let mut max = self.default_method(access);
260
261 for ((range, method_access), method) in &self.region_override {
262 if range_overlaps(range, &address_range) && method_access == &access {
263 max = std::cmp::min(*method, max);
264 }
265 }
266
267 max
268 }
269}
270
271#[derive(Debug)]
273pub struct RiscvCommunicationInterfaceState {
274 debug_version: DebugModuleVersion,
276
277 progbuf_size: u8,
279
280 progbuf_cache: [u32; 16],
282
283 implicit_ebreak: bool,
286
287 data_register_count: u8,
289
290 nscratch: u8,
292
293 supports_autoexec: bool,
295
296 confstrptr: Option<u128>,
298
299 hartsellen: u8,
301
302 num_harts: u32,
304
305 abstract_cmd_register_info: HashMap<RegisterId, CoreRegisterAbstractCmdSupport>,
308
309 s0: ScratchState,
311
312 s1: ScratchState,
314
315 enabled_harts: u32,
317
318 last_selected_hart: u32,
320
321 hasresethaltreq: Option<bool>,
323
324 is_halted: bool,
326
327 current_dmcontrol: Dmcontrol,
329
330 memory_access_config: MemoryAccessConfig,
331
332 sw_breakpoint_debug_enabled: bool,
333}
334
335const RISCV_TIMEOUT: Duration = Duration::from_secs(5);
337
338const RISCV_MAX_CSR_ADDR: u16 = 0xFFF;
341
342impl RiscvCommunicationInterfaceState {
343 pub fn new() -> Self {
345 RiscvCommunicationInterfaceState {
346 progbuf_size: 0,
348 progbuf_cache: [0u32; 16],
349
350 debug_version: DebugModuleVersion::NonConforming,
351
352 implicit_ebreak: false,
354
355 data_register_count: 1,
357
358 nscratch: 0,
359
360 supports_autoexec: false,
361
362 confstrptr: None,
363
364 hartsellen: 20,
366
367 num_harts: 1,
369
370 abstract_cmd_register_info: HashMap::new(),
371
372 s0: ScratchState::default(),
373 s1: ScratchState::default(),
374 enabled_harts: 0,
375 last_selected_hart: 0,
376 hasresethaltreq: None,
377 is_halted: false,
378
379 current_dmcontrol: Dmcontrol(0),
380
381 memory_access_config: MemoryAccessConfig::default(),
382
383 sw_breakpoint_debug_enabled: false,
384 }
385 }
386
387 fn memory_access_method(
390 &mut self,
391 access_width: RiscvBusAccess,
392 address: u64,
393 ) -> MemoryAccessMethod {
394 self.memory_access_config.method(address, access_width)
395 }
396
397 fn memory_range_access_method(
398 &self,
399 width: RiscvBusAccess,
400 address_range: Range<u64>,
401 ) -> MemoryAccessMethod {
402 self.memory_access_config.range_method(address_range, width)
403 }
404}
405
406impl Default for RiscvCommunicationInterfaceState {
407 fn default() -> Self {
408 Self::new()
409 }
410}
411
412pub struct RiscvDebugInterfaceState {
414 pub(super) interface_state: RiscvCommunicationInterfaceState,
415 pub(super) dtm_state: Box<dyn Any + Send>,
416}
417
418impl RiscvDebugInterfaceState {
419 pub(super) fn new(dtm_state: Box<dyn Any + Send>) -> Self {
420 Self {
421 interface_state: RiscvCommunicationInterfaceState::new(),
422 dtm_state,
423 }
424 }
425}
426
427pub trait RiscvInterfaceBuilder<'probe> {
429 fn create_state(&self) -> RiscvDebugInterfaceState;
434
435 fn attach<'state>(
438 self: Box<Self>,
439 state: &'state mut RiscvDebugInterfaceState,
440 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
441 where
442 'probe: 'state;
443
444 fn attach_tunneled<'state>(
447 self: Box<Self>,
448 _tunnel_ir_id: u32,
449 _tunnel_ir_width: u32,
450 _state: &'state mut RiscvDebugInterfaceState,
451 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
452 where
453 'probe: 'state,
454 {
455 Err(DebugProbeError::InterfaceNotAvailable {
456 interface_name: "Tunneled RISC-V",
457 })
458 }
459
460 fn attach_auto<'state>(
465 self: Box<Self>,
466 target: &Target,
467 state: &'state mut RiscvDebugInterfaceState,
468 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
469 where
470 'probe: 'state,
471 {
472 let maybe_tunnel = target.jtag.as_ref().and_then(|j| j.riscv_tunnel.as_ref());
473 if let Some(tunnel) = maybe_tunnel {
474 self.attach_tunneled(tunnel.ir_id, tunnel.ir_width, state)
475 } else {
476 self.attach(state)
477 }
478 }
479}
480
481#[derive(Debug)]
483pub struct RiscvCommunicationInterface<'state> {
484 dtm: Box<dyn DtmAccess + 'state>,
487 state: &'state mut RiscvCommunicationInterfaceState,
488}
489
490impl<'state> RiscvCommunicationInterface<'state> {
491 pub fn new(
493 dtm: Box<dyn DtmAccess + 'state>,
494 state: &'state mut RiscvCommunicationInterfaceState,
495 ) -> Self {
496 Self { dtm, state }
497 }
498
499 pub fn select_hart(&mut self, hart: u32) -> Result<(), RiscvError> {
501 if !self.hart_enabled(hart) {
502 return Err(RiscvError::HartUnavailable);
503 }
504
505 if self.state.last_selected_hart == hart {
506 return Ok(());
507 }
508
509 let mut control = self.read_dm_register::<Dmcontrol>()?;
511 control.set_dmactive(true);
512 control.set_hartsel(hart);
513 self.schedule_write_dm_register(control)?;
514 self.state.last_selected_hart = hart;
515 Ok(())
516 }
517
518 pub fn hart_enabled(&self, hart: u32) -> bool {
520 self.state.enabled_harts & (1 << hart) != 0
521 }
522
523 pub fn target_reset_assert(&mut self) -> Result<(), DebugProbeError> {
525 self.dtm.target_reset_assert()
526 }
527
528 pub fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError> {
530 self.dtm.target_reset_deassert()
531 }
532
533 pub fn read_idcode(&mut self) -> Result<Option<u32>, DebugProbeError> {
535 self.dtm.read_idcode()
536 }
537
538 fn save_s0(&mut self) -> Result<bool, RiscvError> {
539 let s0 = self.abstract_cmd_register_read(®isters::S0)?;
540
541 self.state.s0.push(s0);
542
543 Ok(true)
544 }
545
546 fn restore_s0(&mut self, saved: bool) -> Result<(), RiscvError> {
547 if saved {
548 let s0 = self.state.s0.pop().unwrap();
549
550 self.abstract_cmd_register_write(®isters::S0, s0)?;
551 }
552
553 Ok(())
554 }
555
556 fn save_s1(&mut self) -> Result<bool, RiscvError> {
557 let s1 = self.abstract_cmd_register_read(®isters::S1)?;
558
559 self.state.s1.push(s1);
560
561 Ok(true)
562 }
563
564 fn restore_s1(&mut self, saved: bool) -> Result<(), RiscvError> {
565 if saved {
566 let s1 = self.state.s1.pop().unwrap();
567
568 self.abstract_cmd_register_write(®isters::S1, s1)?;
569 }
570
571 Ok(())
572 }
573
574 pub fn enter_debug_mode(&mut self) -> Result<(), RiscvError> {
577 tracing::debug!("Building RISC-V interface");
578 self.dtm.init()?;
579
580 self.dtm.clear_error_state()?;
582
583 let mut control = Dmcontrol(0);
585 control.set_dmactive(true);
586 self.schedule_write_dm_register(control)?;
587
588 let status: Dmstatus = self.read_dm_register()?;
590
591 self.state.progbuf_cache.fill(0);
592 self.state.memory_access_config = MemoryAccessConfig::default();
593 self.state.debug_version = DebugModuleVersion::from(status.version() as u8);
594 self.state.is_halted = status.allhalted();
595
596 if self.state.debug_version != DebugModuleVersion::Version0_13 {
598 return Err(RiscvError::UnsupportedDebugModuleVersion(
599 self.state.debug_version,
600 ));
601 }
602
603 self.state.implicit_ebreak = status.impebreak();
604
605 self.state.confstrptr = if status.confstrptrvalid() {
607 let confstrptr_0: Confstrptr0 = self.read_dm_register()?;
608 let confstrptr_1: Confstrptr1 = self.read_dm_register()?;
609 let confstrptr_2: Confstrptr2 = self.read_dm_register()?;
610 let confstrptr_3: Confstrptr3 = self.read_dm_register()?;
611 let confstrptr = (u32::from(confstrptr_0) as u128)
612 | ((u32::from(confstrptr_1) as u128) << 8)
613 | ((u32::from(confstrptr_2) as u128) << 16)
614 | ((u32::from(confstrptr_3) as u128) << 32);
615 Some(confstrptr)
616 } else {
617 None
618 };
619
620 tracing::debug!("dmstatus: {:?}", status);
621
622 let mut control = Dmcontrol(0);
625 control.set_dmactive(true);
626 control.set_hartsel(0xffff_ffff);
627
628 self.schedule_write_dm_register(control)?;
629
630 let control = self.read_dm_register::<Dmcontrol>()?;
631
632 self.state.hartsellen = control.hartsel().count_ones() as u8;
633
634 tracing::debug!("HARTSELLEN: {}", self.state.hartsellen);
635
636 let max_hart_index = 2u32.pow(self.state.hartsellen as u32);
639
640 let mut num_harts = 1;
642 self.state.enabled_harts = 1;
643
644 let mut control = Dmcontrol(0);
649 control.set_dmactive(true);
650 control.set_hartsel(max_hart_index - 1);
651 self.schedule_write_dm_register(control)?;
652
653 let status: Dmstatus = self.read_dm_register()?;
655
656 if status.anynonexistent() {
657 for hart_index in 1..max_hart_index {
658 let mut control = Dmcontrol(0);
659 control.set_dmactive(true);
660 control.set_hartsel(hart_index);
661
662 self.schedule_write_dm_register(control)?;
663
664 let status: Dmstatus = self.read_dm_register()?;
666
667 if status.anynonexistent() {
668 break;
669 }
670
671 if !status.allunavail() {
672 self.state.enabled_harts |= 1 << num_harts;
673 }
674
675 num_harts += 1;
676 }
677 } else {
678 tracing::debug!("anynonexistent not supported, assuming only one hart exists")
679 }
680
681 tracing::debug!("Number of harts: {}", num_harts);
682
683 self.state.num_harts = num_harts;
684
685 let mut control = Dmcontrol(0);
687 control.set_dmactive(true);
688 control.set_hartsel(0);
689
690 self.schedule_write_dm_register(control)?;
691
692 let abstractcs: Abstractcs = self.read_dm_register()?;
695
696 self.state.progbuf_size = abstractcs.progbufsize() as u8;
697 tracing::debug!("Program buffer size: {}", self.state.progbuf_size);
698
699 self.state.data_register_count = abstractcs.datacount() as u8;
700 tracing::debug!(
701 "Number of data registers: {}",
702 self.state.data_register_count
703 );
704
705 let hartinfo: Hartinfo = self.read_dm_register()?;
707
708 self.state.nscratch = hartinfo.nscratch() as u8;
709 tracing::debug!("Number of dscratch registers: {}", self.state.nscratch);
710
711 let mut abstractauto = Abstractauto(0);
713 abstractauto.set_autoexecprogbuf(2u32.pow(self.state.progbuf_size as u32) - 1);
714 abstractauto.set_autoexecdata(2u32.pow(self.state.data_register_count as u32) - 1);
715
716 self.schedule_write_dm_register(abstractauto)?;
717
718 let abstractauto_readback: Abstractauto = self.read_dm_register()?;
719
720 self.state.supports_autoexec = abstractauto_readback == abstractauto;
721 tracing::debug!("Support for autoexec: {}", self.state.supports_autoexec);
722
723 abstractauto = Abstractauto(0);
725 self.schedule_write_dm_register(abstractauto)?;
726
727 let sbcs = self.read_dm_register::<Sbcs>()?;
729
730 if sbcs.sbversion() == 1 {
734 if sbcs.sbaccess8() {
737 self.state
738 .memory_access_config
739 .set_default_method(RiscvBusAccess::A8, MemoryAccessMethod::SystemBus);
740 }
741
742 if sbcs.sbaccess16() {
743 self.state
744 .memory_access_config
745 .set_default_method(RiscvBusAccess::A16, MemoryAccessMethod::SystemBus);
746 }
747
748 if sbcs.sbaccess32() {
749 self.state
750 .memory_access_config
751 .set_default_method(RiscvBusAccess::A32, MemoryAccessMethod::SystemBus);
752 }
753
754 if sbcs.sbaccess64() {
755 self.state
756 .memory_access_config
757 .set_default_method(RiscvBusAccess::A64, MemoryAccessMethod::SystemBus);
758 }
759
760 if sbcs.sbaccess128() {
761 self.state
762 .memory_access_config
763 .set_default_method(RiscvBusAccess::A128, MemoryAccessMethod::SystemBus);
764 }
765 } else {
766 tracing::debug!(
767 "System bus interface version {} is not supported.",
768 sbcs.sbversion()
769 );
770 }
771
772 Ok(())
773 }
774
775 pub fn disable_debug_module(&mut self) -> Result<(), RiscvError> {
777 self.debug_on_sw_breakpoint(false)?;
778
779 let mut control = Dmcontrol(0);
780 control.set_dmactive(false);
781 self.write_dm_register(control)?;
782
783 Ok(())
784 }
785
786 pub fn halt(&mut self, timeout: Duration) -> Result<(), RiscvError> {
788 let mut dmcontrol = self.state.current_dmcontrol;
791 tracing::debug!(
792 "Before requesting halt, the Dmcontrol register value was: {:?}",
793 dmcontrol
794 );
795
796 dmcontrol.set_dmactive(true);
797 dmcontrol.set_haltreq(true);
798
799 self.schedule_write_dm_register(dmcontrol)?;
800
801 let result_status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
802
803 dmcontrol.set_haltreq(false);
805 self.write_dm_register(dmcontrol)?;
806
807 let result_status = Dmstatus(self.dtm.read_deferred_result(result_status_idx)?.into_u32());
808
809 if result_status.allhalted() {
810 self.state.is_halted = true;
811 return Ok(());
813 }
814
815 dmcontrol.set_haltreq(true);
819 self.write_dm_register(dmcontrol)?;
820
821 self.wait_for_core_halted(timeout)?;
823
824 dmcontrol.set_haltreq(false);
826 self.write_dm_register(dmcontrol)?;
827
828 if !self.state.sw_breakpoint_debug_enabled {
829 self.debug_on_sw_breakpoint(true)?;
830 }
831
832 Ok(())
833 }
834
835 pub(crate) fn halt_with_previous(&mut self, timeout: Duration) -> Result<bool, RiscvError> {
837 let was_running = if self.state.is_halted {
838 false
840 } else {
841 let status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
844 self.halt(timeout)?;
845 let before_status = Dmstatus(self.dtm.read_deferred_result(status_idx)?.into_u32());
846
847 !before_status.allhalted()
848 };
849
850 Ok(was_running)
851 }
852
853 pub(crate) fn core_info(&mut self) -> Result<CoreInformation, RiscvError> {
854 let pc: u64 = self
855 .read_csr(super::registers::PC.id().0)
856 .map(|v| v.into())?;
857
858 Ok(CoreInformation { pc })
859 }
860
861 pub fn core_halted(&mut self) -> Result<bool, RiscvError> {
863 if !self.state.is_halted {
864 let dmstatus: Dmstatus = self.read_dm_register()?;
865
866 tracing::trace!("{:?}", dmstatus);
867
868 self.state.is_halted = dmstatus.allhalted();
869 }
870
871 Ok(self.state.is_halted)
872 }
873
874 pub(crate) fn wait_for_core_halted(&mut self, timeout: Duration) -> Result<(), RiscvError> {
875 let start = Instant::now();
877
878 while !self.core_halted()? {
879 if start.elapsed() >= timeout {
880 return Err(RiscvError::Timeout);
881 }
882 std::thread::sleep(Duration::from_millis(1));
884 }
885
886 Ok(())
887 }
888
889 pub(crate) fn halted_access<R>(
890 &mut self,
891 op: impl FnOnce(&mut Self) -> Result<R, RiscvError>,
892 ) -> Result<R, RiscvError> {
893 let was_running = self.halt_with_previous(Duration::from_millis(100))?;
894
895 let result = op(self);
896
897 if was_running {
898 self.resume_core()?;
899 }
900
901 result
902 }
903
904 pub(super) fn read_csr(&mut self, address: u16) -> Result<u32, RiscvError> {
905 tracing::debug!("Reading CSR {:#x}", address);
912
913 match self.abstract_cmd_register_read(address) {
916 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
917 tracing::debug!(
918 "Could not read core register {:#x} with abstract command, falling back to program buffer",
919 address
920 );
921 self.read_csr_progbuf(address)
922 }
923 other => other,
924 }
925 }
926
927 pub fn read_dm_register<R: MemoryMappedRegister<u32>>(&mut self) -> Result<R, RiscvError> {
929 tracing::debug!(
930 "Reading DM register '{}' at {:#010x}",
931 R::NAME,
932 R::get_mmio_address()
933 );
934
935 let register_value = self.read_dm_register_untyped(R::get_mmio_address())?.into();
936
937 tracing::debug!(
938 "Read DM register '{}' at {:#010x} = {:x?}",
939 R::NAME,
940 R::get_mmio_address(),
941 register_value
942 );
943
944 Ok(register_value)
945 }
946
947 fn read_dm_register_untyped(&mut self, address: u64) -> Result<u32, RiscvError> {
951 let read_idx = self.schedule_read_dm_register_untyped(address)?;
952 let register_value = self.dtm.read_deferred_result(read_idx)?.into_u32();
953
954 Ok(register_value)
955 }
956
957 pub fn write_dm_register<R: MemoryMappedRegister<u32>>(
959 &mut self,
960 register: R,
961 ) -> Result<(), RiscvError> {
962 tracing::debug!(
965 "Write DM register '{}' at {:#010x} = {:x?}",
966 R::NAME,
967 R::get_mmio_address(),
968 register
969 );
970
971 self.write_dm_register_untyped(R::get_mmio_address(), register.into())
972 }
973
974 fn write_dm_register_untyped(&mut self, address: u64, value: u32) -> Result<(), RiscvError> {
978 self.cache_write(address, value);
979 self.dtm.write_with_timeout(address, value, RISCV_TIMEOUT)?;
980
981 Ok(())
982 }
983
984 fn cache_write(&mut self, address: u64, value: u32) {
985 if address == Dmcontrol::ADDRESS_OFFSET {
986 self.state.current_dmcontrol = Dmcontrol(value);
987 }
988 }
989
990 fn schedule_write_progbuf(&mut self, index: usize, value: u32) -> Result<(), RiscvError> {
991 match index {
992 0 => self.schedule_write_dm_register(Progbuf0(value)),
993 1 => self.schedule_write_dm_register(Progbuf1(value)),
994 2 => self.schedule_write_dm_register(Progbuf2(value)),
995 3 => self.schedule_write_dm_register(Progbuf3(value)),
996 4 => self.schedule_write_dm_register(Progbuf4(value)),
997 5 => self.schedule_write_dm_register(Progbuf5(value)),
998 6 => self.schedule_write_dm_register(Progbuf6(value)),
999 7 => self.schedule_write_dm_register(Progbuf7(value)),
1000 8 => self.schedule_write_dm_register(Progbuf8(value)),
1001 9 => self.schedule_write_dm_register(Progbuf9(value)),
1002 10 => self.schedule_write_dm_register(Progbuf10(value)),
1003 11 => self.schedule_write_dm_register(Progbuf11(value)),
1004 12 => self.schedule_write_dm_register(Progbuf12(value)),
1005 13 => self.schedule_write_dm_register(Progbuf13(value)),
1006 14 => self.schedule_write_dm_register(Progbuf14(value)),
1007 15 => self.schedule_write_dm_register(Progbuf15(value)),
1008 e => Err(RiscvError::UnsupportedProgramBufferRegister(e)),
1009 }
1010 }
1011
1012 pub(crate) fn schedule_setup_program_buffer(&mut self, data: &[u32]) -> Result<(), RiscvError> {
1013 let required_len = if self.state.implicit_ebreak {
1014 data.len()
1015 } else {
1016 data.len() + 1
1017 };
1018
1019 if required_len > self.state.progbuf_size as usize {
1020 return Err(RiscvError::ProgramBufferTooSmall {
1021 required: required_len,
1022 actual: self.state.progbuf_size as usize,
1023 });
1024 }
1025
1026 if data == &self.state.progbuf_cache[..data.len()] {
1027 tracing::debug!("Program buffer is up-to-date, skipping write.");
1029 return Ok(());
1030 }
1031
1032 for (index, word) in data.iter().enumerate() {
1033 self.schedule_write_progbuf(index, *word)?;
1034 }
1035
1036 if !self.state.implicit_ebreak || data.len() < self.state.progbuf_size as usize {
1041 self.schedule_write_progbuf(data.len(), assembly::EBREAK)?;
1042 }
1043
1044 self.state.progbuf_cache[..data.len()].copy_from_slice(data);
1046
1047 Ok(())
1048 }
1049
1050 fn perform_memory_read_sysbus<V: RiscvValue32>(
1052 &mut self,
1053 address: u32,
1054 ) -> Result<V, RiscvError> {
1055 let mut sbcs = Sbcs(0);
1056
1057 sbcs.set_sbaccess(V::WIDTH as u32);
1058 sbcs.set_sbreadonaddr(true);
1059
1060 self.schedule_write_dm_register(sbcs)?;
1061 self.schedule_write_dm_register(Sbaddress0(address))?;
1062
1063 let mut results = vec![];
1064 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut results)?;
1065
1066 let sbcs = self.read_dm_register::<Sbcs>()?;
1068
1069 if sbcs.sberror() != 0 {
1070 Err(RiscvError::SystemBusAccess)
1071 } else {
1072 V::read_scheduled_result(self, &mut results)
1073 }
1074 }
1075
1076 fn perform_memory_read_multiple_sysbus<V: RiscvValue32>(
1080 &mut self,
1081 address: u32,
1082 data: &mut [V],
1083 ) -> Result<(), RiscvError> {
1084 if data.is_empty() {
1085 return Ok(());
1086 }
1087
1088 let mut sbcs = Sbcs(0);
1089
1090 sbcs.set_sbaccess(V::WIDTH as u32);
1091
1092 sbcs.set_sbreadonaddr(true);
1093
1094 sbcs.set_sbreadondata(true);
1095 sbcs.set_sbautoincrement(true);
1096
1097 self.schedule_write_dm_register(sbcs)?;
1098
1099 self.schedule_write_dm_register(Sbaddress0(address))?;
1100
1101 let data_len = data.len();
1102
1103 let mut read_results = Vec::with_capacity(data_len);
1104 for _ in data[..data_len - 1].iter() {
1105 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut read_results)?;
1106 }
1107
1108 self.schedule_write_dm_register(Sbcs(0))?;
1109
1110 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut read_results)?;
1112
1113 let sbcs = self.read_dm_register::<Sbcs>()?;
1114
1115 for out in data.iter_mut() {
1116 *out = V::read_scheduled_result(self, &mut read_results)?;
1117 }
1118
1119 if sbcs.sberror() != 0 {
1121 Err(RiscvError::SystemBusAccess)
1122 } else {
1123 Ok(())
1124 }
1125 }
1126
1127 fn wait_for_idle(&mut self, timeout: Duration) -> Result<(), RiscvError> {
1129 let start = Instant::now();
1130 loop {
1131 let status: Abstractcs = self.read_dm_register()?;
1132 match AbstractCommandErrorKind::parse(status) {
1133 Ok(_) => return Ok(()),
1134 Err(AbstractCommandErrorKind::Busy) => {}
1135 Err(other) => return Err(other.into()),
1136 }
1137
1138 if start.elapsed() > timeout {
1139 return Err(RiscvError::Timeout);
1140 }
1141 }
1142 }
1143
1144 fn perform_memory_read_progbuf<V: RiscvValue32>(
1147 &mut self,
1148 address: u32,
1149 wait_for_idle: bool,
1150 ) -> Result<V, RiscvError> {
1151 self.halted_access(|core| {
1152 let s0 = core.save_s0()?;
1156
1157 let lw_command = assembly::lw(0, 8, V::WIDTH as u8, 8);
1158
1159 core.schedule_setup_program_buffer(&[lw_command])?;
1160
1161 core.schedule_write_dm_register(Data0(address))?;
1162
1163 let mut command = AccessRegisterCommand(0);
1165 command.set_cmd_type(0);
1166 command.set_transfer(true);
1167 command.set_write(true);
1168
1169 command.set_aarsize(RiscvBusAccess::A32);
1171 command.set_postexec(true);
1172
1173 command.set_regno((registers::S0).id.0 as u32);
1175
1176 core.schedule_write_dm_register(command)?;
1177
1178 if wait_for_idle {
1179 core.wait_for_idle(Duration::from_millis(10))?;
1180 }
1181
1182 let value = core.abstract_cmd_register_read(®isters::S0)?;
1184
1185 core.restore_s0(s0)?;
1187
1188 Ok(V::from_register_value(value))
1189 })
1190 }
1191
1192 fn perform_memory_read_multiple_progbuf<V: RiscvValue32>(
1193 &mut self,
1194 address: u32,
1195 data: &mut [V],
1196 wait_for_idle: bool,
1197 ) -> Result<(), RiscvError> {
1198 if data.is_empty() {
1199 return Ok(());
1200 }
1201
1202 if data.len() == 1 {
1203 data[0] = self.perform_memory_read_progbuf(address, wait_for_idle)?;
1204 return Ok(());
1205 }
1206
1207 self.halted_access(|core| {
1208 let s0 = core.save_s0()?;
1210 let s1 = core.save_s1()?;
1211
1212 let lw_command: u32 = assembly::lw(0, 8, V::WIDTH as u8, 9);
1214
1215 core.schedule_setup_program_buffer(&[
1216 lw_command,
1217 assembly::addi(8, 8, V::WIDTH.byte_width() as i16),
1218 ])?;
1219
1220 core.schedule_write_dm_register(Data0(address))?;
1221
1222 let mut command = AccessRegisterCommand(0);
1224 command.set_cmd_type(0);
1225 command.set_transfer(true);
1226 command.set_write(true);
1227
1228 command.set_aarsize(RiscvBusAccess::A32);
1230 command.set_postexec(true);
1231
1232 command.set_regno((registers::S0).id.0 as u32);
1234
1235 core.schedule_write_dm_register(command)?;
1236
1237 if wait_for_idle {
1238 core.wait_for_idle(Duration::from_millis(10))?;
1239 }
1240
1241 let data_len = data.len();
1242
1243 let mut result_idxs = Vec::with_capacity(data_len - 1);
1244 for out_idx in 0..data_len - 1 {
1245 let mut command = AccessRegisterCommand(0);
1246 command.set_cmd_type(0);
1247 command.set_transfer(true);
1248 command.set_write(false);
1249
1250 command.set_aarsize(RiscvBusAccess::A32);
1252 command.set_postexec(true);
1253
1254 command.set_regno((registers::S1).id.0 as u32);
1255
1256 core.schedule_write_dm_register(command)?;
1257
1258 let value_idx = core.schedule_read_dm_register::<Data0>()?;
1260
1261 result_idxs.push((out_idx, value_idx));
1262
1263 if wait_for_idle {
1264 core.wait_for_idle(Duration::from_millis(10))?;
1265 }
1266 }
1267
1268 let last_value = core.abstract_cmd_register_read(®isters::S1)?;
1270 data[data.len() - 1] = V::from_register_value(last_value);
1271
1272 for (out_idx, value_idx) in result_idxs {
1273 let value = core.dtm.read_deferred_result(value_idx)?.into_u32();
1274
1275 data[out_idx] = V::from_register_value(value);
1276 }
1277
1278 let status: Abstractcs = core.read_dm_register()?;
1279 AbstractCommandErrorKind::parse(status)?;
1280
1281 core.restore_s0(s0)?;
1282 core.restore_s1(s1)?;
1283
1284 Ok(())
1285 })
1286 }
1287
1288 fn perform_memory_write_sysbus<V: RiscvValue>(
1290 &mut self,
1291 address: u32,
1292 data: &[V],
1293 ) -> Result<(), RiscvError> {
1294 if data.is_empty() {
1295 return Ok(());
1296 }
1297 let mut sbcs = Sbcs(0);
1298
1299 sbcs.set_sbaccess(V::WIDTH as u32);
1301 sbcs.set_sbautoincrement(true);
1302
1303 self.schedule_write_dm_register(sbcs)?;
1304
1305 self.schedule_write_dm_register(Sbaddress0(address))?;
1306
1307 for value in data {
1308 self.schedule_write_large_dtm_register::<V, Sbdata>(*value)?;
1309 }
1310
1311 let sbcs = self.read_dm_register::<Sbcs>()?;
1313
1314 if sbcs.sberror() != 0 {
1315 Err(RiscvError::SystemBusAccess)
1316 } else {
1317 Ok(())
1318 }
1319 }
1320
1321 fn perform_memory_write_progbuf<V: RiscvValue32>(
1324 &mut self,
1325 address: u32,
1326 data: V,
1327 wait_for_idle: bool,
1328 ) -> Result<(), RiscvError> {
1329 self.halted_access(|core| {
1330 tracing::debug!(
1331 "Memory write using progbuf - {:#010x} = {:#?}",
1332 address,
1333 data
1334 );
1335
1336 let s0 = core.save_s0()?;
1338 let s1 = core.save_s1()?;
1339
1340 let sw_command = assembly::sw(0, 8, V::WIDTH as u32, 9);
1341
1342 core.schedule_setup_program_buffer(&[sw_command])?;
1343
1344 core.abstract_cmd_register_write(®isters::S0, address)?;
1346
1347 core.schedule_write_dm_register(Data0(data.into()))?;
1349
1350 let mut command = AccessRegisterCommand(0);
1352 command.set_cmd_type(0);
1353 command.set_transfer(true);
1354 command.set_write(true);
1355
1356 command.set_aarsize(RiscvBusAccess::A32);
1358 command.set_postexec(true);
1359
1360 command.set_regno((registers::S1).id.0 as u32);
1362
1363 core.schedule_write_dm_register(command)?;
1364
1365 if wait_for_idle && let Err(error) = core.wait_for_idle(Duration::from_millis(10)) {
1366 tracing::error!(
1367 "Executing the abstract command for write_{} failed: {:?}",
1368 V::WIDTH.byte_width() * 8,
1369 error
1370 );
1371
1372 return Err(error);
1373 }
1374
1375 core.restore_s0(s0)?;
1376 core.restore_s1(s1)?;
1377
1378 Ok(())
1379 })
1380 }
1381
1382 fn perform_memory_write_multiple_progbuf<V: RiscvValue32>(
1385 &mut self,
1386 address: u32,
1387 data: &[V],
1388 wait_for_idle: bool,
1389 ) -> Result<(), RiscvError> {
1390 if data.is_empty() {
1391 return Ok(());
1392 }
1393
1394 if data.len() == 1 {
1395 self.perform_memory_write_progbuf(address, data[0], wait_for_idle)?;
1396 return Ok(());
1397 }
1398
1399 self.halted_access(|core| {
1400 let s0 = core.save_s0()?;
1401 let s1 = core.save_s1()?;
1402
1403 core.schedule_setup_program_buffer(&[
1407 assembly::sw(0, 8, V::WIDTH as u32, 9),
1408 assembly::addi(8, 8, V::WIDTH.byte_width() as i16),
1409 ])?;
1410
1411 core.abstract_cmd_register_write(®isters::S0, address)?;
1413
1414 for value in data {
1415 core.schedule_write_dm_register(Data0((*value).into()))?;
1417
1418 let mut command = AccessRegisterCommand(0);
1420 command.set_cmd_type(0);
1421 command.set_transfer(true);
1422 command.set_write(true);
1423
1424 command.set_aarsize(RiscvBusAccess::A32);
1426 command.set_postexec(true);
1427
1428 command.set_regno((registers::S1).id.0 as u32);
1430
1431 core.schedule_write_dm_register(command)?;
1432
1433 if wait_for_idle && let Err(error) = core.wait_for_idle(Duration::from_millis(10)) {
1434 tracing::error!(
1435 "Executing the abstract command for write_multiple_{} failed: {:?}",
1436 V::WIDTH.byte_width() * 8,
1437 error,
1438 );
1439
1440 return Err(error);
1441 }
1442 }
1443
1444 core.restore_s0(s0)?;
1447 core.restore_s1(s1)?;
1448
1449 Ok(())
1450 })
1451 }
1452
1453 pub(crate) fn execute_abstract_command(&mut self, command: u32) -> Result<(), RiscvError> {
1454 let mut dmcontrol = self.state.current_dmcontrol;
1460 dmcontrol.set_dmactive(true);
1461 dmcontrol.set_haltreq(false);
1462 dmcontrol.set_resumereq(false);
1463 dmcontrol.set_ackhavereset(false);
1464 self.schedule_write_dm_register(dmcontrol)?;
1465
1466 fn do_execute_abstract_command(
1467 core: &mut RiscvCommunicationInterface,
1468 command: Command,
1469 ) -> Result<(), RiscvError> {
1470 let mut abstractcs_clear = Abstractcs(0);
1472 abstractcs_clear.set_cmderr(0x7);
1473
1474 core.schedule_write_dm_register(abstractcs_clear)?;
1475 core.schedule_write_dm_register(command)?;
1476
1477 let start_time = Instant::now();
1478
1479 let mut abstractcs;
1481 loop {
1482 abstractcs = core.read_dm_register::<Abstractcs>()?;
1483
1484 if !abstractcs.busy() {
1485 break;
1486 }
1487
1488 if start_time.elapsed() > RISCV_TIMEOUT {
1489 return Err(RiscvError::Timeout);
1490 }
1491 }
1492
1493 tracing::debug!("abstracts: {:?}", abstractcs);
1494
1495 AbstractCommandErrorKind::parse(abstractcs)?;
1497
1498 Ok(())
1499 }
1500
1501 match do_execute_abstract_command(self, Command(command)) {
1502 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::HaltResume)) => {
1503 if !self.core_halted()? {
1504 self.halted_access(|core| do_execute_abstract_command(core, Command(command)))
1507 } else {
1508 err
1511 }
1512 }
1513 other => other,
1514 }
1515 }
1516
1517 fn check_abstract_cmd_register_support(
1519 &self,
1520 regno: RegisterId,
1521 rw: CoreRegisterAbstractCmdSupport,
1522 ) -> bool {
1523 if let Some(status) = self.state.abstract_cmd_register_info.get(®no) {
1524 status.supports(rw)
1525 } else {
1526 true
1528 }
1529 }
1530
1531 fn set_abstract_cmd_register_unsupported(
1533 &mut self,
1534 regno: RegisterId,
1535 rw: CoreRegisterAbstractCmdSupport,
1536 ) {
1537 let entry = self
1538 .state
1539 .abstract_cmd_register_info
1540 .entry(regno)
1541 .or_insert(CoreRegisterAbstractCmdSupport::BOTH);
1542
1543 entry.unset(rw);
1544 }
1545
1546 pub(crate) fn abstract_cmd_register_read(
1548 &mut self,
1549 regno: impl Into<RegisterId>,
1550 ) -> Result<u32, RiscvError> {
1551 let regno = regno.into();
1552
1553 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::READ) {
1555 return Err(RiscvError::AbstractCommand(
1556 AbstractCommandErrorKind::NotSupported,
1557 ));
1558 }
1559
1560 let mut command = AccessRegisterCommand(0);
1562 command.set_cmd_type(0);
1563 command.set_transfer(true);
1564 command.set_aarsize(RiscvBusAccess::A32);
1565
1566 command.set_regno(regno.0 as u32);
1567
1568 match self.execute_abstract_command(command.0) {
1569 Ok(_) => (),
1570 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1571 self.set_abstract_cmd_register_unsupported(
1573 regno,
1574 CoreRegisterAbstractCmdSupport::READ,
1575 );
1576 err?;
1577 }
1578 Err(e) => return Err(e),
1579 }
1580
1581 let register_value: Data0 = self.read_dm_register()?;
1582
1583 Ok(register_value.into())
1584 }
1585
1586 pub(crate) fn abstract_cmd_register_write<V: RiscvValue>(
1587 &mut self,
1588 regno: impl Into<RegisterId>,
1589 value: V,
1590 ) -> Result<(), RiscvError> {
1591 let regno = regno.into();
1592
1593 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::WRITE) {
1595 return Err(RiscvError::AbstractCommand(
1596 AbstractCommandErrorKind::NotSupported,
1597 ));
1598 }
1599
1600 let mut command = AccessRegisterCommand(0);
1602 command.set_cmd_type(0);
1603 command.set_transfer(true);
1604 command.set_write(true);
1605 command.set_aarsize(V::WIDTH);
1606
1607 command.set_regno(regno.0 as u32);
1608
1609 self.schedule_write_large_dtm_register::<V, Arg0>(value)?;
1610
1611 match self.execute_abstract_command(command.0) {
1612 Ok(_) => Ok(()),
1613 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1614 self.set_abstract_cmd_register_unsupported(
1616 regno,
1617 CoreRegisterAbstractCmdSupport::WRITE,
1618 );
1619 err
1620 }
1621 Err(e) => Err(e),
1622 }
1623 }
1624
1625 pub fn read_csr_progbuf(&mut self, address: u16) -> Result<u32, RiscvError> {
1627 self.halted_access(|core| {
1628 tracing::debug!("Reading CSR {:#04x}", address);
1629
1630 if address > RISCV_MAX_CSR_ADDR {
1632 return Err(RiscvError::UnsupportedCsrAddress(address));
1633 }
1634
1635 let s0 = core.save_s0()?;
1636
1637 let csrr_cmd = assembly::csrr(8, address);
1639
1640 core.schedule_setup_program_buffer(&[csrr_cmd])?;
1641
1642 let mut postexec_cmd = AccessRegisterCommand(0);
1644 postexec_cmd.set_postexec(true);
1645
1646 core.execute_abstract_command(postexec_cmd.0)?;
1647
1648 let reg_value = core.abstract_cmd_register_read(®isters::S0)?;
1650
1651 core.restore_s0(s0)?;
1653
1654 Ok(reg_value)
1655 })
1656 }
1657
1658 pub fn write_csr_progbuf(&mut self, address: u16, value: u32) -> Result<(), RiscvError> {
1660 self.halted_access(|core| {
1661 tracing::debug!("Writing CSR {:#04x}={}", address, value);
1662
1663 if address > RISCV_MAX_CSR_ADDR {
1665 return Err(RiscvError::UnsupportedCsrAddress(address));
1666 }
1667
1668 let s0 = core.save_s0()?;
1670
1671 core.abstract_cmd_register_write(®isters::S0, value)?;
1673
1674 let csrw_cmd = assembly::csrw(address, 8);
1676 core.schedule_setup_program_buffer(&[csrw_cmd])?;
1677
1678 let mut postexec_cmd = AccessRegisterCommand(0);
1680 postexec_cmd.set_postexec(true);
1681
1682 core.execute_abstract_command(postexec_cmd.0)?;
1683
1684 core.restore_s0(s0)?;
1687
1688 Ok(())
1689 })
1690 }
1691
1692 fn read_word<V: RiscvValue32>(&mut self, address: u32) -> Result<V, crate::Error> {
1693 let result = match self.state.memory_access_method(V::WIDTH, address as u64) {
1694 MemoryAccessMethod::ProgramBuffer => {
1695 self.perform_memory_read_progbuf(address, false)?
1696 }
1697 MemoryAccessMethod::WaitingProgramBuffer => {
1698 self.perform_memory_read_progbuf(address, true)?
1699 }
1700 MemoryAccessMethod::SystemBus => self.perform_memory_read_sysbus(address)?,
1701 MemoryAccessMethod::AbstractCommand => {
1702 unimplemented!("Memory access using abstract commands is not implemted")
1703 }
1704 };
1705
1706 Ok(result)
1707 }
1708
1709 fn read_multiple<V: RiscvValue32>(
1710 &mut self,
1711 address: u32,
1712 data: &mut [V],
1713 ) -> Result<(), crate::Error> {
1714 let start = address as u64;
1715 let address_range = start..(start + (data.len() * V::WIDTH.byte_width()) as u64);
1716 let access_method = self
1717 .state
1718 .memory_range_access_method(V::WIDTH, address_range);
1719 tracing::debug!(
1720 "read_multiple({:?}) from {:#08x} using {:?}",
1721 V::WIDTH,
1722 address,
1723 access_method
1724 );
1725
1726 match access_method {
1727 MemoryAccessMethod::ProgramBuffer => {
1728 self.perform_memory_read_multiple_progbuf(address, data, false)?;
1729 }
1730 MemoryAccessMethod::WaitingProgramBuffer => {
1731 self.perform_memory_read_multiple_progbuf(address, data, true)?;
1732 }
1733 MemoryAccessMethod::SystemBus => {
1734 self.perform_memory_read_multiple_sysbus(address, data)?;
1735 }
1736 MemoryAccessMethod::AbstractCommand => {
1737 unimplemented!("Memory access using abstract commands is not implemted")
1738 }
1739 };
1740
1741 Ok(())
1742 }
1743
1744 fn write_word<V: RiscvValue32>(&mut self, address: u32, data: V) -> Result<(), crate::Error> {
1745 match self.state.memory_access_method(V::WIDTH, address as u64) {
1746 MemoryAccessMethod::ProgramBuffer => {
1747 self.perform_memory_write_progbuf(address, data, false)?
1748 }
1749 MemoryAccessMethod::WaitingProgramBuffer => {
1750 self.perform_memory_write_progbuf(address, data, true)?
1751 }
1752 MemoryAccessMethod::SystemBus => self.perform_memory_write_sysbus(address, &[data])?,
1753 MemoryAccessMethod::AbstractCommand => {
1754 unimplemented!("Memory access using abstract commands is not implemted")
1755 }
1756 };
1757
1758 Ok(())
1759 }
1760
1761 fn write_multiple<V: RiscvValue32>(
1762 &mut self,
1763 address: u32,
1764 data: &[V],
1765 ) -> Result<(), crate::Error> {
1766 let start = address as u64;
1767 let address_range = start..(start + (data.len() * V::WIDTH.byte_width()) as u64);
1768 let access_method = self
1769 .state
1770 .memory_range_access_method(V::WIDTH, address_range);
1771 match access_method {
1772 MemoryAccessMethod::SystemBus => self.perform_memory_write_sysbus(address, data)?,
1773 MemoryAccessMethod::ProgramBuffer => {
1774 self.perform_memory_write_multiple_progbuf(address, data, false)?
1775 }
1776 MemoryAccessMethod::WaitingProgramBuffer => {
1777 self.perform_memory_write_multiple_progbuf(address, data, true)?
1778 }
1779 MemoryAccessMethod::AbstractCommand => {
1780 unimplemented!("Memory access using abstract commands is not implemted")
1781 }
1782 }
1783
1784 Ok(())
1785 }
1786
1787 pub(crate) fn schedule_write_dm_register<R: MemoryMappedRegister<u32>>(
1788 &mut self,
1789 register: R,
1790 ) -> Result<(), RiscvError> {
1791 tracing::debug!(
1794 "Write DM register '{}' at {:#010x} = {:x?}",
1795 R::NAME,
1796 R::get_mmio_address(),
1797 register
1798 );
1799
1800 self.schedule_write_dm_register_untyped(R::get_mmio_address(), register.into())?;
1801 Ok(())
1802 }
1803
1804 fn schedule_write_dm_register_untyped(
1808 &mut self,
1809 address: u64,
1810 value: u32,
1811 ) -> Result<Option<DeferredResultIndex>, RiscvError> {
1812 self.cache_write(address, value);
1813 self.dtm.schedule_write(address, value)
1814 }
1815
1816 pub(super) fn schedule_read_dm_register<R: MemoryMappedRegister<u32>>(
1817 &mut self,
1818 ) -> Result<DeferredResultIndex, RiscvError> {
1819 tracing::debug!(
1820 "Reading DM register '{}' at {:#010x}",
1821 R::NAME,
1822 R::get_mmio_address()
1823 );
1824
1825 self.schedule_read_dm_register_untyped(R::get_mmio_address())
1826 }
1827
1828 fn schedule_read_dm_register_untyped(
1832 &mut self,
1833 address: u64,
1834 ) -> Result<DeferredResultIndex, RiscvError> {
1835 self.dtm.schedule_read(address)
1837 }
1838
1839 fn schedule_read_large_dtm_register<V, R>(
1840 &mut self,
1841 results: &mut Vec<DeferredResultIndex>,
1842 ) -> Result<(), RiscvError>
1843 where
1844 V: RiscvValue,
1845 R: LargeRegister,
1846 {
1847 V::schedule_read_from_register::<R>(self, results)
1848 }
1849
1850 fn schedule_write_large_dtm_register<V, R>(
1851 &mut self,
1852 value: V,
1853 ) -> Result<Option<DeferredResultIndex>, RiscvError>
1854 where
1855 V: RiscvValue,
1856 R: LargeRegister,
1857 {
1858 V::schedule_write_to_register::<R>(self, value)
1859 }
1860
1861 pub(crate) fn supports_reset_halt_req(&mut self) -> Result<bool, RiscvError> {
1866 if let Some(has_reset_halt_req) = self.state.hasresethaltreq {
1867 Ok(has_reset_halt_req)
1868 } else {
1869 let dmstatus: Dmstatus = self.read_dm_register()?;
1870
1871 self.state.hasresethaltreq = Some(dmstatus.hasresethaltreq());
1872
1873 Ok(dmstatus.hasresethaltreq())
1874 }
1875 }
1876
1877 pub fn resume_core(&mut self) -> Result<(), RiscvError> {
1879 self.state.is_halted = false; let mut dmcontrol = self.state.current_dmcontrol;
1883 dmcontrol.set_dmactive(true);
1884 dmcontrol.set_resumereq(true);
1885 self.schedule_write_dm_register(dmcontrol)?;
1886
1887 let status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
1889
1890 dmcontrol.set_resumereq(false);
1892 self.write_dm_register(dmcontrol)?;
1893
1894 let status = Dmstatus(self.dtm.read_deferred_result(status_idx)?.into_u32());
1895 if !status.allresumeack() {
1896 return Err(RiscvError::RequestNotAcknowledged);
1897 }
1898
1899 Ok(())
1900 }
1901
1902 pub fn reset_hart_and_halt(&mut self, timeout: Duration) -> Result<(), RiscvError> {
1904 tracing::debug!("Resetting core, setting hartreset bit");
1905
1906 let mut dmcontrol = self.state.current_dmcontrol;
1907 dmcontrol.set_dmactive(true);
1908 dmcontrol.set_hartreset(true);
1909 dmcontrol.set_haltreq(true);
1910
1911 self.write_dm_register(dmcontrol)?;
1912
1913 let readback: Dmcontrol = self.read_dm_register()?;
1915
1916 if readback.hartreset() {
1917 tracing::debug!("Clearing hartreset bit");
1918 let mut dmcontrol = readback;
1920 dmcontrol.set_dmactive(true);
1921 dmcontrol.set_haltreq(true);
1922 dmcontrol.set_hartreset(false);
1923
1924 self.write_dm_register(dmcontrol)?;
1925 } else {
1926 tracing::debug!("Hartreset bit not supported, using ndmreset");
1930 dmcontrol.set_hartreset(false);
1931 dmcontrol.set_ndmreset(true);
1932 dmcontrol.set_haltreq(true);
1933
1934 self.write_dm_register(dmcontrol)?;
1935
1936 tracing::debug!("Clearing ndmreset bit");
1937 dmcontrol.set_ndmreset(false);
1938 dmcontrol.set_haltreq(true);
1939
1940 self.write_dm_register(dmcontrol)?;
1941 }
1942
1943 let start = Instant::now();
1944
1945 loop {
1946 let readback: Dmstatus = self.read_dm_register()?;
1948
1949 if readback.allhavereset() && readback.allhalted() {
1950 break;
1951 }
1952
1953 if start.elapsed() > timeout {
1954 return Err(RiscvError::RequestNotAcknowledged);
1955 }
1956 self.write_dm_register(dmcontrol)?;
1957 }
1958
1959 dmcontrol.set_haltreq(false);
1961 dmcontrol.set_ackhavereset(true);
1962 dmcontrol.set_hartreset(false);
1963 dmcontrol.set_ndmreset(false);
1964
1965 self.write_dm_register(dmcontrol)?;
1966
1967 self.debug_on_sw_breakpoint(true)?;
1969
1970 Ok(())
1971 }
1972
1973 fn debug_on_sw_breakpoint(&mut self, enabled: bool) -> Result<(), RiscvError> {
1974 let mut dcsr = Dcsr(self.read_csr(0x7b0)?);
1975
1976 dcsr.set_ebreakm(enabled);
1977 dcsr.set_ebreaks(enabled);
1978 dcsr.set_ebreaku(enabled);
1979
1980 match self.abstract_cmd_register_write(0x7b0, dcsr.0) {
1981 Ok(()) => {
1982 self.state.sw_breakpoint_debug_enabled = enabled;
1983 Ok(())
1984 }
1985 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1986 tracing::debug!(
1987 "Could not write core register {:#x} with abstract command, falling back to program buffer",
1988 0x7b0
1989 );
1990 self.write_csr_progbuf(0x7b0, dcsr.0)
1991 }
1992 other => other,
1993 }
1994 }
1995
1996 pub fn memory_access_config(&mut self) -> &mut MemoryAccessConfig {
1998 &mut self.state.memory_access_config
1999 }
2000}
2001
2002pub(crate) trait LargeRegister {
2003 const R0_ADDRESS: u8;
2004 const R1_ADDRESS: u8;
2005 const R2_ADDRESS: u8;
2006 const R3_ADDRESS: u8;
2007}
2008
2009struct Sbdata {}
2010
2011impl LargeRegister for Sbdata {
2012 const R0_ADDRESS: u8 = Sbdata0::ADDRESS_OFFSET as u8;
2013 const R1_ADDRESS: u8 = Sbdata1::ADDRESS_OFFSET as u8;
2014 const R2_ADDRESS: u8 = Sbdata2::ADDRESS_OFFSET as u8;
2015 const R3_ADDRESS: u8 = Sbdata3::ADDRESS_OFFSET as u8;
2016}
2017
2018struct Arg0 {}
2019
2020impl LargeRegister for Arg0 {
2021 const R0_ADDRESS: u8 = Data0::ADDRESS_OFFSET as u8;
2022 const R1_ADDRESS: u8 = Data1::ADDRESS_OFFSET as u8;
2023 const R2_ADDRESS: u8 = Data2::ADDRESS_OFFSET as u8;
2024 const R3_ADDRESS: u8 = Data3::ADDRESS_OFFSET as u8;
2025}
2026
2027pub(crate) trait RiscvValue32: RiscvValue + Into<u32> {
2029 fn from_register_value(value: u32) -> Self;
2030}
2031
2032impl RiscvValue32 for u8 {
2033 fn from_register_value(value: u32) -> Self {
2034 value as u8
2035 }
2036}
2037impl RiscvValue32 for u16 {
2038 fn from_register_value(value: u32) -> Self {
2039 value as u16
2040 }
2041}
2042impl RiscvValue32 for u32 {
2043 fn from_register_value(value: u32) -> Self {
2044 value
2045 }
2046}
2047
2048pub(crate) trait RiscvValue: std::fmt::Debug + Copy + Sized {
2051 const WIDTH: RiscvBusAccess;
2052
2053 fn schedule_read_from_register<R>(
2054 interface: &mut RiscvCommunicationInterface,
2055 results: &mut Vec<DeferredResultIndex>,
2056 ) -> Result<(), RiscvError>
2057 where
2058 R: LargeRegister;
2059
2060 fn read_scheduled_result(
2061 interface: &mut RiscvCommunicationInterface,
2062 results: &mut Vec<DeferredResultIndex>,
2063 ) -> Result<Self, RiscvError>;
2064
2065 fn schedule_write_to_register<R>(
2066 interface: &mut RiscvCommunicationInterface,
2067 value: Self,
2068 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2069 where
2070 R: LargeRegister;
2071}
2072
2073impl RiscvValue for u8 {
2074 const WIDTH: RiscvBusAccess = RiscvBusAccess::A8;
2075
2076 fn schedule_read_from_register<R>(
2077 interface: &mut RiscvCommunicationInterface,
2078 results: &mut Vec<DeferredResultIndex>,
2079 ) -> Result<(), RiscvError>
2080 where
2081 R: LargeRegister,
2082 {
2083 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2084 Ok(())
2085 }
2086
2087 fn read_scheduled_result(
2088 interface: &mut RiscvCommunicationInterface,
2089 results: &mut Vec<DeferredResultIndex>,
2090 ) -> Result<Self, RiscvError> {
2091 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2092
2093 Ok(result.into_u32() as u8)
2094 }
2095
2096 fn schedule_write_to_register<R>(
2097 interface: &mut RiscvCommunicationInterface,
2098 value: Self,
2099 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2100 where
2101 R: LargeRegister,
2102 {
2103 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value as u32)
2104 }
2105}
2106
2107impl RiscvValue for u16 {
2108 const WIDTH: RiscvBusAccess = RiscvBusAccess::A16;
2109
2110 fn schedule_read_from_register<R>(
2111 interface: &mut RiscvCommunicationInterface,
2112 results: &mut Vec<DeferredResultIndex>,
2113 ) -> Result<(), RiscvError>
2114 where
2115 R: LargeRegister,
2116 {
2117 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2118 Ok(())
2119 }
2120
2121 fn read_scheduled_result(
2122 interface: &mut RiscvCommunicationInterface,
2123 results: &mut Vec<DeferredResultIndex>,
2124 ) -> Result<Self, RiscvError> {
2125 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2126
2127 Ok(result.into_u32() as u16)
2128 }
2129
2130 fn schedule_write_to_register<R>(
2131 interface: &mut RiscvCommunicationInterface,
2132 value: Self,
2133 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2134 where
2135 R: LargeRegister,
2136 {
2137 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value as u32)
2138 }
2139}
2140
2141impl RiscvValue for u32 {
2142 const WIDTH: RiscvBusAccess = RiscvBusAccess::A32;
2143
2144 fn schedule_read_from_register<R>(
2145 interface: &mut RiscvCommunicationInterface,
2146 results: &mut Vec<DeferredResultIndex>,
2147 ) -> Result<(), RiscvError>
2148 where
2149 R: LargeRegister,
2150 {
2151 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2152 Ok(())
2153 }
2154
2155 fn read_scheduled_result(
2156 interface: &mut RiscvCommunicationInterface,
2157 results: &mut Vec<DeferredResultIndex>,
2158 ) -> Result<Self, RiscvError> {
2159 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2160
2161 Ok(result.into_u32())
2162 }
2163
2164 fn schedule_write_to_register<R>(
2165 interface: &mut RiscvCommunicationInterface,
2166 value: Self,
2167 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2168 where
2169 R: LargeRegister,
2170 {
2171 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value)
2172 }
2173}
2174
2175impl RiscvValue for u64 {
2176 const WIDTH: RiscvBusAccess = RiscvBusAccess::A64;
2177
2178 fn schedule_read_from_register<R>(
2179 interface: &mut RiscvCommunicationInterface,
2180 results: &mut Vec<DeferredResultIndex>,
2181 ) -> Result<(), RiscvError>
2182 where
2183 R: LargeRegister,
2184 {
2185 results.push(interface.schedule_read_dm_register_untyped(R::R1_ADDRESS as u64)?);
2186 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2187 Ok(())
2188 }
2189
2190 fn read_scheduled_result(
2191 interface: &mut RiscvCommunicationInterface,
2192 results: &mut Vec<DeferredResultIndex>,
2193 ) -> Result<Self, RiscvError> {
2194 let r1 = interface.dtm.read_deferred_result(results.remove(0))?;
2195 let r0 = interface.dtm.read_deferred_result(results.remove(0))?;
2196
2197 Ok(((r1.into_u32() as u64) << 32) | (r0.into_u32() as u64))
2198 }
2199
2200 fn schedule_write_to_register<R>(
2201 interface: &mut RiscvCommunicationInterface,
2202 value: Self,
2203 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2204 where
2205 R: LargeRegister,
2206 {
2207 let upper_bits = (value >> 32) as u32;
2208 let lower_bits = (value & 0xffff_ffff) as u32;
2209
2210 interface.schedule_write_dm_register_untyped(R::R1_ADDRESS as u64, upper_bits)?;
2214 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, lower_bits)
2215 }
2216}
2217
2218impl RiscvValue for u128 {
2219 const WIDTH: RiscvBusAccess = RiscvBusAccess::A128;
2220
2221 fn schedule_read_from_register<R>(
2222 interface: &mut RiscvCommunicationInterface,
2223 results: &mut Vec<DeferredResultIndex>,
2224 ) -> Result<(), RiscvError>
2225 where
2226 R: LargeRegister,
2227 {
2228 results.push(interface.schedule_read_dm_register_untyped(R::R3_ADDRESS as u64)?);
2229 results.push(interface.schedule_read_dm_register_untyped(R::R2_ADDRESS as u64)?);
2230 results.push(interface.schedule_read_dm_register_untyped(R::R1_ADDRESS as u64)?);
2231 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2232 Ok(())
2233 }
2234
2235 fn read_scheduled_result(
2236 interface: &mut RiscvCommunicationInterface,
2237 results: &mut Vec<DeferredResultIndex>,
2238 ) -> Result<Self, RiscvError> {
2239 let r3 = interface.dtm.read_deferred_result(results.remove(0))?;
2240 let r2 = interface.dtm.read_deferred_result(results.remove(0))?;
2241 let r1 = interface.dtm.read_deferred_result(results.remove(0))?;
2242 let r0 = interface.dtm.read_deferred_result(results.remove(0))?;
2243
2244 Ok(((r3.into_u32() as u128) << 96)
2245 | ((r2.into_u32() as u128) << 64)
2246 | ((r1.into_u32() as u128) << 32)
2247 | (r0.into_u32() as u128))
2248 }
2249
2250 fn schedule_write_to_register<R>(
2251 interface: &mut RiscvCommunicationInterface,
2252 value: Self,
2253 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2254 where
2255 R: LargeRegister,
2256 {
2257 let bits_3 = (value >> 96) as u32;
2258 let bits_2 = (value >> 64) as u32;
2259 let bits_1 = (value >> 32) as u32;
2260 let bits_0 = (value & 0xffff_ffff) as u32;
2261
2262 interface.schedule_write_dm_register_untyped(R::R3_ADDRESS as u64, bits_3)?;
2266 interface.schedule_write_dm_register_untyped(R::R2_ADDRESS as u64, bits_2)?;
2267 interface.schedule_write_dm_register_untyped(R::R1_ADDRESS as u64, bits_1)?;
2268 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, bits_0)
2269 }
2270}
2271
2272impl MemoryInterface for RiscvCommunicationInterface<'_> {
2273 fn supports_native_64bit_access(&mut self) -> bool {
2274 false
2275 }
2276
2277 fn read_word_64(&mut self, address: u64) -> Result<u64, crate::error::Error> {
2278 let address = valid_32bit_address(address)?;
2279 let mut ret = self.read_word::<u32>(address)? as u64;
2280 ret |= (self.read_word::<u32>(address + 4)? as u64) << 32;
2281
2282 Ok(ret)
2283 }
2284
2285 fn read_word_32(&mut self, address: u64) -> Result<u32, crate::Error> {
2286 let address = valid_32bit_address(address)?;
2287 tracing::debug!("read_word_32 from {:#08x}", address);
2288 self.read_word(address)
2289 }
2290
2291 fn read_word_16(&mut self, address: u64) -> Result<u16, crate::Error> {
2292 let address = valid_32bit_address(address)?;
2293 tracing::debug!("read_word_16 from {:#08x}", address);
2294 self.read_word(address)
2295 }
2296
2297 fn read_word_8(&mut self, address: u64) -> Result<u8, crate::Error> {
2298 let address = valid_32bit_address(address)?;
2299 tracing::debug!("read_word_8 from {:#08x}", address);
2300 self.read_word(address)
2301 }
2302
2303 fn read_64(&mut self, address: u64, data: &mut [u64]) -> Result<(), crate::error::Error> {
2304 let address = valid_32bit_address(address)?;
2305 tracing::debug!("read_64 from {:#08x}", address);
2306
2307 for (i, d) in data.iter_mut().enumerate() {
2308 *d = self.read_word_64((address + (i as u32 * 8)).into())?;
2309 }
2310
2311 Ok(())
2312 }
2313
2314 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), crate::Error> {
2315 let address = valid_32bit_address(address)?;
2316 tracing::debug!("read_32 from {:#08x}", address);
2317 self.read_multiple(address, data)
2318 }
2319
2320 fn read_16(&mut self, address: u64, data: &mut [u16]) -> Result<(), crate::Error> {
2321 let address = valid_32bit_address(address)?;
2322 tracing::debug!("read_16 from {:#08x}", address);
2323 self.read_multiple(address, data)
2324 }
2325
2326 fn read_8(&mut self, address: u64, data: &mut [u8]) -> Result<(), crate::Error> {
2327 let address = valid_32bit_address(address)?;
2328 tracing::debug!("read_8 from {:#08x}", address);
2329
2330 self.read_multiple(address, data)
2331 }
2332
2333 fn write_word_64(&mut self, address: u64, data: u64) -> Result<(), crate::error::Error> {
2334 let address = valid_32bit_address(address)?;
2335 let low_word = data as u32;
2336 let high_word = (data >> 32) as u32;
2337
2338 self.write_word(address, low_word)?;
2339 self.write_word(address + 4, high_word)
2340 }
2341
2342 fn write_word_32(&mut self, address: u64, data: u32) -> Result<(), crate::Error> {
2343 let address = valid_32bit_address(address)?;
2344 self.write_word(address, data)
2345 }
2346
2347 fn write_word_16(&mut self, address: u64, data: u16) -> Result<(), crate::Error> {
2348 let address = valid_32bit_address(address)?;
2349 self.write_word(address, data)
2350 }
2351
2352 fn write_word_8(&mut self, address: u64, data: u8) -> Result<(), crate::Error> {
2353 let address = valid_32bit_address(address)?;
2354 self.write_word(address, data)
2355 }
2356
2357 fn write_64(&mut self, address: u64, data: &[u64]) -> Result<(), crate::error::Error> {
2358 let address = valid_32bit_address(address)?;
2359 tracing::debug!("write_64 to {:#08x}", address);
2360
2361 for (i, d) in data.iter().enumerate() {
2362 self.write_word_64((address + (i as u32 * 8)).into(), *d)?;
2363 }
2364
2365 Ok(())
2366 }
2367
2368 fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), crate::Error> {
2369 let address = valid_32bit_address(address)?;
2370 tracing::debug!("write_32 to {:#08x}", address);
2371
2372 self.write_multiple(address, data)
2373 }
2374
2375 fn write_16(&mut self, address: u64, data: &[u16]) -> Result<(), crate::Error> {
2376 let address = valid_32bit_address(address)?;
2377 tracing::debug!("write_16 to {:#08x}", address);
2378
2379 self.write_multiple(address, data)
2380 }
2381
2382 fn write_8(&mut self, address: u64, data: &[u8]) -> Result<(), crate::Error> {
2383 let address = valid_32bit_address(address)?;
2384 tracing::debug!("write_8 to {:#08x}", address);
2385
2386 self.write_multiple(address, data)
2387 }
2388
2389 fn supports_8bit_transfers(&self) -> Result<bool, crate::Error> {
2390 Ok(true)
2391 }
2392
2393 fn flush(&mut self) -> Result<(), crate::Error> {
2394 Ok(())
2395 }
2396}
2397
2398#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, Eq, Debug)]
2402pub enum RiscvBusAccess {
2403 A8 = 0,
2405 A16 = 1,
2407 A32 = 2,
2409 A64 = 3,
2411 A128 = 4,
2413}
2414
2415impl RiscvBusAccess {
2416 const fn byte_width(&self) -> usize {
2418 match self {
2419 RiscvBusAccess::A8 => 1,
2420 RiscvBusAccess::A16 => 2,
2421 RiscvBusAccess::A32 => 4,
2422 RiscvBusAccess::A64 => 8,
2423 RiscvBusAccess::A128 => 16,
2424 }
2425 }
2426}
2427
2428impl From<RiscvBusAccess> for u8 {
2429 fn from(value: RiscvBusAccess) -> Self {
2430 value as u8
2431 }
2432}
2433
2434#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
2439pub enum MemoryAccessMethod {
2440 AbstractCommand,
2442 WaitingProgramBuffer,
2444 ProgramBuffer,
2446 SystemBus,
2448}
2449
2450memory_mapped_bitfield_register! {
2451 pub struct AccessRegisterCommand(u32);
2455 0x17, "command",
2456 impl From;
2457 pub _, set_cmd_type: 31, 24;
2459 pub u8, from into RiscvBusAccess, _, set_aarsize: 22, 20;
2469 pub _, set_aarpostincrement: 19;
2473 pub _, set_postexec: 18;
2479 pub _, set_transfer: 17;
2483 pub _, set_write: 16;
2487 pub _, set_regno: 15, 0;
2491}
2492
2493memory_mapped_bitfield_register! {
2494 pub struct Sbcs(u32);
2496 0x38, "sbcs",
2497 impl From;
2498 sbversion, _: 31, 29;
2504 sbbusyerror, set_sbbusyerror: 22;
2511 sbbusy, _: 21;
2520 sbreadonaddr, set_sbreadonaddr: 20;
2523 sbaccess, set_sbaccess: 19, 17;
2534 sbautoincrement, set_sbautoincrement: 16;
2537 sbreadondata, set_sbreadondata: 15;
2540 sberror, set_sberror: 14, 12;
2553 sbasize, _: 11, 5;
2555 sbaccess128, _: 4;
2557 sbaccess64, _: 3;
2559 sbaccess32, _: 2;
2561 sbaccess16, _: 1;
2563 sbaccess8, _: 0;
2565}
2566
2567memory_mapped_bitfield_register! {
2568 #[derive(Eq, PartialEq)]
2570 pub struct Abstractauto(u32);
2571 0x18, "abstractauto",
2572 impl From;
2573 autoexecprogbuf, set_autoexecprogbuf: 31, 16;
2576 autoexecdata, set_autoexecdata: 11, 0;
2579}
2580
2581memory_mapped_bitfield_register! {
2582 pub struct AccessMemoryCommand(u32);
2586 0x17, "command",
2587 _, set_cmd_type: 31, 24;
2589 pub _, set_aamvirtual: 23;
2598 pub _, set_aamsize: 22,20;
2604 pub _, set_aampostincrement: 19;
2608 pub _, set_write: 16;
2613 pub _, set_target_specific: 15, 14;
2615}
2616
2617impl From<AccessMemoryCommand> for u32 {
2618 fn from(register: AccessMemoryCommand) -> Self {
2619 let mut reg = register;
2620 reg.set_cmd_type(2);
2621 reg.0
2622 }
2623}
2624
2625impl From<u32> for AccessMemoryCommand {
2626 fn from(value: u32) -> Self {
2627 Self(value)
2628 }
2629}
2630
2631memory_mapped_bitfield_register! { pub struct Sbaddress0(u32); 0x39, "sbaddress0", impl From; }
2632memory_mapped_bitfield_register! { pub struct Sbaddress1(u32); 0x3a, "sbaddress1", impl From; }
2633memory_mapped_bitfield_register! { pub struct Sbaddress2(u32); 0x3b, "sbaddress2", impl From; }
2634memory_mapped_bitfield_register! { pub struct Sbaddress3(u32); 0x37, "sbaddress3", impl From; }
2635
2636memory_mapped_bitfield_register! { pub struct Sbdata0(u32); 0x3c, "sbdata0", impl From; }
2637memory_mapped_bitfield_register! { pub struct Sbdata1(u32); 0x3d, "sbdata1", impl From; }
2638memory_mapped_bitfield_register! { pub struct Sbdata2(u32); 0x3e, "sbdata2", impl From; }
2639memory_mapped_bitfield_register! { pub struct Sbdata3(u32); 0x3f, "sbdata3", impl From; }
2640
2641memory_mapped_bitfield_register! { pub struct Confstrptr0(u32); 0x19, "confstrptr0", impl From; }
2642memory_mapped_bitfield_register! { pub struct Confstrptr1(u32); 0x1a, "confstrptr1", impl From; }
2643memory_mapped_bitfield_register! { pub struct Confstrptr2(u32); 0x1b, "confstrptr2", impl From; }
2644memory_mapped_bitfield_register! { pub struct Confstrptr3(u32); 0x1c, "confstrptr3", impl From; }