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
333const RISCV_TIMEOUT: Duration = Duration::from_secs(5);
335
336const RISCV_MAX_CSR_ADDR: u16 = 0xFFF;
339
340impl RiscvCommunicationInterfaceState {
341 pub fn new() -> Self {
343 RiscvCommunicationInterfaceState {
344 progbuf_size: 0,
346 progbuf_cache: [0u32; 16],
347
348 debug_version: DebugModuleVersion::NonConforming,
349
350 implicit_ebreak: false,
352
353 data_register_count: 1,
355
356 nscratch: 0,
357
358 supports_autoexec: false,
359
360 confstrptr: None,
361
362 hartsellen: 20,
364
365 num_harts: 1,
367
368 abstract_cmd_register_info: HashMap::new(),
369
370 s0: ScratchState::default(),
371 s1: ScratchState::default(),
372 enabled_harts: 0,
373 last_selected_hart: 0,
374 hasresethaltreq: None,
375 is_halted: false,
376
377 current_dmcontrol: Dmcontrol(0),
378
379 memory_access_config: MemoryAccessConfig::default(),
380 }
381 }
382
383 fn memory_access_method(
386 &mut self,
387 access_width: RiscvBusAccess,
388 address: u64,
389 ) -> MemoryAccessMethod {
390 self.memory_access_config.method(address, access_width)
391 }
392
393 fn memory_range_access_method(
394 &self,
395 width: RiscvBusAccess,
396 address_range: Range<u64>,
397 ) -> MemoryAccessMethod {
398 self.memory_access_config.range_method(address_range, width)
399 }
400}
401
402impl Default for RiscvCommunicationInterfaceState {
403 fn default() -> Self {
404 Self::new()
405 }
406}
407
408pub struct RiscvDebugInterfaceState {
410 pub(super) interface_state: RiscvCommunicationInterfaceState,
411 pub(super) dtm_state: Box<dyn Any + Send>,
412}
413
414impl RiscvDebugInterfaceState {
415 pub(super) fn new(dtm_state: Box<dyn Any + Send>) -> Self {
416 Self {
417 interface_state: RiscvCommunicationInterfaceState::new(),
418 dtm_state,
419 }
420 }
421}
422
423pub trait RiscvInterfaceBuilder<'probe> {
425 fn create_state(&self) -> RiscvDebugInterfaceState;
430
431 fn attach<'state>(
434 self: Box<Self>,
435 state: &'state mut RiscvDebugInterfaceState,
436 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
437 where
438 'probe: 'state;
439
440 fn attach_tunneled<'state>(
443 self: Box<Self>,
444 _tunnel_ir_id: u32,
445 _tunnel_ir_width: u32,
446 _state: &'state mut RiscvDebugInterfaceState,
447 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
448 where
449 'probe: 'state,
450 {
451 Err(DebugProbeError::InterfaceNotAvailable {
452 interface_name: "Tunneled RISC-V",
453 })
454 }
455
456 fn attach_auto<'state>(
461 self: Box<Self>,
462 target: &Target,
463 state: &'state mut RiscvDebugInterfaceState,
464 ) -> Result<RiscvCommunicationInterface<'state>, DebugProbeError>
465 where
466 'probe: 'state,
467 {
468 let maybe_tunnel = target.jtag.as_ref().and_then(|j| j.riscv_tunnel.as_ref());
469 if let Some(tunnel) = maybe_tunnel {
470 self.attach_tunneled(tunnel.ir_id, tunnel.ir_width, state)
471 } else {
472 self.attach(state)
473 }
474 }
475}
476
477#[derive(Debug)]
479pub struct RiscvCommunicationInterface<'state> {
480 dtm: Box<dyn DtmAccess + 'state>,
483 state: &'state mut RiscvCommunicationInterfaceState,
484}
485
486impl<'state> RiscvCommunicationInterface<'state> {
487 pub fn new(
489 dtm: Box<dyn DtmAccess + 'state>,
490 state: &'state mut RiscvCommunicationInterfaceState,
491 ) -> Self {
492 Self { dtm, state }
493 }
494
495 pub fn select_hart(&mut self, hart: u32) -> Result<(), RiscvError> {
497 if self.state.enabled_harts & (1 << hart) == 0 {
498 return Err(RiscvError::HartUnavailable);
499 }
500
501 if self.state.last_selected_hart == hart {
502 return Ok(());
503 }
504
505 let mut control = self.read_dm_register::<Dmcontrol>()?;
507 control.set_dmactive(true);
508 control.set_hartsel(hart);
509 self.schedule_write_dm_register(control)?;
510 self.state.last_selected_hart = hart;
511 Ok(())
512 }
513
514 pub fn hart_enabled(&self, hart: u32) -> bool {
516 self.state.enabled_harts & (1 << hart) != 0
517 }
518
519 pub fn target_reset_assert(&mut self) -> Result<(), DebugProbeError> {
521 self.dtm.target_reset_assert()
522 }
523
524 pub fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError> {
526 self.dtm.target_reset_deassert()
527 }
528
529 pub fn read_idcode(&mut self) -> Result<Option<u32>, DebugProbeError> {
531 self.dtm.read_idcode()
532 }
533
534 fn save_s0(&mut self) -> Result<bool, RiscvError> {
535 let s0 = self.abstract_cmd_register_read(®isters::S0)?;
536
537 self.state.s0.push(s0);
538
539 Ok(true)
540 }
541
542 fn restore_s0(&mut self, saved: bool) -> Result<(), RiscvError> {
543 if saved {
544 let s0 = self.state.s0.pop().unwrap();
545
546 self.abstract_cmd_register_write(®isters::S0, s0)?;
547 }
548
549 Ok(())
550 }
551
552 fn save_s1(&mut self) -> Result<bool, RiscvError> {
553 let s1 = self.abstract_cmd_register_read(®isters::S1)?;
554
555 self.state.s1.push(s1);
556
557 Ok(true)
558 }
559
560 fn restore_s1(&mut self, saved: bool) -> Result<(), RiscvError> {
561 if saved {
562 let s1 = self.state.s1.pop().unwrap();
563
564 self.abstract_cmd_register_write(®isters::S1, s1)?;
565 }
566
567 Ok(())
568 }
569
570 pub(crate) fn enter_debug_mode(&mut self) -> Result<(), RiscvError> {
571 tracing::debug!("Building RISC-V interface");
572 self.dtm.init()?;
573
574 self.dtm.clear_error_state()?;
576
577 let mut control = Dmcontrol(0);
579 control.set_dmactive(true);
580 self.schedule_write_dm_register(control)?;
581
582 let status: Dmstatus = self.read_dm_register()?;
584
585 self.state.progbuf_cache.fill(0);
586 self.state.memory_access_config = MemoryAccessConfig::default();
587 self.state.debug_version = DebugModuleVersion::from(status.version() as u8);
588 self.state.is_halted = status.allhalted();
589
590 if self.state.debug_version != DebugModuleVersion::Version0_13 {
592 return Err(RiscvError::UnsupportedDebugModuleVersion(
593 self.state.debug_version,
594 ));
595 }
596
597 self.state.implicit_ebreak = status.impebreak();
598
599 self.state.confstrptr = if status.confstrptrvalid() {
601 let confstrptr_0: Confstrptr0 = self.read_dm_register()?;
602 let confstrptr_1: Confstrptr1 = self.read_dm_register()?;
603 let confstrptr_2: Confstrptr2 = self.read_dm_register()?;
604 let confstrptr_3: Confstrptr3 = self.read_dm_register()?;
605 let confstrptr = (u32::from(confstrptr_0) as u128)
606 | ((u32::from(confstrptr_1) as u128) << 8)
607 | ((u32::from(confstrptr_2) as u128) << 16)
608 | ((u32::from(confstrptr_3) as u128) << 32);
609 Some(confstrptr)
610 } else {
611 None
612 };
613
614 tracing::debug!("dmstatus: {:?}", status);
615
616 let mut control = Dmcontrol(0);
619 control.set_dmactive(true);
620 control.set_hartsel(0xffff_ffff);
621
622 self.schedule_write_dm_register(control)?;
623
624 let control = self.read_dm_register::<Dmcontrol>()?;
625
626 self.state.hartsellen = control.hartsel().count_ones() as u8;
627
628 tracing::debug!("HARTSELLEN: {}", self.state.hartsellen);
629
630 let max_hart_index = 2u32.pow(self.state.hartsellen as u32);
633
634 let mut num_harts = 1;
636 self.state.enabled_harts = 1;
637
638 let mut control = Dmcontrol(0);
643 control.set_dmactive(true);
644 control.set_hartsel(max_hart_index - 1);
645 self.schedule_write_dm_register(control)?;
646
647 let status: Dmstatus = self.read_dm_register()?;
649
650 if status.anynonexistent() {
651 for hart_index in 1..max_hart_index {
652 let mut control = Dmcontrol(0);
653 control.set_dmactive(true);
654 control.set_hartsel(hart_index);
655
656 self.schedule_write_dm_register(control)?;
657
658 let status: Dmstatus = self.read_dm_register()?;
660
661 if status.anynonexistent() {
662 break;
663 }
664
665 if !status.allunavail() {
666 self.state.enabled_harts |= 1 << num_harts;
667 }
668
669 num_harts += 1;
670 }
671 } else {
672 tracing::debug!("anynonexistent not supported, assuming only one hart exists")
673 }
674
675 tracing::debug!("Number of harts: {}", num_harts);
676
677 self.state.num_harts = num_harts;
678
679 let mut control = Dmcontrol(0);
681 control.set_dmactive(true);
682 control.set_hartsel(0);
683
684 self.schedule_write_dm_register(control)?;
685
686 let abstractcs: Abstractcs = self.read_dm_register()?;
689
690 self.state.progbuf_size = abstractcs.progbufsize() as u8;
691 tracing::debug!("Program buffer size: {}", self.state.progbuf_size);
692
693 self.state.data_register_count = abstractcs.datacount() as u8;
694 tracing::debug!(
695 "Number of data registers: {}",
696 self.state.data_register_count
697 );
698
699 let hartinfo: Hartinfo = self.read_dm_register()?;
701
702 self.state.nscratch = hartinfo.nscratch() as u8;
703 tracing::debug!("Number of dscratch registers: {}", self.state.nscratch);
704
705 let mut abstractauto = Abstractauto(0);
707 abstractauto.set_autoexecprogbuf(2u32.pow(self.state.progbuf_size as u32) - 1);
708 abstractauto.set_autoexecdata(2u32.pow(self.state.data_register_count as u32) - 1);
709
710 self.schedule_write_dm_register(abstractauto)?;
711
712 let abstractauto_readback: Abstractauto = self.read_dm_register()?;
713
714 self.state.supports_autoexec = abstractauto_readback == abstractauto;
715 tracing::debug!("Support for autoexec: {}", self.state.supports_autoexec);
716
717 abstractauto = Abstractauto(0);
719 self.schedule_write_dm_register(abstractauto)?;
720
721 let sbcs = self.read_dm_register::<Sbcs>()?;
723
724 if sbcs.sbversion() == 1 {
728 if sbcs.sbaccess8() {
731 self.state
732 .memory_access_config
733 .set_default_method(RiscvBusAccess::A8, MemoryAccessMethod::SystemBus);
734 }
735
736 if sbcs.sbaccess16() {
737 self.state
738 .memory_access_config
739 .set_default_method(RiscvBusAccess::A16, MemoryAccessMethod::SystemBus);
740 }
741
742 if sbcs.sbaccess32() {
743 self.state
744 .memory_access_config
745 .set_default_method(RiscvBusAccess::A32, MemoryAccessMethod::SystemBus);
746 }
747
748 if sbcs.sbaccess64() {
749 self.state
750 .memory_access_config
751 .set_default_method(RiscvBusAccess::A64, MemoryAccessMethod::SystemBus);
752 }
753
754 if sbcs.sbaccess128() {
755 self.state
756 .memory_access_config
757 .set_default_method(RiscvBusAccess::A128, MemoryAccessMethod::SystemBus);
758 }
759 } else {
760 tracing::debug!(
761 "System bus interface version {} is not supported.",
762 sbcs.sbversion()
763 );
764 }
765
766 Ok(())
767 }
768
769 pub(crate) fn disable_debug_module(&mut self) -> Result<(), RiscvError> {
770 self.debug_on_sw_breakpoint(false)?;
771
772 let mut control = Dmcontrol(0);
773 control.set_dmactive(false);
774 self.write_dm_register(control)?;
775
776 Ok(())
777 }
778
779 pub(crate) fn halt(&mut self, timeout: Duration) -> Result<(), RiscvError> {
780 let mut dmcontrol = self.state.current_dmcontrol;
783 tracing::debug!(
784 "Before requesting halt, the Dmcontrol register value was: {:?}",
785 dmcontrol
786 );
787
788 dmcontrol.set_dmactive(true);
789 dmcontrol.set_haltreq(true);
790
791 self.schedule_write_dm_register(dmcontrol)?;
792
793 let result_status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
794
795 dmcontrol.set_haltreq(false);
797 self.write_dm_register(dmcontrol)?;
798
799 let result_status = Dmstatus(self.dtm.read_deferred_result(result_status_idx)?.into_u32());
800
801 if result_status.allhalted() {
802 self.state.is_halted = true;
803 return Ok(());
805 }
806
807 dmcontrol.set_haltreq(true);
811 self.write_dm_register(dmcontrol)?;
812
813 self.wait_for_core_halted(timeout)?;
815
816 dmcontrol.set_haltreq(false);
818 self.write_dm_register(dmcontrol)?;
819
820 Ok(())
821 }
822
823 pub(crate) fn halt_with_previous(&mut self, timeout: Duration) -> Result<bool, RiscvError> {
825 let was_running = if self.state.is_halted {
826 false
828 } else {
829 let status_idx = self.schedule_read_dm_register::<Dmstatus>()?;
832 self.halt(timeout)?;
833 let before_status = Dmstatus(self.dtm.read_deferred_result(status_idx)?.into_u32());
834
835 !before_status.allhalted()
836 };
837
838 Ok(was_running)
839 }
840
841 pub(crate) fn core_info(&mut self) -> Result<CoreInformation, RiscvError> {
842 let pc: u64 = self
843 .read_csr(super::registers::PC.id().0)
844 .map(|v| v.into())?;
845
846 Ok(CoreInformation { pc })
847 }
848
849 pub(crate) fn core_halted(&mut self) -> Result<bool, RiscvError> {
850 if !self.state.is_halted {
851 let dmstatus: Dmstatus = self.read_dm_register()?;
852
853 tracing::trace!("{:?}", dmstatus);
854
855 self.state.is_halted = dmstatus.allhalted();
856 }
857
858 Ok(self.state.is_halted)
859 }
860
861 pub(crate) fn wait_for_core_halted(&mut self, timeout: Duration) -> Result<(), RiscvError> {
862 let start = Instant::now();
864
865 while !self.core_halted()? {
866 if start.elapsed() >= timeout {
867 return Err(RiscvError::Timeout);
868 }
869 std::thread::sleep(Duration::from_millis(1));
871 }
872
873 Ok(())
874 }
875
876 pub(crate) fn halted_access<R>(
877 &mut self,
878 op: impl FnOnce(&mut Self) -> Result<R, RiscvError>,
879 ) -> Result<R, RiscvError> {
880 let was_running = self.halt_with_previous(Duration::from_millis(100))?;
881
882 let result = op(self);
883
884 if was_running {
885 self.resume_core()?;
886 }
887
888 result
889 }
890
891 pub(super) fn read_csr(&mut self, address: u16) -> Result<u32, RiscvError> {
892 tracing::debug!("Reading CSR {:#x}", address);
899
900 match self.abstract_cmd_register_read(address) {
903 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
904 tracing::debug!(
905 "Could not read core register {:#x} with abstract command, falling back to program buffer",
906 address
907 );
908 self.read_csr_progbuf(address)
909 }
910 other => other,
911 }
912 }
913
914 pub(crate) fn read_dm_register<R: MemoryMappedRegister<u32>>(
916 &mut self,
917 ) -> Result<R, RiscvError> {
918 tracing::debug!(
919 "Reading DM register '{}' at {:#010x}",
920 R::NAME,
921 R::get_mmio_address()
922 );
923
924 let register_value = self.read_dm_register_untyped(R::get_mmio_address())?.into();
925
926 tracing::debug!(
927 "Read DM register '{}' at {:#010x} = {:x?}",
928 R::NAME,
929 R::get_mmio_address(),
930 register_value
931 );
932
933 Ok(register_value)
934 }
935
936 fn read_dm_register_untyped(&mut self, address: u64) -> Result<u32, RiscvError> {
940 let read_idx = self.schedule_read_dm_register_untyped(address)?;
941 let register_value = self.dtm.read_deferred_result(read_idx)?.into_u32();
942
943 Ok(register_value)
944 }
945
946 pub(crate) fn write_dm_register<R: MemoryMappedRegister<u32>>(
947 &mut self,
948 register: R,
949 ) -> Result<(), RiscvError> {
950 tracing::debug!(
953 "Write DM register '{}' at {:#010x} = {:x?}",
954 R::NAME,
955 R::get_mmio_address(),
956 register
957 );
958
959 self.write_dm_register_untyped(R::get_mmio_address(), register.into())
960 }
961
962 fn write_dm_register_untyped(&mut self, address: u64, value: u32) -> Result<(), RiscvError> {
966 self.cache_write(address, value);
967 self.dtm.write_with_timeout(address, value, RISCV_TIMEOUT)?;
968
969 Ok(())
970 }
971
972 fn cache_write(&mut self, address: u64, value: u32) {
973 if address == Dmcontrol::ADDRESS_OFFSET {
974 self.state.current_dmcontrol = Dmcontrol(value);
975 }
976 }
977
978 fn schedule_write_progbuf(&mut self, index: usize, value: u32) -> Result<(), RiscvError> {
979 match index {
980 0 => self.schedule_write_dm_register(Progbuf0(value)),
981 1 => self.schedule_write_dm_register(Progbuf1(value)),
982 2 => self.schedule_write_dm_register(Progbuf2(value)),
983 3 => self.schedule_write_dm_register(Progbuf3(value)),
984 4 => self.schedule_write_dm_register(Progbuf4(value)),
985 5 => self.schedule_write_dm_register(Progbuf5(value)),
986 6 => self.schedule_write_dm_register(Progbuf6(value)),
987 7 => self.schedule_write_dm_register(Progbuf7(value)),
988 8 => self.schedule_write_dm_register(Progbuf8(value)),
989 9 => self.schedule_write_dm_register(Progbuf9(value)),
990 10 => self.schedule_write_dm_register(Progbuf10(value)),
991 11 => self.schedule_write_dm_register(Progbuf11(value)),
992 12 => self.schedule_write_dm_register(Progbuf12(value)),
993 13 => self.schedule_write_dm_register(Progbuf13(value)),
994 14 => self.schedule_write_dm_register(Progbuf14(value)),
995 15 => self.schedule_write_dm_register(Progbuf15(value)),
996 e => Err(RiscvError::UnsupportedProgramBufferRegister(e)),
997 }
998 }
999
1000 pub(crate) fn schedule_setup_program_buffer(&mut self, data: &[u32]) -> Result<(), RiscvError> {
1001 let required_len = if self.state.implicit_ebreak {
1002 data.len()
1003 } else {
1004 data.len() + 1
1005 };
1006
1007 if required_len > self.state.progbuf_size as usize {
1008 return Err(RiscvError::ProgramBufferTooSmall {
1009 required: required_len,
1010 actual: self.state.progbuf_size as usize,
1011 });
1012 }
1013
1014 if data == &self.state.progbuf_cache[..data.len()] {
1015 tracing::debug!("Program buffer is up-to-date, skipping write.");
1017 return Ok(());
1018 }
1019
1020 for (index, word) in data.iter().enumerate() {
1021 self.schedule_write_progbuf(index, *word)?;
1022 }
1023
1024 if !self.state.implicit_ebreak || data.len() < self.state.progbuf_size as usize {
1029 self.schedule_write_progbuf(data.len(), assembly::EBREAK)?;
1030 }
1031
1032 self.state.progbuf_cache[..data.len()].copy_from_slice(data);
1034
1035 Ok(())
1036 }
1037
1038 fn perform_memory_read_sysbus<V: RiscvValue32>(
1040 &mut self,
1041 address: u32,
1042 ) -> Result<V, RiscvError> {
1043 let mut sbcs = Sbcs(0);
1044
1045 sbcs.set_sbaccess(V::WIDTH as u32);
1046 sbcs.set_sbreadonaddr(true);
1047
1048 self.schedule_write_dm_register(sbcs)?;
1049 self.schedule_write_dm_register(Sbaddress0(address))?;
1050
1051 let mut results = vec![];
1052 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut results)?;
1053
1054 let sbcs = self.read_dm_register::<Sbcs>()?;
1056
1057 if sbcs.sberror() != 0 {
1058 Err(RiscvError::SystemBusAccess)
1059 } else {
1060 V::read_scheduled_result(self, &mut results)
1061 }
1062 }
1063
1064 fn perform_memory_read_multiple_sysbus<V: RiscvValue32>(
1068 &mut self,
1069 address: u32,
1070 data: &mut [V],
1071 ) -> Result<(), RiscvError> {
1072 if data.is_empty() {
1073 return Ok(());
1074 }
1075
1076 let mut sbcs = Sbcs(0);
1077
1078 sbcs.set_sbaccess(V::WIDTH as u32);
1079
1080 sbcs.set_sbreadonaddr(true);
1081
1082 sbcs.set_sbreadondata(true);
1083 sbcs.set_sbautoincrement(true);
1084
1085 self.schedule_write_dm_register(sbcs)?;
1086
1087 self.schedule_write_dm_register(Sbaddress0(address))?;
1088
1089 let data_len = data.len();
1090
1091 let mut read_results = Vec::with_capacity(data_len);
1092 for _ in data[..data_len - 1].iter() {
1093 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut read_results)?;
1094 }
1095
1096 self.schedule_write_dm_register(Sbcs(0))?;
1097
1098 self.schedule_read_large_dtm_register::<V, Sbdata>(&mut read_results)?;
1100
1101 let sbcs = self.read_dm_register::<Sbcs>()?;
1102
1103 for out in data.iter_mut() {
1104 *out = V::read_scheduled_result(self, &mut read_results)?;
1105 }
1106
1107 if sbcs.sberror() != 0 {
1109 Err(RiscvError::SystemBusAccess)
1110 } else {
1111 Ok(())
1112 }
1113 }
1114
1115 fn wait_for_idle(&mut self, timeout: Duration) -> Result<(), RiscvError> {
1117 let start = Instant::now();
1118 loop {
1119 let status: Abstractcs = self.read_dm_register()?;
1120 match AbstractCommandErrorKind::parse(status) {
1121 Ok(_) => return Ok(()),
1122 Err(AbstractCommandErrorKind::Busy) => {}
1123 Err(other) => return Err(other.into()),
1124 }
1125
1126 if start.elapsed() > timeout {
1127 return Err(RiscvError::Timeout);
1128 }
1129 }
1130 }
1131
1132 fn perform_memory_read_progbuf<V: RiscvValue32>(
1135 &mut self,
1136 address: u32,
1137 wait_for_idle: bool,
1138 ) -> Result<V, RiscvError> {
1139 self.halted_access(|core| {
1140 let s0 = core.save_s0()?;
1144
1145 let lw_command = assembly::lw(0, 8, V::WIDTH as u8, 8);
1146
1147 core.schedule_setup_program_buffer(&[lw_command])?;
1148
1149 core.schedule_write_dm_register(Data0(address))?;
1150
1151 let mut command = AccessRegisterCommand(0);
1153 command.set_cmd_type(0);
1154 command.set_transfer(true);
1155 command.set_write(true);
1156
1157 command.set_aarsize(RiscvBusAccess::A32);
1159 command.set_postexec(true);
1160
1161 command.set_regno((registers::S0).id.0 as u32);
1163
1164 core.schedule_write_dm_register(command)?;
1165
1166 if wait_for_idle {
1167 core.wait_for_idle(Duration::from_millis(10))?;
1168 }
1169
1170 let value = core.abstract_cmd_register_read(®isters::S0)?;
1172
1173 core.restore_s0(s0)?;
1175
1176 Ok(V::from_register_value(value))
1177 })
1178 }
1179
1180 fn perform_memory_read_multiple_progbuf<V: RiscvValue32>(
1181 &mut self,
1182 address: u32,
1183 data: &mut [V],
1184 wait_for_idle: bool,
1185 ) -> Result<(), RiscvError> {
1186 if data.is_empty() {
1187 return Ok(());
1188 }
1189
1190 if data.len() == 1 {
1191 data[0] = self.perform_memory_read_progbuf(address, wait_for_idle)?;
1192 return Ok(());
1193 }
1194
1195 self.halted_access(|core| {
1196 let s0 = core.save_s0()?;
1198 let s1 = core.save_s1()?;
1199
1200 let lw_command: u32 = assembly::lw(0, 8, V::WIDTH as u8, 9);
1202
1203 core.schedule_setup_program_buffer(&[
1204 lw_command,
1205 assembly::addi(8, 8, V::WIDTH.byte_width() as i16),
1206 ])?;
1207
1208 core.schedule_write_dm_register(Data0(address))?;
1209
1210 let mut command = AccessRegisterCommand(0);
1212 command.set_cmd_type(0);
1213 command.set_transfer(true);
1214 command.set_write(true);
1215
1216 command.set_aarsize(RiscvBusAccess::A32);
1218 command.set_postexec(true);
1219
1220 command.set_regno((registers::S0).id.0 as u32);
1222
1223 core.schedule_write_dm_register(command)?;
1224
1225 if wait_for_idle {
1226 core.wait_for_idle(Duration::from_millis(10))?;
1227 }
1228
1229 let data_len = data.len();
1230
1231 let mut result_idxs = Vec::with_capacity(data_len - 1);
1232 for out_idx in 0..data_len - 1 {
1233 let mut command = AccessRegisterCommand(0);
1234 command.set_cmd_type(0);
1235 command.set_transfer(true);
1236 command.set_write(false);
1237
1238 command.set_aarsize(RiscvBusAccess::A32);
1240 command.set_postexec(true);
1241
1242 command.set_regno((registers::S1).id.0 as u32);
1243
1244 core.schedule_write_dm_register(command)?;
1245
1246 let value_idx = core.schedule_read_dm_register::<Data0>()?;
1248
1249 result_idxs.push((out_idx, value_idx));
1250
1251 if wait_for_idle {
1252 core.wait_for_idle(Duration::from_millis(10))?;
1253 }
1254 }
1255
1256 let last_value = core.abstract_cmd_register_read(®isters::S1)?;
1258 data[data.len() - 1] = V::from_register_value(last_value);
1259
1260 for (out_idx, value_idx) in result_idxs {
1261 let value = core.dtm.read_deferred_result(value_idx)?.into_u32();
1262
1263 data[out_idx] = V::from_register_value(value);
1264 }
1265
1266 let status: Abstractcs = core.read_dm_register()?;
1267 AbstractCommandErrorKind::parse(status)?;
1268
1269 core.restore_s0(s0)?;
1270 core.restore_s1(s1)?;
1271
1272 Ok(())
1273 })
1274 }
1275
1276 fn perform_memory_write_sysbus<V: RiscvValue>(
1278 &mut self,
1279 address: u32,
1280 data: &[V],
1281 ) -> Result<(), RiscvError> {
1282 if data.is_empty() {
1283 return Ok(());
1284 }
1285 let mut sbcs = Sbcs(0);
1286
1287 sbcs.set_sbaccess(V::WIDTH as u32);
1289 sbcs.set_sbautoincrement(true);
1290
1291 self.schedule_write_dm_register(sbcs)?;
1292
1293 self.schedule_write_dm_register(Sbaddress0(address))?;
1294
1295 for value in data {
1296 self.schedule_write_large_dtm_register::<V, Sbdata>(*value)?;
1297 }
1298
1299 let sbcs = self.read_dm_register::<Sbcs>()?;
1301
1302 if sbcs.sberror() != 0 {
1303 Err(RiscvError::SystemBusAccess)
1304 } else {
1305 Ok(())
1306 }
1307 }
1308
1309 fn perform_memory_write_progbuf<V: RiscvValue32>(
1312 &mut self,
1313 address: u32,
1314 data: V,
1315 wait_for_idle: bool,
1316 ) -> Result<(), RiscvError> {
1317 self.halted_access(|core| {
1318 tracing::debug!(
1319 "Memory write using progbuf - {:#010x} = {:#?}",
1320 address,
1321 data
1322 );
1323
1324 let s0 = core.save_s0()?;
1326 let s1 = core.save_s1()?;
1327
1328 let sw_command = assembly::sw(0, 8, V::WIDTH as u32, 9);
1329
1330 core.schedule_setup_program_buffer(&[sw_command])?;
1331
1332 core.abstract_cmd_register_write(®isters::S0, address)?;
1334
1335 core.schedule_write_dm_register(Data0(data.into()))?;
1337
1338 let mut command = AccessRegisterCommand(0);
1340 command.set_cmd_type(0);
1341 command.set_transfer(true);
1342 command.set_write(true);
1343
1344 command.set_aarsize(RiscvBusAccess::A32);
1346 command.set_postexec(true);
1347
1348 command.set_regno((registers::S1).id.0 as u32);
1350
1351 core.schedule_write_dm_register(command)?;
1352
1353 if wait_for_idle && let Err(error) = core.wait_for_idle(Duration::from_millis(10)) {
1354 tracing::error!(
1355 "Executing the abstract command for write_{} failed: {:?}",
1356 V::WIDTH.byte_width() * 8,
1357 error
1358 );
1359
1360 return Err(error);
1361 }
1362
1363 core.restore_s0(s0)?;
1364 core.restore_s1(s1)?;
1365
1366 Ok(())
1367 })
1368 }
1369
1370 fn perform_memory_write_multiple_progbuf<V: RiscvValue32>(
1373 &mut self,
1374 address: u32,
1375 data: &[V],
1376 wait_for_idle: bool,
1377 ) -> Result<(), RiscvError> {
1378 if data.is_empty() {
1379 return Ok(());
1380 }
1381
1382 if data.len() == 1 {
1383 self.perform_memory_write_progbuf(address, data[0], wait_for_idle)?;
1384 return Ok(());
1385 }
1386
1387 self.halted_access(|core| {
1388 let s0 = core.save_s0()?;
1389 let s1 = core.save_s1()?;
1390
1391 core.schedule_setup_program_buffer(&[
1395 assembly::sw(0, 8, V::WIDTH as u32, 9),
1396 assembly::addi(8, 8, V::WIDTH.byte_width() as i16),
1397 ])?;
1398
1399 core.abstract_cmd_register_write(®isters::S0, address)?;
1401
1402 for value in data {
1403 core.schedule_write_dm_register(Data0((*value).into()))?;
1405
1406 let mut command = AccessRegisterCommand(0);
1408 command.set_cmd_type(0);
1409 command.set_transfer(true);
1410 command.set_write(true);
1411
1412 command.set_aarsize(RiscvBusAccess::A32);
1414 command.set_postexec(true);
1415
1416 command.set_regno((registers::S1).id.0 as u32);
1418
1419 core.schedule_write_dm_register(command)?;
1420
1421 if wait_for_idle && let Err(error) = core.wait_for_idle(Duration::from_millis(10)) {
1422 tracing::error!(
1423 "Executing the abstract command for write_multiple_{} failed: {:?}",
1424 V::WIDTH.byte_width() * 8,
1425 error,
1426 );
1427
1428 return Err(error);
1429 }
1430 }
1431
1432 core.restore_s0(s0)?;
1435 core.restore_s1(s1)?;
1436
1437 Ok(())
1438 })
1439 }
1440
1441 pub(crate) fn execute_abstract_command(&mut self, command: u32) -> Result<(), RiscvError> {
1442 let mut dmcontrol = self.state.current_dmcontrol;
1448 dmcontrol.set_dmactive(true);
1449 dmcontrol.set_haltreq(false);
1450 dmcontrol.set_resumereq(false);
1451 dmcontrol.set_ackhavereset(false);
1452 self.schedule_write_dm_register(dmcontrol)?;
1453
1454 fn do_execute_abstract_command(
1455 core: &mut RiscvCommunicationInterface,
1456 command: Command,
1457 ) -> Result<(), RiscvError> {
1458 let mut abstractcs_clear = Abstractcs(0);
1460 abstractcs_clear.set_cmderr(0x7);
1461
1462 core.schedule_write_dm_register(abstractcs_clear)?;
1463 core.schedule_write_dm_register(command)?;
1464
1465 let start_time = Instant::now();
1466
1467 let mut abstractcs;
1469 loop {
1470 abstractcs = core.read_dm_register::<Abstractcs>()?;
1471
1472 if !abstractcs.busy() {
1473 break;
1474 }
1475
1476 if start_time.elapsed() > RISCV_TIMEOUT {
1477 return Err(RiscvError::Timeout);
1478 }
1479 }
1480
1481 tracing::debug!("abstracts: {:?}", abstractcs);
1482
1483 AbstractCommandErrorKind::parse(abstractcs)?;
1485
1486 Ok(())
1487 }
1488
1489 match do_execute_abstract_command(self, Command(command)) {
1490 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::HaltResume)) => {
1491 if !self.core_halted()? {
1492 self.halted_access(|core| do_execute_abstract_command(core, Command(command)))
1495 } else {
1496 err
1499 }
1500 }
1501 other => other,
1502 }
1503 }
1504
1505 fn check_abstract_cmd_register_support(
1507 &self,
1508 regno: RegisterId,
1509 rw: CoreRegisterAbstractCmdSupport,
1510 ) -> bool {
1511 if let Some(status) = self.state.abstract_cmd_register_info.get(®no) {
1512 status.supports(rw)
1513 } else {
1514 true
1516 }
1517 }
1518
1519 fn set_abstract_cmd_register_unsupported(
1521 &mut self,
1522 regno: RegisterId,
1523 rw: CoreRegisterAbstractCmdSupport,
1524 ) {
1525 let entry = self
1526 .state
1527 .abstract_cmd_register_info
1528 .entry(regno)
1529 .or_insert(CoreRegisterAbstractCmdSupport::BOTH);
1530
1531 entry.unset(rw);
1532 }
1533
1534 pub(crate) fn abstract_cmd_register_read(
1536 &mut self,
1537 regno: impl Into<RegisterId>,
1538 ) -> Result<u32, RiscvError> {
1539 let regno = regno.into();
1540
1541 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::READ) {
1543 return Err(RiscvError::AbstractCommand(
1544 AbstractCommandErrorKind::NotSupported,
1545 ));
1546 }
1547
1548 let mut command = AccessRegisterCommand(0);
1550 command.set_cmd_type(0);
1551 command.set_transfer(true);
1552 command.set_aarsize(RiscvBusAccess::A32);
1553
1554 command.set_regno(regno.0 as u32);
1555
1556 match self.execute_abstract_command(command.0) {
1557 Ok(_) => (),
1558 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1559 self.set_abstract_cmd_register_unsupported(
1561 regno,
1562 CoreRegisterAbstractCmdSupport::READ,
1563 );
1564 err?;
1565 }
1566 Err(e) => return Err(e),
1567 }
1568
1569 let register_value: Data0 = self.read_dm_register()?;
1570
1571 Ok(register_value.into())
1572 }
1573
1574 pub(crate) fn abstract_cmd_register_write<V: RiscvValue>(
1575 &mut self,
1576 regno: impl Into<RegisterId>,
1577 value: V,
1578 ) -> Result<(), RiscvError> {
1579 let regno = regno.into();
1580
1581 if !self.check_abstract_cmd_register_support(regno, CoreRegisterAbstractCmdSupport::WRITE) {
1583 return Err(RiscvError::AbstractCommand(
1584 AbstractCommandErrorKind::NotSupported,
1585 ));
1586 }
1587
1588 let mut command = AccessRegisterCommand(0);
1590 command.set_cmd_type(0);
1591 command.set_transfer(true);
1592 command.set_write(true);
1593 command.set_aarsize(V::WIDTH);
1594
1595 command.set_regno(regno.0 as u32);
1596
1597 self.schedule_write_large_dtm_register::<V, Arg0>(value)?;
1598
1599 match self.execute_abstract_command(command.0) {
1600 Ok(_) => Ok(()),
1601 err @ Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1602 self.set_abstract_cmd_register_unsupported(
1604 regno,
1605 CoreRegisterAbstractCmdSupport::WRITE,
1606 );
1607 err
1608 }
1609 Err(e) => Err(e),
1610 }
1611 }
1612
1613 pub fn read_csr_progbuf(&mut self, address: u16) -> Result<u32, RiscvError> {
1615 self.halted_access(|core| {
1616 tracing::debug!("Reading CSR {:#04x}", address);
1617
1618 if address > RISCV_MAX_CSR_ADDR {
1620 return Err(RiscvError::UnsupportedCsrAddress(address));
1621 }
1622
1623 let s0 = core.save_s0()?;
1624
1625 let csrr_cmd = assembly::csrr(8, address);
1627
1628 core.schedule_setup_program_buffer(&[csrr_cmd])?;
1629
1630 let mut postexec_cmd = AccessRegisterCommand(0);
1632 postexec_cmd.set_postexec(true);
1633
1634 core.execute_abstract_command(postexec_cmd.0)?;
1635
1636 let reg_value = core.abstract_cmd_register_read(®isters::S0)?;
1638
1639 core.restore_s0(s0)?;
1641
1642 Ok(reg_value)
1643 })
1644 }
1645
1646 pub fn write_csr_progbuf(&mut self, address: u16, value: u32) -> Result<(), RiscvError> {
1648 self.halted_access(|core| {
1649 tracing::debug!("Writing CSR {:#04x}={}", address, value);
1650
1651 if address > RISCV_MAX_CSR_ADDR {
1653 return Err(RiscvError::UnsupportedCsrAddress(address));
1654 }
1655
1656 let s0 = core.save_s0()?;
1658
1659 core.abstract_cmd_register_write(®isters::S0, value)?;
1661
1662 let csrw_cmd = assembly::csrw(address, 8);
1664 core.schedule_setup_program_buffer(&[csrw_cmd])?;
1665
1666 let mut postexec_cmd = AccessRegisterCommand(0);
1668 postexec_cmd.set_postexec(true);
1669
1670 core.execute_abstract_command(postexec_cmd.0)?;
1671
1672 core.restore_s0(s0)?;
1675
1676 Ok(())
1677 })
1678 }
1679
1680 fn read_word<V: RiscvValue32>(&mut self, address: u32) -> Result<V, crate::Error> {
1681 let result = match self.state.memory_access_method(V::WIDTH, address as u64) {
1682 MemoryAccessMethod::ProgramBuffer => {
1683 self.perform_memory_read_progbuf(address, false)?
1684 }
1685 MemoryAccessMethod::WaitingProgramBuffer => {
1686 self.perform_memory_read_progbuf(address, true)?
1687 }
1688 MemoryAccessMethod::HaltedSystemBus => {
1689 self.halted_access(|this| this.perform_memory_read_sysbus(address))?
1690 }
1691 MemoryAccessMethod::SystemBus => self.perform_memory_read_sysbus(address)?,
1692 MemoryAccessMethod::AbstractCommand => {
1693 unimplemented!("Memory access using abstract commands is not implemted")
1694 }
1695 };
1696
1697 Ok(result)
1698 }
1699
1700 fn read_multiple<V: RiscvValue32>(
1701 &mut self,
1702 address: u32,
1703 data: &mut [V],
1704 ) -> Result<(), crate::Error> {
1705 let start = address as u64;
1706 let address_range = start..(start + (data.len() * V::WIDTH.byte_width()) as u64);
1707 let access_method = self
1708 .state
1709 .memory_range_access_method(V::WIDTH, address_range);
1710 tracing::debug!(
1711 "read_multiple({:?}) from {:#08x} using {:?}",
1712 V::WIDTH,
1713 address,
1714 access_method
1715 );
1716
1717 match access_method {
1718 MemoryAccessMethod::ProgramBuffer => {
1719 self.perform_memory_read_multiple_progbuf(address, data, false)?;
1720 }
1721 MemoryAccessMethod::WaitingProgramBuffer => {
1722 self.perform_memory_read_multiple_progbuf(address, data, true)?;
1723 }
1724 MemoryAccessMethod::HaltedSystemBus => {
1725 self.halted_access(|this| this.perform_memory_read_multiple_sysbus(address, data))?
1726 }
1727 MemoryAccessMethod::SystemBus => {
1728 self.perform_memory_read_multiple_sysbus(address, data)?;
1729 }
1730 MemoryAccessMethod::AbstractCommand => {
1731 unimplemented!("Memory access using abstract commands is not implemted")
1732 }
1733 };
1734
1735 Ok(())
1736 }
1737
1738 fn write_word<V: RiscvValue32>(&mut self, address: u32, data: V) -> Result<(), crate::Error> {
1739 match self.state.memory_access_method(V::WIDTH, address as u64) {
1740 MemoryAccessMethod::ProgramBuffer => {
1741 self.perform_memory_write_progbuf(address, data, false)?
1742 }
1743 MemoryAccessMethod::WaitingProgramBuffer => {
1744 self.perform_memory_write_progbuf(address, data, true)?
1745 }
1746 MemoryAccessMethod::HaltedSystemBus => {
1747 self.halted_access(|this| this.perform_memory_write_sysbus(address, &[data]))?
1748 }
1749 MemoryAccessMethod::SystemBus => self.perform_memory_write_sysbus(address, &[data])?,
1750 MemoryAccessMethod::AbstractCommand => {
1751 unimplemented!("Memory access using abstract commands is not implemted")
1752 }
1753 };
1754
1755 Ok(())
1756 }
1757
1758 fn write_multiple<V: RiscvValue32>(
1759 &mut self,
1760 address: u32,
1761 data: &[V],
1762 ) -> Result<(), crate::Error> {
1763 let start = address as u64;
1764 let address_range = start..(start + (data.len() * V::WIDTH.byte_width()) as u64);
1765 let access_method = self
1766 .state
1767 .memory_range_access_method(V::WIDTH, address_range);
1768 match access_method {
1769 MemoryAccessMethod::HaltedSystemBus => {
1770 self.halted_access(|this| this.perform_memory_write_sysbus(address, data))?
1771 }
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(crate) 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(crate) fn reset_hart_and_halt(&mut self, timeout: Duration) -> Result<(), RiscvError> {
1903 tracing::debug!("Resetting core, setting hartreset bit");
1904
1905 let mut dmcontrol = self.state.current_dmcontrol;
1906 dmcontrol.set_dmactive(true);
1907 dmcontrol.set_hartreset(true);
1908 dmcontrol.set_haltreq(true);
1909
1910 self.write_dm_register(dmcontrol)?;
1911
1912 let readback: Dmcontrol = self.read_dm_register()?;
1914
1915 if readback.hartreset() {
1916 tracing::debug!("Clearing hartreset bit");
1917 let mut dmcontrol = readback;
1919 dmcontrol.set_dmactive(true);
1920 dmcontrol.set_hartreset(false);
1921
1922 self.write_dm_register(dmcontrol)?;
1923 } else {
1924 tracing::debug!("Hartreset bit not supported, using ndmreset");
1928 dmcontrol.set_hartreset(false);
1929 dmcontrol.set_ndmreset(true);
1930 dmcontrol.set_haltreq(true);
1931
1932 self.write_dm_register(dmcontrol)?;
1933
1934 tracing::debug!("Clearing ndmreset bit");
1935 dmcontrol.set_ndmreset(false);
1936 dmcontrol.set_haltreq(true);
1937
1938 self.write_dm_register(dmcontrol)?;
1939 }
1940
1941 let start = Instant::now();
1942
1943 loop {
1944 let readback: Dmstatus = self.read_dm_register()?;
1946
1947 if readback.allhavereset() && readback.allhalted() {
1948 break;
1949 }
1950
1951 if start.elapsed() > timeout {
1952 return Err(RiscvError::RequestNotAcknowledged);
1953 }
1954 }
1955
1956 dmcontrol.set_haltreq(false);
1958 dmcontrol.set_ackhavereset(true);
1959 dmcontrol.set_hartreset(false);
1960 dmcontrol.set_ndmreset(false);
1961
1962 self.write_dm_register(dmcontrol)?;
1963
1964 self.debug_on_sw_breakpoint(true)?;
1966
1967 Ok(())
1968 }
1969
1970 pub(crate) fn debug_on_sw_breakpoint(&mut self, enabled: bool) -> Result<(), RiscvError> {
1971 let mut dcsr = Dcsr(self.read_csr(0x7b0)?);
1972
1973 dcsr.set_ebreakm(enabled);
1974 dcsr.set_ebreaks(enabled);
1975 dcsr.set_ebreaku(enabled);
1976
1977 match self.abstract_cmd_register_write(0x7b0, dcsr.0) {
1978 Err(RiscvError::AbstractCommand(AbstractCommandErrorKind::NotSupported)) => {
1979 tracing::debug!(
1980 "Could not write core register {:#x} with abstract command, falling back to program buffer",
1981 0x7b0
1982 );
1983 self.write_csr_progbuf(0x7b0, dcsr.0)
1984 }
1985 other => other,
1986 }
1987 }
1988
1989 pub fn memory_access_config(&mut self) -> &mut MemoryAccessConfig {
1991 &mut self.state.memory_access_config
1992 }
1993}
1994
1995pub(crate) trait LargeRegister {
1996 const R0_ADDRESS: u8;
1997 const R1_ADDRESS: u8;
1998 const R2_ADDRESS: u8;
1999 const R3_ADDRESS: u8;
2000}
2001
2002struct Sbdata {}
2003
2004impl LargeRegister for Sbdata {
2005 const R0_ADDRESS: u8 = Sbdata0::ADDRESS_OFFSET as u8;
2006 const R1_ADDRESS: u8 = Sbdata1::ADDRESS_OFFSET as u8;
2007 const R2_ADDRESS: u8 = Sbdata2::ADDRESS_OFFSET as u8;
2008 const R3_ADDRESS: u8 = Sbdata3::ADDRESS_OFFSET as u8;
2009}
2010
2011struct Arg0 {}
2012
2013impl LargeRegister for Arg0 {
2014 const R0_ADDRESS: u8 = Data0::ADDRESS_OFFSET as u8;
2015 const R1_ADDRESS: u8 = Data1::ADDRESS_OFFSET as u8;
2016 const R2_ADDRESS: u8 = Data2::ADDRESS_OFFSET as u8;
2017 const R3_ADDRESS: u8 = Data3::ADDRESS_OFFSET as u8;
2018}
2019
2020pub(crate) trait RiscvValue32: RiscvValue + Into<u32> {
2022 fn from_register_value(value: u32) -> Self;
2023}
2024
2025impl RiscvValue32 for u8 {
2026 fn from_register_value(value: u32) -> Self {
2027 value as u8
2028 }
2029}
2030impl RiscvValue32 for u16 {
2031 fn from_register_value(value: u32) -> Self {
2032 value as u16
2033 }
2034}
2035impl RiscvValue32 for u32 {
2036 fn from_register_value(value: u32) -> Self {
2037 value
2038 }
2039}
2040
2041pub(crate) trait RiscvValue: std::fmt::Debug + Copy + Sized {
2044 const WIDTH: RiscvBusAccess;
2045
2046 fn schedule_read_from_register<R>(
2047 interface: &mut RiscvCommunicationInterface,
2048 results: &mut Vec<DeferredResultIndex>,
2049 ) -> Result<(), RiscvError>
2050 where
2051 R: LargeRegister;
2052
2053 fn read_scheduled_result(
2054 interface: &mut RiscvCommunicationInterface,
2055 results: &mut Vec<DeferredResultIndex>,
2056 ) -> Result<Self, RiscvError>;
2057
2058 fn schedule_write_to_register<R>(
2059 interface: &mut RiscvCommunicationInterface,
2060 value: Self,
2061 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2062 where
2063 R: LargeRegister;
2064}
2065
2066impl RiscvValue for u8 {
2067 const WIDTH: RiscvBusAccess = RiscvBusAccess::A8;
2068
2069 fn schedule_read_from_register<R>(
2070 interface: &mut RiscvCommunicationInterface,
2071 results: &mut Vec<DeferredResultIndex>,
2072 ) -> Result<(), RiscvError>
2073 where
2074 R: LargeRegister,
2075 {
2076 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2077 Ok(())
2078 }
2079
2080 fn read_scheduled_result(
2081 interface: &mut RiscvCommunicationInterface,
2082 results: &mut Vec<DeferredResultIndex>,
2083 ) -> Result<Self, RiscvError> {
2084 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2085
2086 Ok(result.into_u32() as u8)
2087 }
2088
2089 fn schedule_write_to_register<R>(
2090 interface: &mut RiscvCommunicationInterface,
2091 value: Self,
2092 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2093 where
2094 R: LargeRegister,
2095 {
2096 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value as u32)
2097 }
2098}
2099
2100impl RiscvValue for u16 {
2101 const WIDTH: RiscvBusAccess = RiscvBusAccess::A16;
2102
2103 fn schedule_read_from_register<R>(
2104 interface: &mut RiscvCommunicationInterface,
2105 results: &mut Vec<DeferredResultIndex>,
2106 ) -> Result<(), RiscvError>
2107 where
2108 R: LargeRegister,
2109 {
2110 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2111 Ok(())
2112 }
2113
2114 fn read_scheduled_result(
2115 interface: &mut RiscvCommunicationInterface,
2116 results: &mut Vec<DeferredResultIndex>,
2117 ) -> Result<Self, RiscvError> {
2118 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2119
2120 Ok(result.into_u32() as u16)
2121 }
2122
2123 fn schedule_write_to_register<R>(
2124 interface: &mut RiscvCommunicationInterface,
2125 value: Self,
2126 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2127 where
2128 R: LargeRegister,
2129 {
2130 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value as u32)
2131 }
2132}
2133
2134impl RiscvValue for u32 {
2135 const WIDTH: RiscvBusAccess = RiscvBusAccess::A32;
2136
2137 fn schedule_read_from_register<R>(
2138 interface: &mut RiscvCommunicationInterface,
2139 results: &mut Vec<DeferredResultIndex>,
2140 ) -> Result<(), RiscvError>
2141 where
2142 R: LargeRegister,
2143 {
2144 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2145 Ok(())
2146 }
2147
2148 fn read_scheduled_result(
2149 interface: &mut RiscvCommunicationInterface,
2150 results: &mut Vec<DeferredResultIndex>,
2151 ) -> Result<Self, RiscvError> {
2152 let result = interface.dtm.read_deferred_result(results.remove(0))?;
2153
2154 Ok(result.into_u32())
2155 }
2156
2157 fn schedule_write_to_register<R>(
2158 interface: &mut RiscvCommunicationInterface,
2159 value: Self,
2160 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2161 where
2162 R: LargeRegister,
2163 {
2164 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, value)
2165 }
2166}
2167
2168impl RiscvValue for u64 {
2169 const WIDTH: RiscvBusAccess = RiscvBusAccess::A64;
2170
2171 fn schedule_read_from_register<R>(
2172 interface: &mut RiscvCommunicationInterface,
2173 results: &mut Vec<DeferredResultIndex>,
2174 ) -> Result<(), RiscvError>
2175 where
2176 R: LargeRegister,
2177 {
2178 results.push(interface.schedule_read_dm_register_untyped(R::R1_ADDRESS as u64)?);
2179 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2180 Ok(())
2181 }
2182
2183 fn read_scheduled_result(
2184 interface: &mut RiscvCommunicationInterface,
2185 results: &mut Vec<DeferredResultIndex>,
2186 ) -> Result<Self, RiscvError> {
2187 let r1 = interface.dtm.read_deferred_result(results.remove(0))?;
2188 let r0 = interface.dtm.read_deferred_result(results.remove(0))?;
2189
2190 Ok(((r1.into_u32() as u64) << 32) | (r0.into_u32() as u64))
2191 }
2192
2193 fn schedule_write_to_register<R>(
2194 interface: &mut RiscvCommunicationInterface,
2195 value: Self,
2196 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2197 where
2198 R: LargeRegister,
2199 {
2200 let upper_bits = (value >> 32) as u32;
2201 let lower_bits = (value & 0xffff_ffff) as u32;
2202
2203 interface.schedule_write_dm_register_untyped(R::R1_ADDRESS as u64, upper_bits)?;
2207 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, lower_bits)
2208 }
2209}
2210
2211impl RiscvValue for u128 {
2212 const WIDTH: RiscvBusAccess = RiscvBusAccess::A128;
2213
2214 fn schedule_read_from_register<R>(
2215 interface: &mut RiscvCommunicationInterface,
2216 results: &mut Vec<DeferredResultIndex>,
2217 ) -> Result<(), RiscvError>
2218 where
2219 R: LargeRegister,
2220 {
2221 results.push(interface.schedule_read_dm_register_untyped(R::R3_ADDRESS as u64)?);
2222 results.push(interface.schedule_read_dm_register_untyped(R::R2_ADDRESS as u64)?);
2223 results.push(interface.schedule_read_dm_register_untyped(R::R1_ADDRESS as u64)?);
2224 results.push(interface.schedule_read_dm_register_untyped(R::R0_ADDRESS as u64)?);
2225 Ok(())
2226 }
2227
2228 fn read_scheduled_result(
2229 interface: &mut RiscvCommunicationInterface,
2230 results: &mut Vec<DeferredResultIndex>,
2231 ) -> Result<Self, RiscvError> {
2232 let r3 = interface.dtm.read_deferred_result(results.remove(0))?;
2233 let r2 = interface.dtm.read_deferred_result(results.remove(0))?;
2234 let r1 = interface.dtm.read_deferred_result(results.remove(0))?;
2235 let r0 = interface.dtm.read_deferred_result(results.remove(0))?;
2236
2237 Ok(((r3.into_u32() as u128) << 96)
2238 | ((r2.into_u32() as u128) << 64)
2239 | ((r1.into_u32() as u128) << 32)
2240 | (r0.into_u32() as u128))
2241 }
2242
2243 fn schedule_write_to_register<R>(
2244 interface: &mut RiscvCommunicationInterface,
2245 value: Self,
2246 ) -> Result<Option<DeferredResultIndex>, RiscvError>
2247 where
2248 R: LargeRegister,
2249 {
2250 let bits_3 = (value >> 96) as u32;
2251 let bits_2 = (value >> 64) as u32;
2252 let bits_1 = (value >> 32) as u32;
2253 let bits_0 = (value & 0xffff_ffff) as u32;
2254
2255 interface.schedule_write_dm_register_untyped(R::R3_ADDRESS as u64, bits_3)?;
2259 interface.schedule_write_dm_register_untyped(R::R2_ADDRESS as u64, bits_2)?;
2260 interface.schedule_write_dm_register_untyped(R::R1_ADDRESS as u64, bits_1)?;
2261 interface.schedule_write_dm_register_untyped(R::R0_ADDRESS as u64, bits_0)
2262 }
2263}
2264
2265impl MemoryInterface for RiscvCommunicationInterface<'_> {
2266 fn supports_native_64bit_access(&mut self) -> bool {
2267 false
2268 }
2269
2270 fn read_word_64(&mut self, address: u64) -> Result<u64, crate::error::Error> {
2271 let address = valid_32bit_address(address)?;
2272 let mut ret = self.read_word::<u32>(address)? as u64;
2273 ret |= (self.read_word::<u32>(address + 4)? as u64) << 32;
2274
2275 Ok(ret)
2276 }
2277
2278 fn read_word_32(&mut self, address: u64) -> Result<u32, crate::Error> {
2279 let address = valid_32bit_address(address)?;
2280 tracing::debug!("read_word_32 from {:#08x}", address);
2281 self.read_word(address)
2282 }
2283
2284 fn read_word_16(&mut self, address: u64) -> Result<u16, crate::Error> {
2285 let address = valid_32bit_address(address)?;
2286 tracing::debug!("read_word_16 from {:#08x}", address);
2287 self.read_word(address)
2288 }
2289
2290 fn read_word_8(&mut self, address: u64) -> Result<u8, crate::Error> {
2291 let address = valid_32bit_address(address)?;
2292 tracing::debug!("read_word_8 from {:#08x}", address);
2293 self.read_word(address)
2294 }
2295
2296 fn read_64(&mut self, address: u64, data: &mut [u64]) -> Result<(), crate::error::Error> {
2297 let address = valid_32bit_address(address)?;
2298 tracing::debug!("read_64 from {:#08x}", address);
2299
2300 for (i, d) in data.iter_mut().enumerate() {
2301 *d = self.read_word_64((address + (i as u32 * 8)).into())?;
2302 }
2303
2304 Ok(())
2305 }
2306
2307 fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), crate::Error> {
2308 let address = valid_32bit_address(address)?;
2309 tracing::debug!("read_32 from {:#08x}", address);
2310 self.read_multiple(address, data)
2311 }
2312
2313 fn read_16(&mut self, address: u64, data: &mut [u16]) -> Result<(), crate::Error> {
2314 let address = valid_32bit_address(address)?;
2315 tracing::debug!("read_16 from {:#08x}", address);
2316 self.read_multiple(address, data)
2317 }
2318
2319 fn read_8(&mut self, address: u64, data: &mut [u8]) -> Result<(), crate::Error> {
2320 let address = valid_32bit_address(address)?;
2321 tracing::debug!("read_8 from {:#08x}", address);
2322
2323 self.read_multiple(address, data)
2324 }
2325
2326 fn read(&mut self, address: u64, data: &mut [u8]) -> Result<(), crate::Error> {
2327 let address = valid_32bit_address(address)?;
2328 tracing::debug!("read 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 HaltedSystemBus,
2448 SystemBus,
2450}
2451
2452memory_mapped_bitfield_register! {
2453 pub struct AccessRegisterCommand(u32);
2457 0x17, "command",
2458 impl From;
2459 pub _, set_cmd_type: 31, 24;
2461 pub u8, from into RiscvBusAccess, _, set_aarsize: 22, 20;
2471 pub _, set_aarpostincrement: 19;
2475 pub _, set_postexec: 18;
2481 pub _, set_transfer: 17;
2485 pub _, set_write: 16;
2489 pub _, set_regno: 15, 0;
2493}
2494
2495memory_mapped_bitfield_register! {
2496 pub struct Sbcs(u32);
2498 0x38, "sbcs",
2499 impl From;
2500 sbversion, _: 31, 29;
2506 sbbusyerror, set_sbbusyerror: 22;
2513 sbbusy, _: 21;
2522 sbreadonaddr, set_sbreadonaddr: 20;
2525 sbaccess, set_sbaccess: 19, 17;
2536 sbautoincrement, set_sbautoincrement: 16;
2539 sbreadondata, set_sbreadondata: 15;
2542 sberror, set_sberror: 14, 12;
2555 sbasize, _: 11, 5;
2557 sbaccess128, _: 4;
2559 sbaccess64, _: 3;
2561 sbaccess32, _: 2;
2563 sbaccess16, _: 1;
2565 sbaccess8, _: 0;
2567}
2568
2569memory_mapped_bitfield_register! {
2570 #[derive(Eq, PartialEq)]
2572 pub struct Abstractauto(u32);
2573 0x18, "abstractauto",
2574 impl From;
2575 autoexecprogbuf, set_autoexecprogbuf: 31, 16;
2578 autoexecdata, set_autoexecdata: 11, 0;
2581}
2582
2583memory_mapped_bitfield_register! {
2584 pub struct AccessMemoryCommand(u32);
2588 0x17, "command",
2589 _, set_cmd_type: 31, 24;
2591 pub _, set_aamvirtual: 23;
2600 pub _, set_aamsize: 22,20;
2606 pub _, set_aampostincrement: 19;
2610 pub _, set_write: 16;
2615 pub _, set_target_specific: 15, 14;
2617}
2618
2619impl From<AccessMemoryCommand> for u32 {
2620 fn from(register: AccessMemoryCommand) -> Self {
2621 let mut reg = register;
2622 reg.set_cmd_type(2);
2623 reg.0
2624 }
2625}
2626
2627impl From<u32> for AccessMemoryCommand {
2628 fn from(value: u32) -> Self {
2629 Self(value)
2630 }
2631}
2632
2633memory_mapped_bitfield_register! { pub struct Sbaddress0(u32); 0x39, "sbaddress0", impl From; }
2634memory_mapped_bitfield_register! { pub struct Sbaddress1(u32); 0x3a, "sbaddress1", impl From; }
2635memory_mapped_bitfield_register! { pub struct Sbaddress2(u32); 0x3b, "sbaddress2", impl From; }
2636memory_mapped_bitfield_register! { pub struct Sbaddress3(u32); 0x37, "sbaddress3", impl From; }
2637
2638memory_mapped_bitfield_register! { pub struct Sbdata0(u32); 0x3c, "sbdata0", impl From; }
2639memory_mapped_bitfield_register! { pub struct Sbdata1(u32); 0x3d, "sbdata1", impl From; }
2640memory_mapped_bitfield_register! { pub struct Sbdata2(u32); 0x3e, "sbdata2", impl From; }
2641memory_mapped_bitfield_register! { pub struct Sbdata3(u32); 0x3f, "sbdata3", impl From; }
2642
2643memory_mapped_bitfield_register! { pub struct Confstrptr0(u32); 0x19, "confstrptr0", impl From; }
2644memory_mapped_bitfield_register! { pub struct Confstrptr1(u32); 0x1a, "confstrptr1", impl From; }
2645memory_mapped_bitfield_register! { pub struct Confstrptr2(u32); 0x1b, "confstrptr2", impl From; }
2646memory_mapped_bitfield_register! { pub struct Confstrptr3(u32); 0x1c, "confstrptr3", impl From; }