1use bitfield::bitfield;
6use bitflags::bitflags;
7use std::num::NonZeroU16;
8
9pub const MMC_BLOCK_SIZE: u64 = 512;
11
12pub const EXT_CSD_SIZE: usize = 512;
15
16pub const EXT_CSD_BARRIER_EN: usize = 31;
17pub const EXT_CSD_BARRIER_ENABLED: u8 = 1;
18
19pub const EXT_CSD_FLUSH_CACHE: usize = 32;
20pub const EXT_CSD_FLUSH_CACHE_FLUSH: u8 = 0x1;
21pub const EXT_CSD_FLUSH_CACHE_BARRIER: u8 = 0x2;
22
23pub const EXT_CSD_CACHE_CTRL: usize = 33;
24pub const EXT_CSD_CACHE_EN_MASK: u8 = 1;
25
26pub const EXT_CSD_PARTITION_CONFIG: usize = 179;
27pub const EXT_CSD_PARTITION_ACCESS_MASK: u8 = 0xf8;
28
29pub const EXT_CSD_PARTITON_SWITCH_TIME: usize = 199;
30
31pub const EXT_CSD_SEC_FEATURE_SUPPORT: usize = 231;
32pub const EXT_CSD_SEC_FEATURE_SUPPORT_SEC_GB_CL_EN: u8 = 1 << 4;
33
34pub const EXT_CSD_CACHE_FLUSH_POLICY: usize = 240;
35pub const EXT_CSD_CACHE_FLUSH_POLICY_FIFO: u8 = 1;
36
37pub const EXT_CSD_GENERIC_CMD6_TIME: usize = 248;
38
39pub const EXT_CSD_BARRIER_SUPPORT: usize = 486;
40pub const EXT_CSD_BARRIER_SUPPORT_MASK: u8 = 0x1;
41
42#[derive(Clone, Copy, Debug, PartialEq, enumn::N)]
43#[repr(u8)]
44pub enum MmcCommand {
48 Switch = 6,
49 SendStatus = 13,
50 EraseGroupStart = 35,
51 EraseGroupEnd = 36,
52 Erase = 38,
53 QueuedTaskParams = 44,
54 QueuedTaskAddress = 45,
55 CommandQueueTaskManagement = 48,
56}
57
58pub const MMC_ERASE_TRIM_ARG: u32 = 0x00000001;
61
62pub const MMC_ERASE_DISCARD_ARG: u32 = 0x00000003;
66
67impl MmcCommand {
68 fn response_type(&self) -> DcmdResponseType {
69 match self {
70 Self::Switch => DcmdResponseType::R1B,
71 Self::SendStatus => DcmdResponseType::R1,
72 Self::EraseGroupStart => DcmdResponseType::R1,
73 Self::EraseGroupEnd => DcmdResponseType::R1,
74 Self::Erase => DcmdResponseType::R1B,
75 Self::QueuedTaskParams => DcmdResponseType::R1,
76 Self::QueuedTaskAddress => DcmdResponseType::R1,
77 Self::CommandQueueTaskManagement => DcmdResponseType::R1B,
78 }
79 }
80}
81
82impl TryFrom<u8> for MmcCommand {
83 type Error = ();
84
85 fn try_from(value: u8) -> Result<Self, ()> {
86 Self::n(value).ok_or(())
87 }
88}
89
90impl From<MmcCommand> for u8 {
91 fn from(value: MmcCommand) -> Self {
92 value as u8
93 }
94}
95
96bitflags! {
97 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
98 pub struct MmcSendStatusResponse: u32 {
100 const STATUS_ERR = 1 << 19;
101 const CURRENT_STATE_STDBY = 0x3 << 9;
102 const CURRENT_STATE_TRAN = 0x4 << 9;
103 const CURRENT_STATE_DATA = 0x5 << 9;
104 const CURRENT_STATE_RECV = 0x6 << 9;
105 const CURRENT_STATE_SLP = 0xa << 9;
106 const READY_FOR_DATA = 1 << 8;
107 const SWITCH_ERR = 1 << 7;
108 const EXCEPTION_EVENT = 1 << 6;
109 const APP_CMD = 1 << 5;
110 }
111}
112
113#[derive(Clone, Copy, Debug, PartialEq, Eq)]
114pub enum Direction {
116 Read,
117 Write,
118}
119
120impl Direction {
121 pub const fn as_str(&self) -> &'static str {
122 match self {
123 Self::Read => "read",
124 Self::Write => "write",
125 }
126 }
127}
128
129const TASK_DESCRIPTOR_ACT: u8 = 0b101;
131
132bitfield! {
133 #[derive(
134 Clone, Copy, Eq, PartialEq, zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable,
135 )]
136 pub struct CommandQueueTaskDescriptor(u128);
138 impl Debug;
139 pub bool, valid, set_valid: 0;
140 pub bool, end, set_end: 1;
141 pub bool, int, set_int: 2;
142 pub u8, act, set_act: 5, 3;
143 pub bool, forced_programming, set_forced_programming: 6;
144 pub u8, context_id, set_context_id: 10, 7;
145 pub bool, tag_request, set_tag_request: 11;
146 pub bool, data_direction, set_data_direction: 12;
147 pub bool, priority, set_priority: 13;
148 pub bool, qbr, set_qbr: 14;
149 pub bool, reliable_write, set_reliable_write: 15;
150 pub u16, block_count, set_block_count: 31, 16;
151 pub u32, block_offset, set_block_offset: 63, 32;
152 pub u32, dun, set_dun: 95, 64;
153 pub u8, cci, set_cci: 103, 96;
154 pub bool, ce, set_ce: 111;
155 }
157
158#[derive(Clone, Copy, Debug, PartialEq, Eq)]
159pub struct CryptoParams {
160 pub slot: u8,
161 pub dun: u32,
162}
163
164impl CommandQueueTaskDescriptor {
165 fn new(
166 direction: Direction,
167 block_offset: u32,
168 block_count: NonZeroU16,
169 queue_barrier: bool,
170 crypto_params: Option<CryptoParams>,
171 ) -> Self {
172 let mut this = Self(0);
173 this.set_valid(true);
174 this.set_end(true);
175 this.set_int(true);
176 this.set_act(TASK_DESCRIPTOR_ACT);
177 this.set_data_direction(direction == Direction::Read);
178 this.set_block_count(block_count.get());
179 this.set_block_offset(block_offset as u32);
180 this.set_qbr(queue_barrier);
181 if let Some(CryptoParams { slot, dun }) = crypto_params {
182 this.set_ce(true);
183 this.set_cci(slot);
184 this.set_dun(dun);
185 }
186 this
187 }
188}
189
190#[derive(Clone, Copy, Debug, PartialEq, Eq)]
191#[repr(u8)]
192pub enum DcmdResponseType {
193 NoResponse = 0b00,
195 R1 = 0b10,
197 R1B = 0b11,
199}
200
201impl From<DcmdResponseType> for u8 {
202 fn from(value: DcmdResponseType) -> Self {
203 value as u8
204 }
205}
206
207bitfield! {
208 #[derive(
209 Clone, Copy, Eq, PartialEq, zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable,
210 )]
211 pub struct CommandQueueDirectCmdTaskDescriptor(u128);
213 impl Debug;
214 pub bool, valid, set_valid: 0;
215 pub bool, end, set_end: 1;
216 pub bool, int, set_int: 2;
217 pub u8, act, set_act: 5, 3;
218 pub bool, qbr, set_qbr: 14;
219 pub u8, from try_into MmcCommand, cmd_index, set_cmd_index: 21, 16;
220 pub bool, cmd_timing, set_cmd_timing: 22;
221 pub u8, from into DcmdResponseType, _, set_response_type: 24, 23;
222 pub u32, cmd_arg, set_cmd_arg: 63, 32;
223}
224
225impl CommandQueueDirectCmdTaskDescriptor {
226 fn new(command: MmcCommand, command_arg: u32) -> Self {
227 let mut this = Self(0);
228 this.set_valid(true);
229 this.set_end(true);
230 this.set_act(TASK_DESCRIPTOR_ACT);
231 this.set_qbr(true);
232 this.set_int(true);
233 this.set_cmd_index(command);
234 let response_type = command.response_type();
235 this.set_response_type(response_type);
236 this.set_cmd_timing(response_type != DcmdResponseType::R1B);
239 this.set_cmd_arg(command_arg);
240 this
241 }
242}
243
244#[derive(Clone, Copy, Debug, PartialEq, Eq)]
245#[repr(transparent)]
246pub struct TransferBytes(u16);
250
251impl TransferBytes {
252 pub const MAX_BYTES: usize = u16::MAX as usize + 1;
254
255 pub const MAX_BLOCKS: u64 = Self::MAX_BYTES as u64 / MMC_BLOCK_SIZE;
257
258 pub const MAX: Self = Self(0);
259}
260
261impl From<TransferBytes> for u32 {
262 fn from(length: TransferBytes) -> u32 {
263 if length == TransferBytes::MAX { TransferBytes::MAX_BYTES as u32 } else { length.0 as u32 }
264 }
265}
266
267impl TryFrom<usize> for TransferBytes {
268 type Error = usize;
269
270 fn try_from(size: usize) -> Result<Self, Self::Error> {
271 if size == 0 {
272 Err(size)
273 } else if size < Self::MAX_BYTES {
274 debug_assert!(size <= u16::MAX as usize);
275 Ok(Self(size as u16))
276 } else if size == Self::MAX_BYTES {
277 Ok(Self::MAX)
278 } else {
279 Err(size)
280 }
281 }
282}
283
284#[derive(Clone, Copy, Debug, Eq, PartialEq, enumn::N)]
285#[repr(u8)]
286pub enum TransferAct {
287 Tran = 0b100,
289 Link = 0b110,
291}
292
293impl TryFrom<u8> for TransferAct {
294 type Error = ();
295
296 fn try_from(value: u8) -> Result<Self, ()> {
297 Self::n(value).ok_or(())
298 }
299}
300
301impl From<TransferAct> for u8 {
302 fn from(value: TransferAct) -> Self {
303 value as u8
304 }
305}
306
307bitfield! {
308 #[derive(
309 Clone, Copy, Eq, PartialEq, zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable,
310 )]
311 pub struct CommandQueueTransferDescriptor(u128);
313 impl Debug;
314 pub bool, valid, set_valid: 0;
315 pub bool, end, set_end: 1;
316 pub bool, int, set_int: 2;
317 pub u8, from try_into TransferAct, act, set_act: 5, 3;
318 pub u16, length, set_length: 31, 16;
320 pub u64, address, set_address: 95, 32;
321 }
323
324impl CommandQueueTransferDescriptor {
325 pub fn transfer(address: u64, length: TransferBytes, end: bool) -> Self {
327 let mut this = Self(0);
328 this.set_valid(true);
329 this.set_end(end);
330 this.set_int(false);
331 this.set_act(TransferAct::Tran);
332 this.set_length(length.0);
333 this.set_address(address);
334 this
335 }
336
337 pub fn link(address: u64) -> Self {
339 let mut this = Self(0);
340 this.set_valid(true);
341 this.set_end(false);
342 this.set_int(false);
343 this.set_act(TransferAct::Link);
344 this.set_address(address);
345 this
346 }
347}
348
349#[repr(C)]
350#[derive(
351 Debug, Clone, Copy, Eq, PartialEq, zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable,
352)]
353pub struct CommandQueueTDLEntry {
357 pub task: CommandQueueTaskDescriptor,
358 pub transfer: CommandQueueTransferDescriptor,
359}
360
361impl CommandQueueTDLEntry {
362 pub fn task(&self) -> &CommandQueueTaskDescriptor {
363 &self.task
364 }
365
366 pub fn single_buffer(
372 direction: Direction,
373 block_offset: u32,
374 block_count: NonZeroU16,
375 phys_address: u64,
376 queue_barrier: bool,
377 crypto_params: Option<CryptoParams>,
378 ) -> Result<Self, ()> {
379 let length = TransferBytes::try_from(block_count.get() as usize * MMC_BLOCK_SIZE as usize)
380 .map_err(|_| ())?;
381 Ok(Self {
382 task: CommandQueueTaskDescriptor::new(
383 direction,
384 block_offset,
385 block_count,
386 queue_barrier,
387 crypto_params,
388 ),
389 transfer: CommandQueueTransferDescriptor::transfer(phys_address, length, true),
390 })
391 }
392
393 pub fn scatter_gather_buffers(
398 direction: Direction,
399 block_offset: u32,
400 block_count: NonZeroU16,
401 descriptors_phys_address: u64,
402 queue_barrier: bool,
403 crypto_params: Option<CryptoParams>,
404 ) -> Self {
405 debug_assert!(
406 descriptors_phys_address
407 .is_multiple_of(std::mem::align_of::<CommandQueueTransferDescriptor>() as u64)
408 );
409 Self {
410 task: CommandQueueTaskDescriptor::new(
411 direction,
412 block_offset,
413 block_count,
414 queue_barrier,
415 crypto_params,
416 ),
417 transfer: CommandQueueTransferDescriptor::link(descriptors_phys_address),
418 }
419 }
420}
421
422#[repr(C)]
423#[derive(
424 Debug, Clone, Copy, Eq, PartialEq, zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable,
425)]
426pub struct CommandQueueTDLDirectCmdEntry {
433 pub task: CommandQueueDirectCmdTaskDescriptor,
434 _transfer: u128,
435}
436
437impl CommandQueueTDLDirectCmdEntry {
438 pub fn new(command: MmcCommand, command_arg: u32) -> Self {
439 Self { task: CommandQueueDirectCmdTaskDescriptor::new(command, command_arg), _transfer: 0 }
440 }
441}
442
443pub const CQHCI_TASK_DESCRIPTOR_LIST_NUM_SLOTS: usize = 32;
444pub const CQHCI_TASK_DESCRIPTOR_LIST_DCMD_SLOT: u8 = 31;
445pub const CQHCI_TASK_DESCRIPTOR_LIST_SIZE: usize =
446 CQHCI_TASK_DESCRIPTOR_LIST_NUM_SLOTS * size_of::<CommandQueueTDLEntry>();
447
448pub const CQHCI_CQ_VER_OFFSET: usize = 0x0;
451pub const CQHCI_CQ_CAP_OFFSET: usize = 0x4;
452pub const CQHCI_CQ_CFG_OFFSET: usize = 0x8;
453pub const CQHCI_CQ_CTL_OFFSET: usize = 0xC;
454pub const CQHCI_CQ_IS_OFFSET: usize = 0x10;
455pub const CQHCI_CQ_ISTE_OFFSET: usize = 0x14;
456pub const CQHCI_CQ_ISGE_OFFSET: usize = 0x18;
457pub const CQHCI_CQ_IC_OFFSET: usize = 0x1c;
458pub const CQHCI_CQ_TDLBA_OFFSET: usize = 0x20;
459pub const CQHCI_CQ_TDLBAU_OFFSET: usize = 0x24;
460pub const CQHCI_CQ_TDBR_OFFSET: usize = 0x28;
461pub const CQHCI_CQ_TCN_OFFSET: usize = 0x2C;
462pub const CQHCI_CQ_DQS_OFFSET: usize = 0x30;
463pub const CQHCI_CQ_DPT_OFFSET: usize = 0x34;
464pub const CQHCI_CQ_TDPE_OFFSET: usize = 0x3C;
465pub const CQHCI_CQ_SSC1_OFFSET: usize = 0x40;
466pub const CQHCI_CQ_SSC2_OFFSET: usize = 0x44;
467pub const CQHCI_CQ_CRDCT_OFFSET: usize = 0x48;
468pub const CQHCI_CQ_RMEM_OFFSET: usize = 0x50;
469pub const CQHCI_CQ_TERRI_OFFSET: usize = 0x54;
470pub const CQHCI_CQ_CRI_OFFSET: usize = 0x58;
471pub const CQHCI_CQ_CRA_OFFSET: usize = 0x5C;
472pub const CQHCI_CQ_HCCAP_OFFSET: usize = 0x60;
473pub const CQHCI_CQ_HCCFG_OFFSET: usize = 0x64;
474pub const CQHCI_CQ_CRYPTO_NQP_OFFSET: usize = 0x70;
476pub const CQHCI_CQ_CRYPTO_NQDUN_OFFSET: usize = 0x74;
477pub const CQHCI_CQ_CRYPTO_NQIS_OFFSET: usize = 0x78;
478pub const CQHCI_CQ_CRYPTO_NQIE_OFFSET: usize = 0x7C;
479pub const CQHCI_CQ_CRYPTO_CAP_OFFSET: usize = 0x100;
480
481bitfield! {
482 #[derive(Clone, Copy)]
483 pub struct CqhciCqCapsRegister(u32);
484 impl Debug;
485 pub u16, timer_clock_freq, set_timer_clock_freq: 9, 0;
486 pub u8, timer_clock_freq_multiplier, set_timer_clock_freq_multiplier: 15, 12;
487 pub bool, crypto_support, set_crypto_support: 28;
488}
489
490bitflags! {
491 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
492 pub struct CqhciCqCfgRegister: u32 {
493 const DCMD_ENABLE = 1 << 12;
494 const TASK_DESC_128 = 1 << 8; const CRYPTO_ENABLE = 1 << 1;
496 const CQE_ENABLE = 1;
497 }
498}
499
500bitflags! {
501 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
502 pub struct CqhciCqCtlRegister: u32 {
503 const HALT = 1;
504 const HALT_ON_EMPTY_QUEUE = 1 << 1;
505 const CLEAR_ALL_TASKS = 1 << 8;
506 }
507}
508
509bitfield! {
510 #[derive(Clone, Copy)]
511 pub struct CqhciCqSendStatusConfiguration1Register(u32);
512 impl Debug;
513 pub u16, ssc_idle_timer, set_ssc_idle_timer: 15, 0;
514 pub u8, ssc_block_counter, set_ssc_block_counter: 19, 16;
515}
516
517bitfield! {
518 #[derive(Clone, Copy)]
519 pub struct CqhciCqSendStatusConfiguration2Register(u32);
520 impl Debug;
521 pub u16, rca, set_rca: 15, 0;
522}
523
524impl CqhciCqSendStatusConfiguration2Register {
525 pub fn from_rca(rca: u16) -> Self {
526 let mut this = Self(0);
527 this.set_rca(rca);
528 this
529 }
530
531 pub fn raw(&self) -> u32 {
532 self.0
533 }
534}
535
536bitfield! {
538 #[derive(Clone, Copy)]
539 pub struct CqhciCqInterruptStatusRegister(u32);
540 impl Debug;
541 pub bool, halt_complete, set_halt_complete: 0;
542 pub bool, task_complete, set_task_complete: 1;
543 pub bool, response_error_detected, set_response_error_detected: 2;
544 pub bool, task_cleared, set_task_cleared: 3;
545 pub bool, general_crypto_error, set_general_crypto_error: 4;
546 pub bool, invalid_crypto_config_error, set_invalid_crypto_config_error: 5;
547 pub bool, device_exception_event, set_device_exception_event: 6;
548 pub bool, host_controller_fatal_error, _: 7;
549}
550
551impl CqhciCqInterruptStatusRegister {
552 pub fn is_error(&self) -> bool {
553 self.response_error_detected()
554 || self.general_crypto_error()
555 || self.invalid_crypto_config_error()
556 || self.host_controller_fatal_error()
557 }
558 pub fn raw(&self) -> u32 {
559 self.0
560 }
561 pub fn from_raw(value: u32) -> Self {
562 Self(value)
563 }
564}
565
566bitfield! {
567 #[derive(Clone, Copy)]
568 pub struct CqhciCqInterruptStatusEnableRegister(u32);
569 impl Debug;
570 pub bool, halt_complete, set_halt_complete: 0;
571 pub bool, task_complete, set_task_complete: 1;
572 pub bool, response_error_detected, set_response_error_detected: 2;
573 pub bool, task_cleared, set_task_cleared: 3;
574 pub bool, general_crypto_error, set_general_crypto_error: 4;
575 pub bool, invalid_crypto_config_error, set_invalid_crypto_config_error: 5;
576 pub bool, device_exception_event, set_device_exception_event: 6;
577 pub bool, host_controller_fatal_error, set_host_controller_fatal_error: 7;
578}
579
580impl CqhciCqInterruptStatusEnableRegister {
581 pub fn disabled() -> Self {
582 Self(0)
583 }
584 pub fn enabled() -> Self {
585 let mut this = Self(0xff);
586 this.set_device_exception_event(false);
590 this
591 }
592 pub fn raw(&self) -> u32 {
593 self.0
594 }
595 pub fn from_raw(value: u32) -> Self {
596 Self(value)
597 }
598}
599
600bitfield! {
601 #[derive(Clone, Copy)]
602 pub struct CqhciCqInterruptSignalEnableRegister(u32);
603 impl Debug;
604 pub bool, halt_complete, set_halt_complete: 0;
605 pub bool, task_complete, set_task_complete: 1;
606 pub bool, response_error_detected, set_response_error_detected: 2;
607 pub bool, task_cleared, set_task_cleared: 3;
608 pub bool, general_crypto_error, set_general_crypto_error: 4;
609 pub bool, invalid_crypto_config_error, set_invalid_crypto_config_error: 5;
610 pub bool, device_exception_event, set_device_exception_event: 6;
611 pub bool, host_controller_fatal_error, set_host_controller_fatal_error: 7;
612}
613
614impl CqhciCqInterruptSignalEnableRegister {
615 pub fn disabled() -> Self {
616 Self(0)
617 }
618 pub fn enabled() -> Self {
619 let mut this = Self(0xff);
620 this.set_device_exception_event(false);
622 this
623 }
624 pub fn raw(&self) -> u32 {
625 self.0
626 }
627 pub fn from_raw(value: u32) -> Self {
628 Self(value)
629 }
630}
631
632bitfield! {
633 #[derive(Clone, Copy)]
634 pub struct CqhciCqInterruptCoalescingRegister(u32);
635 impl Debug;
636 pub u8, ic_timeout_value, set_ic_timeout_value: 6, 0;
637 pub bool, ic_timeout_value_write_enable, set_ic_timeout_value_write_enable: 7;
638 pub u8, ic_counter_threshold, set_ic_counter_threshold: 12, 8;
639 pub bool, ic_counter_threshold_write_enable, set_ic_counter_threshold_write_enable: 15;
640 pub bool, ic_counter_timer_reset, set_ic_counter_timer_reset: 16;
641 pub bool, ic_status_bit, set_ic_status_bit: 20;
642 pub bool, ic_enable, set_ic_enable: 31;
643}
644
645impl CqhciCqInterruptCoalescingRegister {
646 pub fn disabled() -> Self {
647 let mut this = Self(0);
648 this.set_ic_enable(false);
649 this
650 }
651 pub fn raw(&self) -> u32 {
652 self.0
653 }
654}
655
656bitfield! {
657 #[derive(Clone, Copy)]
658 pub struct CqhciCqTaskErrorRegister(u32);
659 impl Debug;
660 pub u8, response_mode_error_command_index, set_response_mode_error_command_index: 5, 0;
661 pub u8, response_mode_error_task_id, set_response_mode_error_task_id: 12, 8;
662 pub bool, response_mode_error_fields_valid, set_response_mode_error_fields_valid: 15;
663 pub u8, data_transfer_error_command_index, set_data_transfer_error_command_index: 21, 16;
664 pub u8, data_transfer_error_task_id, set_data_transfer_error_task_id: 28, 24;
665 pub bool, data_transfer_error_fields_valid, set_data_transfer_error_fields_valid: 31;
666}
667
668pub const SDHCI_IS_OFFSET: usize = 0x30;
672pub const SDHCI_ISTE_OFFSET: usize = 0x34;
673pub const SDHCI_ISGE_OFFSET: usize = 0x38;
674
675bitfield! {
676 #[derive(Clone, Copy)]
677 pub struct SdhciInterruptStatusRegister(u32);
678 impl Debug;
679 pub bool, tuning_error, set_tuning_error: 26;
680 pub bool, adma_error, set_adma_error: 25;
681 pub bool, auto_cmd_error, set_auto_cmd_error: 24;
682 pub bool, current_limit_error, set_current_limit_error: 23;
683 pub bool, data_end_bit_error, set_data_end_bit_error: 22;
684 pub bool, data_crc_error, set_data_crc_error: 21;
685 pub bool, data_timeout_error, set_data_timeout_error: 20;
686 pub bool, command_index_error, set_command_index_error: 19;
687 pub bool, command_end_bit_error, set_command_end_bit_error: 18;
688 pub bool, command_crc_error, set_command_crc_error: 17;
689 pub bool, command_timeout_error, set_command_timeout_error: 16;
690 pub bool, error, set_error: 15;
691 pub bool, cqhci_interrupt, set_cqhci_interrupt: 14;
693 pub bool, card_interrupt, set_card_interrupt: 8;
694 pub bool, buffer_read_ready, set_buffer_read_ready: 5;
695 pub bool, buffer_write_ready, set_buffer_write_ready: 4;
696 pub bool, transfer_complete, set_transfer_complete: 1;
697 pub bool, command_complete, set_command_complete: 0;
698}
699
700impl SdhciInterruptStatusRegister {
701 pub fn take_cqhci_interrupt(&mut self) -> Self {
702 let mut cqhci = Self(0);
703 if self.cqhci_interrupt() {
704 cqhci.set_cqhci_interrupt(true);
705 self.set_cqhci_interrupt(false);
706 }
707 cqhci
708 }
709
710 pub fn is_empty(&self) -> bool {
711 self.raw() == 0
712 }
713
714 pub fn is_error(&self) -> bool {
715 self.tuning_error()
716 || self.adma_error()
717 || self.auto_cmd_error()
718 || self.current_limit_error()
719 || self.data_end_bit_error()
720 || self.data_crc_error()
721 || self.data_timeout_error()
722 || self.command_index_error()
723 || self.command_end_bit_error()
724 || self.command_crc_error()
725 || self.command_timeout_error()
726 || self.error()
727 }
728 pub fn from_raw(value: u32) -> Self {
729 Self(value)
730 }
731 pub fn raw(&self) -> u32 {
732 self.0
733 }
734}
735
736bitfield! {
737 #[derive(Clone, Copy)]
738 pub struct SdhciInterruptStatusEnableRegister(u32);
739 impl Debug;
740 pub bool, tuning_error, set_tuning_error: 26;
741 pub bool, adma_error, set_adma_error: 25;
742 pub bool, auto_cmd_error, set_auto_cmd_error: 24;
743 pub bool, current_limit_error, set_current_limit_error: 23;
744 pub bool, data_end_bit_error, set_data_end_bit_error: 22;
745 pub bool, data_crc_error, set_data_crc_error: 21;
746 pub bool, data_timeout_error, set_data_timeout_error: 20;
747 pub bool, command_index_error, set_command_index_error: 19;
748 pub bool, command_end_bit_error, set_command_end_bit_error: 18;
749 pub bool, command_crc_error, set_command_crc_error: 17;
750 pub bool, command_timeout_error, set_command_timeout_error: 16;
751 pub bool, error, set_error: 15;
752 pub bool, cqhci_interrupt, set_cqhci_interrupt: 14;
753 pub bool, card_interrupt, set_card_interrupt: 8;
754 pub bool, buffer_read_ready, set_buffer_read_ready: 5;
755 pub bool, buffer_write_ready, set_buffer_write_ready: 4;
756 pub bool, transfer_complete, set_transfer_complete: 1;
757 pub bool, command_complete, set_command_complete: 0;
758}
759
760impl SdhciInterruptStatusEnableRegister {
761 pub fn disabled() -> Self {
762 Self(0)
763 }
764 pub fn enabled() -> Self {
766 let mut this = Self::disabled();
767 this.enable_errors();
768 this.set_cqhci_interrupt(true);
769 this
770 }
771 pub fn errors_enabled() -> Self {
773 let mut this = Self::disabled();
774 this.enable_errors();
775 this
776 }
777 pub fn enable_errors(&mut self) {
778 self.set_tuning_error(true);
779 self.set_adma_error(true);
780 self.set_auto_cmd_error(true);
781 self.set_current_limit_error(true);
782 self.set_data_end_bit_error(true);
783 self.set_data_crc_error(true);
784 self.set_data_timeout_error(true);
785 self.set_command_index_error(true);
786 self.set_command_end_bit_error(true);
787 self.set_command_crc_error(true);
788 self.set_command_timeout_error(true);
789 self.set_error(true)
790 }
791 pub fn raw(&self) -> u32 {
792 self.0
793 }
794}
795
796bitfield! {
797 #[derive(Clone, Copy)]
798 pub struct SdhciInterruptSignalEnableRegister(u32);
799 impl Debug;
800 pub bool, tuning_error, set_tuning_error: 26;
801 pub bool, adma_error, set_adma_error: 25;
802 pub bool, auto_cmd_error, set_auto_cmd_error: 24;
803 pub bool, current_limit_error, set_current_limit_error: 23;
804 pub bool, data_end_bit_error, set_data_end_bit_error: 22;
805 pub bool, data_crc_error, set_data_crc_error: 21;
806 pub bool, data_timeout_error, set_data_timeout_error: 20;
807 pub bool, command_index_error, set_command_index_error: 19;
808 pub bool, command_end_bit_error, set_command_end_bit_error: 18;
809 pub bool, command_crc_error, set_command_crc_error: 17;
810 pub bool, command_timeout_error, set_command_timeout_error: 16;
811 pub bool, error, set_error: 15;
812 pub bool, cqhci_interrupt, set_cqhci_interrupt: 14;
813 pub bool, card_interrupt, set_card_interrupt: 8;
814 pub bool, buffer_read_ready, set_buffer_read_ready: 5;
815 pub bool, buffer_write_ready, set_buffer_write_ready: 4;
816 pub bool, transfer_complete, set_transfer_complete: 1;
817 pub bool, command_complete, set_command_complete: 0;
818}
819
820impl SdhciInterruptSignalEnableRegister {
821 pub fn disabled() -> Self {
822 Self(0)
823 }
824 pub fn enabled() -> Self {
826 let mut this = Self::disabled();
827 this.enable_errors();
828 this.set_cqhci_interrupt(true);
829 this
830 }
831 pub fn errors_enabled() -> Self {
833 let mut this = Self::disabled();
834 this.enable_errors();
835 this
836 }
837 pub fn enable_errors(&mut self) {
838 self.set_tuning_error(true);
839 self.set_adma_error(true);
840 self.set_auto_cmd_error(true);
841 self.set_current_limit_error(true);
842 self.set_data_end_bit_error(true);
843 self.set_data_crc_error(true);
844 self.set_data_timeout_error(true);
845 self.set_command_index_error(true);
846 self.set_command_end_bit_error(true);
847 self.set_command_crc_error(true);
848 self.set_command_timeout_error(true);
849 self.set_error(true)
850 }
851 pub fn raw(&self) -> u32 {
852 self.0
853 }
854}
855
856pub struct CqhciCryptoRegisterSnapshot {
858 pub crnqp: u32,
859 pub crnqdun: u32,
860 pub crnqis: u32,
861 pub crnqie: u32,
862 pub crcap: u32,
863}
864
865pub struct CqhciRegisterSnapshot {
867 pub ver: u32,
868 pub caps: u32,
869 pub cfg: u32,
870 pub ctl: u32,
871 pub is: u32,
872 pub iste: u32,
873 pub isge: u32,
874 pub tdlba: u32,
875 pub tdlbau: u32,
876 pub dbr: u32,
877 pub tcn: u32,
878 pub dqs: u32,
879 pub dpt: u32,
880 pub tdpe: u32,
881 pub ssc1: u32,
882 pub ssc2: u32,
883 pub rmem: u32,
884 pub terri: u32,
885 pub cri: u32,
886 pub cra: u32,
887 pub hccap: u32,
888 pub hccfg: u32,
889 pub crypto: Option<CqhciCryptoRegisterSnapshot>,
890}
891
892impl std::fmt::Debug for CqhciRegisterSnapshot {
893 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
894 writeln!(f, "CQHCI Registers: ")?;
895 writeln!(
896 f,
897 " ver {:08x} caps {:08x} cfg {:08x} ctl {:08x}",
898 self.ver, self.caps, self.cfg, self.ctl
899 )?;
900 writeln!(
901 f,
902 " is {:08x} iste {:08x} isge {:08x} tdlba {:08x}",
903 self.is, self.iste, self.isge, self.tdlba
904 )?;
905 writeln!(
906 f,
907 "tdlbau {:08x} dbr {:08x} tcn {:08x} dqs {:08x}",
908 self.tdlbau, self.dbr, self.tcn, self.dqs
909 )?;
910 writeln!(
911 f,
912 " dpt {:08x} tdpe {:08x} ssc1 {:08x} ssc2 {:08x}",
913 self.dpt, self.tdpe, self.ssc1, self.ssc2
914 )?;
915 writeln!(
916 f,
917 " rmem {:08x} terri {:08x} cri {:08x} cra {:08x}",
918 self.rmem, self.terri, self.cri, self.cra
919 )?;
920 write!(f, " hccap {:08x} hccfg {:08x}", self.hccap, self.hccfg)?;
921 if let Some(crypto) = &self.crypto {
922 writeln!(f)?;
923 writeln!(f, "CQHCI Crypto Registers: ")?;
924 writeln!(
925 f,
926 " crnqp {:08x}crnqdun {:08x}crnqis {:08x}crnqie {:08x}",
927 crypto.crnqp, crypto.crnqdun, crypto.crnqis, crypto.crnqie
928 )?;
929 write!(f, " crcap {:08x}", crypto.crcap)?;
930 }
931 Ok(())
932 }
933}