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.device_exception_event()
557 || self.host_controller_fatal_error()
558 }
559 pub fn raw(&self) -> u32 {
560 self.0
561 }
562 pub fn from_raw(value: u32) -> Self {
563 Self(value)
564 }
565}
566
567bitfield! {
568 #[derive(Clone, Copy)]
569 pub struct CqhciCqInterruptStatusEnableRegister(u32);
570 impl Debug;
571 pub bool, halt_complete, set_halt_complete: 0;
572 pub bool, task_complete, set_task_complete: 1;
573 pub bool, response_error_detected, set_response_error_detected: 2;
574 pub bool, task_cleared, set_task_cleared: 3;
575 pub bool, general_crypto_error, set_general_crypto_error: 4;
576 pub bool, invalid_crypto_config_error, set_invalid_crypto_config_error: 5;
577 pub bool, device_exception_event, set_device_exception_event: 6;
578 pub bool, host_controller_fatal_error, set_host_controller_fatal_error: 7;
579}
580
581impl CqhciCqInterruptStatusEnableRegister {
582 pub fn disabled() -> Self {
583 Self(0)
584 }
585 pub fn enabled() -> Self {
586 Self(0xff)
587 }
588 pub fn raw(&self) -> u32 {
589 self.0
590 }
591 pub fn from_raw(value: u32) -> Self {
592 Self(value)
593 }
594}
595
596bitfield! {
597 #[derive(Clone, Copy)]
598 pub struct CqhciCqInterruptSignalEnableRegister(u32);
599 impl Debug;
600 pub bool, halt_complete, set_halt_complete: 0;
601 pub bool, task_complete, set_task_complete: 1;
602 pub bool, response_error_detected, set_response_error_detected: 2;
603 pub bool, task_cleared, set_task_cleared: 3;
604 pub bool, general_crypto_error, set_general_crypto_error: 4;
605 pub bool, invalid_crypto_config_error, set_invalid_crypto_config_error: 5;
606 pub bool, device_exception_event, set_device_exception_event: 6;
607 pub bool, host_controller_fatal_error, set_host_controller_fatal_error: 7;
608}
609
610impl CqhciCqInterruptSignalEnableRegister {
611 pub fn disabled() -> Self {
612 Self(0)
613 }
614 pub fn enabled() -> Self {
615 Self(0xff)
616 }
617 pub fn raw(&self) -> u32 {
618 self.0
619 }
620 pub fn from_raw(value: u32) -> Self {
621 Self(value)
622 }
623}
624
625bitfield! {
626 #[derive(Clone, Copy)]
627 pub struct CqhciCqInterruptCoalescingRegister(u32);
628 impl Debug;
629 pub u8, ic_timeout_value, set_ic_timeout_value: 6, 0;
630 pub bool, ic_timeout_value_write_enable, set_ic_timeout_value_write_enable: 7;
631 pub u8, ic_counter_threshold, set_ic_counter_threshold: 12, 8;
632 pub bool, ic_counter_threshold_write_enable, set_ic_counter_threshold_write_enable: 15;
633 pub bool, ic_counter_timer_reset, set_ic_counter_timer_reset: 16;
634 pub bool, ic_status_bit, set_ic_status_bit: 20;
635 pub bool, ic_enable, set_ic_enable: 31;
636}
637
638impl CqhciCqInterruptCoalescingRegister {
639 pub fn disabled() -> Self {
640 let mut this = Self(0);
641 this.set_ic_enable(false);
642 this
643 }
644 pub fn raw(&self) -> u32 {
645 self.0
646 }
647}
648
649bitfield! {
650 #[derive(Clone, Copy)]
651 pub struct CqhciCqTaskErrorRegister(u32);
652 impl Debug;
653 pub u8, response_mode_error_command_index, set_response_mode_error_command_index: 5, 0;
654 pub u8, response_mode_error_task_id, set_response_mode_error_task_id: 12, 8;
655 pub bool, response_mode_error_fields_valid, set_response_mode_error_fields_valid: 15;
656 pub u8, data_transfer_error_command_index, set_data_transfer_error_command_index: 21, 16;
657 pub u8, data_transfer_error_task_id, set_data_transfer_error_task_id: 28, 24;
658 pub bool, data_transfer_error_fields_valid, set_data_transfer_error_fields_valid: 31;
659}
660
661pub const SDHCI_IS_OFFSET: usize = 0x30;
665pub const SDHCI_ISTE_OFFSET: usize = 0x34;
666pub const SDHCI_ISGE_OFFSET: usize = 0x38;
667
668bitfield! {
669 #[derive(Clone, Copy)]
670 pub struct SdhciInterruptStatusRegister(u32);
671 impl Debug;
672 pub bool, tuning_error, set_tuning_error: 26;
673 pub bool, adma_error, set_adma_error: 25;
674 pub bool, auto_cmd_error, set_auto_cmd_error: 24;
675 pub bool, current_limit_error, set_current_limit_error: 23;
676 pub bool, data_end_bit_error, set_data_end_bit_error: 22;
677 pub bool, data_crc_error, set_data_crc_error: 21;
678 pub bool, data_timeout_error, set_data_timeout_error: 20;
679 pub bool, command_index_error, set_command_index_error: 19;
680 pub bool, command_end_bit_error, set_command_end_bit_error: 18;
681 pub bool, command_crc_error, set_command_crc_error: 17;
682 pub bool, command_timeout_error, set_command_timeout_error: 16;
683 pub bool, error, set_error: 15;
684 pub bool, cqhci_interrupt, set_cqhci_interrupt: 14;
686 pub bool, card_interrupt, set_card_interrupt: 8;
687 pub bool, buffer_read_ready, set_buffer_read_ready: 5;
688 pub bool, buffer_write_ready, set_buffer_write_ready: 4;
689 pub bool, transfer_complete, set_transfer_complete: 1;
690 pub bool, command_complete, set_command_complete: 0;
691}
692
693impl SdhciInterruptStatusRegister {
694 pub fn take_cqhci_interrupt(&mut self) -> Self {
695 let mut cqhci = Self(0);
696 if self.cqhci_interrupt() {
697 cqhci.set_cqhci_interrupt(true);
698 self.set_cqhci_interrupt(false);
699 }
700 cqhci
701 }
702
703 pub fn is_empty(&self) -> bool {
704 self.raw() == 0
705 }
706
707 pub fn is_error(&self) -> bool {
708 self.tuning_error()
709 || self.adma_error()
710 || self.auto_cmd_error()
711 || self.current_limit_error()
712 || self.data_end_bit_error()
713 || self.data_crc_error()
714 || self.data_timeout_error()
715 || self.command_index_error()
716 || self.command_end_bit_error()
717 || self.command_crc_error()
718 || self.command_timeout_error()
719 || self.error()
720 }
721 pub fn from_raw(value: u32) -> Self {
722 Self(value)
723 }
724 pub fn raw(&self) -> u32 {
725 self.0
726 }
727}
728
729bitfield! {
730 #[derive(Clone, Copy)]
731 pub struct SdhciInterruptStatusEnableRegister(u32);
732 impl Debug;
733 pub bool, tuning_error, set_tuning_error: 26;
734 pub bool, adma_error, set_adma_error: 25;
735 pub bool, auto_cmd_error, set_auto_cmd_error: 24;
736 pub bool, current_limit_error, set_current_limit_error: 23;
737 pub bool, data_end_bit_error, set_data_end_bit_error: 22;
738 pub bool, data_crc_error, set_data_crc_error: 21;
739 pub bool, data_timeout_error, set_data_timeout_error: 20;
740 pub bool, command_index_error, set_command_index_error: 19;
741 pub bool, command_end_bit_error, set_command_end_bit_error: 18;
742 pub bool, command_crc_error, set_command_crc_error: 17;
743 pub bool, command_timeout_error, set_command_timeout_error: 16;
744 pub bool, error, set_error: 15;
745 pub bool, cqhci_interrupt, set_cqhci_interrupt: 14;
746 pub bool, card_interrupt, set_card_interrupt: 8;
747 pub bool, buffer_read_ready, set_buffer_read_ready: 5;
748 pub bool, buffer_write_ready, set_buffer_write_ready: 4;
749 pub bool, transfer_complete, set_transfer_complete: 1;
750 pub bool, command_complete, set_command_complete: 0;
751}
752
753impl SdhciInterruptStatusEnableRegister {
754 pub fn disabled() -> Self {
755 Self(0)
756 }
757 pub fn enabled() -> Self {
759 let mut this = Self::disabled();
760 this.enable_errors();
761 this.set_cqhci_interrupt(true);
762 this
763 }
764 pub fn errors_enabled() -> Self {
766 let mut this = Self::disabled();
767 this.enable_errors();
768 this
769 }
770 pub fn enable_errors(&mut self) {
771 self.set_tuning_error(true);
772 self.set_adma_error(true);
773 self.set_auto_cmd_error(true);
774 self.set_current_limit_error(true);
775 self.set_data_end_bit_error(true);
776 self.set_data_crc_error(true);
777 self.set_data_timeout_error(true);
778 self.set_command_index_error(true);
779 self.set_command_end_bit_error(true);
780 self.set_command_crc_error(true);
781 self.set_command_timeout_error(true);
782 self.set_error(true)
783 }
784 pub fn raw(&self) -> u32 {
785 self.0
786 }
787}
788
789bitfield! {
790 #[derive(Clone, Copy)]
791 pub struct SdhciInterruptSignalEnableRegister(u32);
792 impl Debug;
793 pub bool, tuning_error, set_tuning_error: 26;
794 pub bool, adma_error, set_adma_error: 25;
795 pub bool, auto_cmd_error, set_auto_cmd_error: 24;
796 pub bool, current_limit_error, set_current_limit_error: 23;
797 pub bool, data_end_bit_error, set_data_end_bit_error: 22;
798 pub bool, data_crc_error, set_data_crc_error: 21;
799 pub bool, data_timeout_error, set_data_timeout_error: 20;
800 pub bool, command_index_error, set_command_index_error: 19;
801 pub bool, command_end_bit_error, set_command_end_bit_error: 18;
802 pub bool, command_crc_error, set_command_crc_error: 17;
803 pub bool, command_timeout_error, set_command_timeout_error: 16;
804 pub bool, error, set_error: 15;
805 pub bool, cqhci_interrupt, set_cqhci_interrupt: 14;
806 pub bool, card_interrupt, set_card_interrupt: 8;
807 pub bool, buffer_read_ready, set_buffer_read_ready: 5;
808 pub bool, buffer_write_ready, set_buffer_write_ready: 4;
809 pub bool, transfer_complete, set_transfer_complete: 1;
810 pub bool, command_complete, set_command_complete: 0;
811}
812
813impl SdhciInterruptSignalEnableRegister {
814 pub fn disabled() -> Self {
815 Self(0)
816 }
817 pub fn enabled() -> Self {
819 let mut this = Self::disabled();
820 this.enable_errors();
821 this.set_cqhci_interrupt(true);
822 this
823 }
824 pub fn errors_enabled() -> Self {
826 let mut this = Self::disabled();
827 this.enable_errors();
828 this
829 }
830 pub fn enable_errors(&mut self) {
831 self.set_tuning_error(true);
832 self.set_adma_error(true);
833 self.set_auto_cmd_error(true);
834 self.set_current_limit_error(true);
835 self.set_data_end_bit_error(true);
836 self.set_data_crc_error(true);
837 self.set_data_timeout_error(true);
838 self.set_command_index_error(true);
839 self.set_command_end_bit_error(true);
840 self.set_command_crc_error(true);
841 self.set_command_timeout_error(true);
842 self.set_error(true)
843 }
844 pub fn raw(&self) -> u32 {
845 self.0
846 }
847}
848
849pub struct CqhciCryptoRegisterSnapshot {
851 pub crnqp: u32,
852 pub crnqdun: u32,
853 pub crnqis: u32,
854 pub crnqie: u32,
855 pub crcap: u32,
856}
857
858pub struct CqhciRegisterSnapshot {
860 pub ver: u32,
861 pub caps: u32,
862 pub cfg: u32,
863 pub ctl: u32,
864 pub is: u32,
865 pub iste: u32,
866 pub isge: u32,
867 pub tdlba: u32,
868 pub tdlbau: u32,
869 pub dbr: u32,
870 pub tcn: u32,
871 pub dqs: u32,
872 pub dpt: u32,
873 pub tdpe: u32,
874 pub ssc1: u32,
875 pub ssc2: u32,
876 pub rmem: u32,
877 pub terri: u32,
878 pub cri: u32,
879 pub cra: u32,
880 pub hccap: u32,
881 pub hccfg: u32,
882 pub crypto: Option<CqhciCryptoRegisterSnapshot>,
883}
884
885impl std::fmt::Debug for CqhciRegisterSnapshot {
886 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
887 writeln!(f, "CQHCI Registers: ")?;
888 writeln!(
889 f,
890 " ver {:08x} caps {:08x} cfg {:08x} ctl {:08x}",
891 self.ver, self.caps, self.cfg, self.ctl
892 )?;
893 writeln!(
894 f,
895 " is {:08x} iste {:08x} isge {:08x} tdlba {:08x}",
896 self.is, self.iste, self.isge, self.tdlba
897 )?;
898 writeln!(
899 f,
900 "tdlbau {:08x} dbr {:08x} tcn {:08x} dqs {:08x}",
901 self.tdlbau, self.dbr, self.tcn, self.dqs
902 )?;
903 writeln!(
904 f,
905 " dpt {:08x} tdpe {:08x} ssc1 {:08x} ssc2 {:08x}",
906 self.dpt, self.tdpe, self.ssc1, self.ssc2
907 )?;
908 writeln!(
909 f,
910 " rmem {:08x} terri {:08x} cri {:08x} cra {:08x}",
911 self.rmem, self.terri, self.cri, self.cra
912 )?;
913 write!(f, " hccap {:08x} hccfg {:08x}", self.hccap, self.hccfg)?;
914 if let Some(crypto) = &self.crypto {
915 writeln!(f)?;
916 writeln!(f, "CQHCI Crypto Registers: ")?;
917 writeln!(
918 f,
919 " crnqp {:08x}crnqdun {:08x}crnqis {:08x}crnqie {:08x}",
920 crypto.crnqp, crypto.crnqdun, crypto.crnqis, crypto.crnqie
921 )?;
922 write!(f, " crcap {:08x}", crypto.crcap)?;
923 }
924 Ok(())
925 }
926}