add SDIO support
This commit is contained in:
		
							
								
								
									
										432
									
								
								zynq/zynq7000/src/sdio.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								zynq/zynq7000/src/sdio.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,432 @@
 | 
			
		||||
use arbitrary_int::{u2, u4, u6, u12};
 | 
			
		||||
 | 
			
		||||
pub const SDIO_BASE_ADDR_0: usize = 0xE010_0000;
 | 
			
		||||
pub const SDIO_BASE_ADDR_1: usize = 0xE010_1000;
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u3, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum BufferSize {
 | 
			
		||||
    _4kB = 0b000,
 | 
			
		||||
    _8kB = 0b001,
 | 
			
		||||
    _16kB = 0b010,
 | 
			
		||||
    _32kB = 0b011,
 | 
			
		||||
    _64kB = 0b100,
 | 
			
		||||
    _128kB = 0b101,
 | 
			
		||||
    _256kB = 0b110,
 | 
			
		||||
    _512kB = 0b111,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct BlockParams {
 | 
			
		||||
    #[bits(16..=31, rw)]
 | 
			
		||||
    blocks_count: u16,
 | 
			
		||||
    #[bits(12..=14, rw)]
 | 
			
		||||
    buffer_size: BufferSize,
 | 
			
		||||
    #[bits(0..=11, rw)]
 | 
			
		||||
    block_size: u12,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u2, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum CommandType {
 | 
			
		||||
    Normal = 0b00,
 | 
			
		||||
    Suspend = 0b01,
 | 
			
		||||
    Resume = 0b10,
 | 
			
		||||
    Abort = 0b11,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u2, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum ResponseLength {
 | 
			
		||||
    NoResponse = 0b00,
 | 
			
		||||
    ResponseLength136 = 0b01,
 | 
			
		||||
    ResponseLength48 = 0b10,
 | 
			
		||||
    ResponseLength48Check = 0b11,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u1, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum BlockSelect {
 | 
			
		||||
    SingleBlock = 0,
 | 
			
		||||
    MultiBlock = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u1, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum TransferDirection {
 | 
			
		||||
    /// Host to card.
 | 
			
		||||
    Write = 0,
 | 
			
		||||
    /// Card to host.
 | 
			
		||||
    Read = 1,
 | 
			
		||||
}
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct TransferModeAndCommand {
 | 
			
		||||
    /// Set to command number (CMD0-63, ACMD0-63)
 | 
			
		||||
    #[bits(24..=29, rw)]
 | 
			
		||||
    command_index: u6,
 | 
			
		||||
    #[bits(22..=23, rw)]
 | 
			
		||||
    command_type: CommandType,
 | 
			
		||||
    /// Set to [false] for the following:
 | 
			
		||||
    ///
 | 
			
		||||
    /// 1. Commands using only CMD line (ex. CMD52).
 | 
			
		||||
    /// 2. Commands with no data transfer but using busy signal on DAT\[0\].
 | 
			
		||||
    /// 3. Resume Command.
 | 
			
		||||
    #[bit(21, rw)]
 | 
			
		||||
    data_is_present: bool,
 | 
			
		||||
    /// When 1, the host controller checks the index field in the response to see if it has the
 | 
			
		||||
    /// same value as the command index.
 | 
			
		||||
    #[bit(20, rw)]
 | 
			
		||||
    command_index_check_enable: bool,
 | 
			
		||||
    /// When 1, the host controller checks the CRC field in the response.
 | 
			
		||||
    #[bit(18, rw)]
 | 
			
		||||
    command_crc_check_enable: bool,
 | 
			
		||||
    #[bits(16..=17, rw)]
 | 
			
		||||
    response_type_select: u2,
 | 
			
		||||
    #[bit(5, rw)]
 | 
			
		||||
    multi_single_block_select: BlockSelect,
 | 
			
		||||
    #[bit(4, rw)]
 | 
			
		||||
    data_transfer_direction: TransferDirection,
 | 
			
		||||
    /// Multiple block transfers for memory require CMD12 to stop the transaction. When this bit is
 | 
			
		||||
    /// 1, the host controller issues CMD12 automatically when completing the last block tranfer.
 | 
			
		||||
    #[bit(2, rw)]
 | 
			
		||||
    auto_cmd12_enable: bool,
 | 
			
		||||
    /// Enable block count register, which is only relevant for multiple block transfers.
 | 
			
		||||
    #[bit(1, rw)]
 | 
			
		||||
    block_count_enable: bool,
 | 
			
		||||
    #[bit(0, rw)]
 | 
			
		||||
    dma_enable: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct PresentState {
 | 
			
		||||
    #[bit(24, r)]
 | 
			
		||||
    cmd_line_signal_level: bool,
 | 
			
		||||
    #[bits(20..=23, r)]
 | 
			
		||||
    data_line_signal_level: u4,
 | 
			
		||||
    /// The Write Protect Switch is supported for memory and combo cards. This bit reflects the
 | 
			
		||||
    /// inversion of the SDx_WP pin.
 | 
			
		||||
    #[bit(19, r)]
 | 
			
		||||
    write_protect_switch_level: bool,
 | 
			
		||||
    /// This bit reflects the inverse value of the SDx_CDn pin.
 | 
			
		||||
    #[bit(18, r)]
 | 
			
		||||
    card_detect_pin_level: bool,
 | 
			
		||||
    /// This bit is used for testing. If it is 0, the Card Detect Pin Level is not stable. If this
 | 
			
		||||
    /// bit is set to 1, it means the Card Detect Pin Level is stable. The Software Reset For All
 | 
			
		||||
    /// in the Software Reset Register shall not affect this bit.
 | 
			
		||||
    #[bit(17, r)]
 | 
			
		||||
    card_state_stable: bool,
 | 
			
		||||
    /// This bit indicates whether a card has been inserted. Changing from 0 to 1 generates a Card
 | 
			
		||||
    /// Insertion interrupt in the Normal Interrupt Status register and changing from 1 to 0
 | 
			
		||||
    /// generates a Card Removal Interrupt in the Normal Interrupt Status register. The Software
 | 
			
		||||
    /// Reset For All in the Software Reset register shall not affect this bit. If a Card is
 | 
			
		||||
    /// removed while its power is on and its clock is oscillating, the HC shall clear SD Bus Power
 | 
			
		||||
    /// in the Power Control register and SD Clock Enable in the Clock control register. In
 | 
			
		||||
    /// addition the HD should clear the HC by the Software Reset For All in Software register. The
 | 
			
		||||
    /// card detect is active regardless of the SD Bus Power.
 | 
			
		||||
    #[bit(16, r)]
 | 
			
		||||
    card_inserted: bool,
 | 
			
		||||
    /// This status is used for non-DMA read transfers. This read only flag indicates that valid
 | 
			
		||||
    /// data exists in the host side buffer status. If this bit is 1, readable data exists in the
 | 
			
		||||
    /// buffer. A change of this bit from 1 to 0 occurs when all the block data is read from the
 | 
			
		||||
    /// buffer. A change of this bit from 0 to 1 occurs when all the block data is ready in the
 | 
			
		||||
    /// buffer and generates the Buffer Read Ready Interrupt.
 | 
			
		||||
    #[bit(11, r)]
 | 
			
		||||
    buffer_readable: bool,
 | 
			
		||||
    /// This status is used for non-DMA write transfers. This read only flag indicates if space is
 | 
			
		||||
    /// available for write data. If this bit is 1, data can be written to the buffer. A change of
 | 
			
		||||
    /// this bit from 1 to 0 occurs when all the block data is written to the buffer. A change of
 | 
			
		||||
    /// this bit from 0 to 1 occurs when top of block data can be written to the buffer and
 | 
			
		||||
    /// generates the Buffer Write Ready Interrupt.
 | 
			
		||||
    #[bit(10, r)]
 | 
			
		||||
    buffer_writable: bool,
 | 
			
		||||
    /// This status is used for detecting completion of a read transfer. This bit is set to 1 for
 | 
			
		||||
    /// either of the following conditions:
 | 
			
		||||
    ///
 | 
			
		||||
    ///  1. After the end bit of the read command
 | 
			
		||||
    ///  2. When writing a 1 to continue Request in the Block Gap Control register to restart a read
 | 
			
		||||
    ///  transfer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This bit is cleared to 0 for either of the following conditions:
 | 
			
		||||
    ///
 | 
			
		||||
    ///  1. When the last data block as specified by block length is transferred to the system.
 | 
			
		||||
    ///  2. When all valid data blocks have been transferred to the system and no current block
 | 
			
		||||
    ///  transfers are being sent as a result of the Stop At Block Gap Request set to 1. A transfer
 | 
			
		||||
    ///  complete interrupt is generated when this bit changes to 0.
 | 
			
		||||
    #[bit(9, r)]
 | 
			
		||||
    read_transfer_active: bool,
 | 
			
		||||
    /// This status indicates a write transfer is active. If this bit is 0, it means no valid write
 | 
			
		||||
    /// data exists in the HC. This bit is set in either of the following cases: 1. After the end
 | 
			
		||||
    /// bit of the write command. 2. When writing a 1 to Continue Request in the Block Gap Control
 | 
			
		||||
    /// register to restart a write transfer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This bit is cleared in either of the following cases:
 | 
			
		||||
    ///
 | 
			
		||||
    ///  1. After getting the CRC status of the last data block as specified by the transfer count
 | 
			
		||||
    ///  (Single or Multiple)
 | 
			
		||||
    ///  2. After getting a CRC status of any block where data transmission is about to be stopped
 | 
			
		||||
    ///  by a Stop At Block Gap Request.
 | 
			
		||||
    ///
 | 
			
		||||
    /// During a write transaction, a Block Gap Event interrupt is generated when this bit is
 | 
			
		||||
    /// changed to 0, as a result of the Stop At Block Gap Request being set. This status is useful
 | 
			
		||||
    /// for the HD in determining when to issue commands during write busy.
 | 
			
		||||
    #[bit(8, r)]
 | 
			
		||||
    write_transfer_active: bool,
 | 
			
		||||
    #[bit(2, r)]
 | 
			
		||||
    dat_line_active: bool,
 | 
			
		||||
    /// This status bit is generated if either the DAT Line Active or the Read transfer Active is
 | 
			
		||||
    /// set to 1. If this bit is 0, it indicates the HC can issue the next SD command. Commands
 | 
			
		||||
    /// with busy signal belong to Command Inhibit (DAT) (ex. R1b, R5b type). Changing from 1 to 0
 | 
			
		||||
    /// generates a Transfer Complete interrupt in the Normal interrupt status register.
 | 
			
		||||
    #[bit(1, r)]
 | 
			
		||||
    command_inhibit_dat: bool,
 | 
			
		||||
    /// 0 indicates the CMD line is not in use and the host controller can issue a SD command
 | 
			
		||||
    /// using the CMD line. This bit is set immediately after the Command register (00Fh) is
 | 
			
		||||
    /// written. This bit is cleared when the command response is received. Even if the Command
 | 
			
		||||
    /// Inhibit (DAT) is set to 1, Commands using only the CMD line can be issued if this bit is 0.
 | 
			
		||||
    /// Changing from 1 to 0 generates a Command complete interrupt in the Normal Interrupt Status
 | 
			
		||||
    /// register. If the HC cannot issue the command because of a command conflict error or because
 | 
			
		||||
    /// of Command Not Issued By Auto CMD12 Error, this bit shall remain 1 and the Command Complete
 | 
			
		||||
    /// is not set. Status issuing Auto CMD12 is not read from this bit.
 | 
			
		||||
    #[bit(0, r)]
 | 
			
		||||
    command_inhibit_cmd: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u1, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum DataTransferWidth {
 | 
			
		||||
    _1bit = 0,
 | 
			
		||||
    _4bit = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u2, exhaustive = true)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum DmaSelect {
 | 
			
		||||
    Sdma = 0b00,
 | 
			
		||||
    Adma1_32bits = 0b01,
 | 
			
		||||
    Adma2_32bits = 0b10,
 | 
			
		||||
    Adma2_64bits = 0b11,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u3, exhaustive = false)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum SdBusVoltageSelect {
 | 
			
		||||
    _1_8V = 0b101,
 | 
			
		||||
    _3_0V = 0b110,
 | 
			
		||||
    _3_3V = 0b111,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct HostPowerBlockgapWakeupControl {
 | 
			
		||||
    #[bit(26, rw)]
 | 
			
		||||
    wakeup_event_enable_on_sd_card_removal: bool,
 | 
			
		||||
    #[bit(25, rw)]
 | 
			
		||||
    wakeup_event_enable_on_sd_card_insertion: bool,
 | 
			
		||||
    #[bit(24, rw)]
 | 
			
		||||
    wakeup_event_enable_on_card_interrupt: bool,
 | 
			
		||||
    #[bit(19, rw)]
 | 
			
		||||
    interrupt_at_block_gap: bool,
 | 
			
		||||
    #[bit(18, rw)]
 | 
			
		||||
    read_wait_control: bool,
 | 
			
		||||
    #[bit(17, rw)]
 | 
			
		||||
    continue_request: bool,
 | 
			
		||||
    #[bit(16, rw)]
 | 
			
		||||
    stop_as_block_gap_request: bool,
 | 
			
		||||
    #[bits(9..=11, rw)]
 | 
			
		||||
    sd_bus_voltage_select: Option<SdBusVoltageSelect>,
 | 
			
		||||
    #[bit(8, rw)]
 | 
			
		||||
    sd_bus_power: bool,
 | 
			
		||||
    #[bit(7, rw)]
 | 
			
		||||
    card_detect_signal_detection: bool,
 | 
			
		||||
    #[bit(6, rw)]
 | 
			
		||||
    card_detetect_test_level: bool,
 | 
			
		||||
    #[bits(3..=4, rw)]
 | 
			
		||||
    dma_select: DmaSelect,
 | 
			
		||||
    #[bit(2, rw)]
 | 
			
		||||
    high_speed_enable: bool,
 | 
			
		||||
    #[bit(1, rw)]
 | 
			
		||||
    data_transfer_width: DataTransferWidth,
 | 
			
		||||
    #[bit(0, rw)]
 | 
			
		||||
    led_control: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitenum(u8, exhaustive = false)]
 | 
			
		||||
#[derive(Debug, PartialEq, Eq)]
 | 
			
		||||
pub enum SdclkFrequencySelect {
 | 
			
		||||
    Div256 = 0x80,
 | 
			
		||||
    Div128 = 0x40,
 | 
			
		||||
    Div64 = 0x20,
 | 
			
		||||
    Div32 = 0x10,
 | 
			
		||||
    Div16 = 0x08,
 | 
			
		||||
    Div8 = 0x04,
 | 
			
		||||
    Div4 = 0x02,
 | 
			
		||||
    Div2 = 0x01,
 | 
			
		||||
    Div1 = 0x00,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct ClockAndTimeoutAndSwResetControl {
 | 
			
		||||
    #[bit(26, rw)]
 | 
			
		||||
    software_reset_for_dat_line: bool,
 | 
			
		||||
    #[bit(25, rw)]
 | 
			
		||||
    software_reset_for_cmd_line: bool,
 | 
			
		||||
    #[bit(24, rw)]
 | 
			
		||||
    software_reset_for_all: bool,
 | 
			
		||||
    /// Interval: TMCLK * 2^(13 + register value)
 | 
			
		||||
    ///
 | 
			
		||||
    /// 0b1111 is reserved.
 | 
			
		||||
    #[bits(16..=19, rw)]
 | 
			
		||||
    data_timeout_counter_value: u4,
 | 
			
		||||
    #[bits(8..=15, rw)]
 | 
			
		||||
    sdclk_frequency_select: Option<SdclkFrequencySelect>,
 | 
			
		||||
    #[bit(2, rw)]
 | 
			
		||||
    sd_clock_enable: bool,
 | 
			
		||||
    #[bit(1, r)]
 | 
			
		||||
    internal_clock_stable: bool,
 | 
			
		||||
    #[bit(0, rw)]
 | 
			
		||||
    internal_clock_enable: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct InterruptStatus {
 | 
			
		||||
    #[bit(29, rw)]
 | 
			
		||||
    ceata_error_status: bool,
 | 
			
		||||
    #[bit(28, rw)]
 | 
			
		||||
    target_response_error: bool,
 | 
			
		||||
    #[bit(25, rw)]
 | 
			
		||||
    adma_error: bool,
 | 
			
		||||
    #[bit(24, rw)]
 | 
			
		||||
    auto_cmd12_error: bool,
 | 
			
		||||
    #[bit(23, rw)]
 | 
			
		||||
    current_limit_error: bool,
 | 
			
		||||
    #[bit(22, rw)]
 | 
			
		||||
    data_end_bit_error: bool,
 | 
			
		||||
    #[bit(21, rw)]
 | 
			
		||||
    data_crc_error: bool,
 | 
			
		||||
    #[bit(20, rw)]
 | 
			
		||||
    data_timeout_error: bool,
 | 
			
		||||
    #[bit(19, rw)]
 | 
			
		||||
    command_index_error: bool,
 | 
			
		||||
    #[bit(18, rw)]
 | 
			
		||||
    command_end_bit_error: bool,
 | 
			
		||||
    #[bit(17, rw)]
 | 
			
		||||
    command_crc_error: bool,
 | 
			
		||||
    #[bit(16, rw)]
 | 
			
		||||
    command_timeout_error: bool,
 | 
			
		||||
    #[bit(15, r)]
 | 
			
		||||
    error_interrupt: bool,
 | 
			
		||||
    #[bit(10, rw)]
 | 
			
		||||
    boot_terminate: bool,
 | 
			
		||||
    #[bit(9, rw)]
 | 
			
		||||
    boot_ack_recv: bool,
 | 
			
		||||
    #[bit(8, r)]
 | 
			
		||||
    card_interrupt: bool,
 | 
			
		||||
    #[bit(7, rw)]
 | 
			
		||||
    card_removal: bool,
 | 
			
		||||
    #[bit(6, rw)]
 | 
			
		||||
    card_insertion: bool,
 | 
			
		||||
    #[bit(5, rw)]
 | 
			
		||||
    buffer_read_ready: bool,
 | 
			
		||||
    #[bit(4, rw)]
 | 
			
		||||
    buffer_write_ready: bool,
 | 
			
		||||
    #[bit(3, rw)]
 | 
			
		||||
    dma_interrupt: bool,
 | 
			
		||||
    #[bit(2, rw)]
 | 
			
		||||
    blockgap_event: bool,
 | 
			
		||||
    #[bit(1, rw)]
 | 
			
		||||
    transfer_complete: bool,
 | 
			
		||||
    #[bit(0, rw)]
 | 
			
		||||
    command_complete: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[bitbybit::bitfield(u32, debug)]
 | 
			
		||||
pub struct InterruptMask {
 | 
			
		||||
    #[bit(29, rw)]
 | 
			
		||||
    ceata_error_status: bool,
 | 
			
		||||
    #[bit(28, rw)]
 | 
			
		||||
    target_response_error: bool,
 | 
			
		||||
    #[bit(25, rw)]
 | 
			
		||||
    adma_error: bool,
 | 
			
		||||
    #[bit(24, rw)]
 | 
			
		||||
    auto_cmd12_error: bool,
 | 
			
		||||
    #[bit(23, rw)]
 | 
			
		||||
    current_limit_error: bool,
 | 
			
		||||
    #[bit(22, rw)]
 | 
			
		||||
    data_end_bit_error: bool,
 | 
			
		||||
    #[bit(21, rw)]
 | 
			
		||||
    data_crc_error: bool,
 | 
			
		||||
    #[bit(20, rw)]
 | 
			
		||||
    data_timeout_error: bool,
 | 
			
		||||
    #[bit(19, rw)]
 | 
			
		||||
    command_index_error: bool,
 | 
			
		||||
    #[bit(18, rw)]
 | 
			
		||||
    command_end_bit_error: bool,
 | 
			
		||||
    #[bit(17, rw)]
 | 
			
		||||
    command_crc_error: bool,
 | 
			
		||||
    #[bit(16, rw)]
 | 
			
		||||
    command_timeout_error: bool,
 | 
			
		||||
    #[bit(15, rw)]
 | 
			
		||||
    error_interrupt: bool,
 | 
			
		||||
    #[bit(10, rw)]
 | 
			
		||||
    boot_terminate: bool,
 | 
			
		||||
    #[bit(9, rw)]
 | 
			
		||||
    boot_ack_recv: bool,
 | 
			
		||||
    #[bit(8, rw)]
 | 
			
		||||
    card_interrupt: bool,
 | 
			
		||||
    #[bit(7, rw)]
 | 
			
		||||
    card_removal: bool,
 | 
			
		||||
    #[bit(6, rw)]
 | 
			
		||||
    card_insertion: bool,
 | 
			
		||||
    #[bit(5, rw)]
 | 
			
		||||
    buffer_read_ready: bool,
 | 
			
		||||
    #[bit(4, rw)]
 | 
			
		||||
    buffer_write_ready: bool,
 | 
			
		||||
    #[bit(3, rw)]
 | 
			
		||||
    dma_interrupt: bool,
 | 
			
		||||
    #[bit(2, rw)]
 | 
			
		||||
    blockgap_event: bool,
 | 
			
		||||
    #[bit(1, rw)]
 | 
			
		||||
    transfer_complete: bool,
 | 
			
		||||
    #[bit(0, rw)]
 | 
			
		||||
    command_complete: bool,
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(derive_mmio::Mmio)]
 | 
			
		||||
#[repr(C)]
 | 
			
		||||
pub struct Registers {
 | 
			
		||||
    sdma_system_addr: u32,
 | 
			
		||||
    block_params: u32,
 | 
			
		||||
    /// Bit 39-8 of Command-Format.
 | 
			
		||||
    argument: u32,
 | 
			
		||||
    transfer_mode_and_command: TransferModeAndCommand,
 | 
			
		||||
    #[mmio(PureRead)]
 | 
			
		||||
    responses: [u32; 4],
 | 
			
		||||
    buffer_data_port: u32,
 | 
			
		||||
    #[mmio(PureRead)]
 | 
			
		||||
    present_state: PresentState,
 | 
			
		||||
    host_power_blockgap_wakeup_control: HostPowerBlockgapWakeupControl,
 | 
			
		||||
    clock_timeout_sw_reset_control: ClockAndTimeoutAndSwResetControl,
 | 
			
		||||
    interrupt_status: InterruptStatus,
 | 
			
		||||
    interrupt_status_enable: InterruptMask,
 | 
			
		||||
    interrupt_signal_enable: InterruptMask,
 | 
			
		||||
    #[mmio(PureRead)]
 | 
			
		||||
    auto_cmd12_error_status: u32,
 | 
			
		||||
    #[mmio(PureRead)]
 | 
			
		||||
    capabilities: u32,
 | 
			
		||||
    _reserved_0: u32,
 | 
			
		||||
    #[mmio(PureRead)]
 | 
			
		||||
    maximum_current_capabilities: u32,
 | 
			
		||||
    _reserved_1: u32,
 | 
			
		||||
    force_event_register: u32,
 | 
			
		||||
    adma_error_status: u32,
 | 
			
		||||
    adma_system_address: u32,
 | 
			
		||||
    _reserved_2: u32,
 | 
			
		||||
    boot_timeout_control: u32,
 | 
			
		||||
    debug_selection: u32,
 | 
			
		||||
    _reserved_3: [u32; 0x22],
 | 
			
		||||
    spi_interrupt_support: u32,
 | 
			
		||||
    _reserved_4: [u32; 0x2],
 | 
			
		||||
    slot_interrupt_status_host_controll_version: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x100);
 | 
			
		||||
		Reference in New Issue
	
	Block a user