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