1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
//! Frame Information Structures //! //! A FIS is a packet or frame of information that is transferred between the host and device. //! Refer to the Serial ATA specification for more information. #![allow(clippy::missing_docs_in_private_items)] // just read the spec, ok !? use sunrise_libuser::io::Mmio; /// The types of a FIS. /// /// Stored on byte 0 of every FIS, determines the length of the structure to be read. #[repr(u8)] pub enum FisType { /// Register FIS - host to device RegH2D = 0x27, /// Register FIS - device to host RegD2H = 0x34, /// DMA activate FIS - device to host DmaAct = 0x39, /// DMA setup FIS - bidirectional DmaSetup = 0x41, /// Data FIS - bidirectional Data = 0x46, /// BIST activate FIS - bidirectional Bist = 0x58, /// PIO setup FIS - device to host PioSetup = 0x5F, /// Set device bits FIS - device to host DevBits = 0xA1 } /// Register FIS - host to device /// /// `fis_type` must be set to 0x27. #[repr(packed)] pub struct FisRegH2D { // DWORD 0 pub fis_type: Mmio<u8>, // FIS_TYPE_REG_H2D pub pm: Mmio<u8>, // Port multiplier, 1: Command, 0: Control pub command: Mmio<u8>, // Command register pub featurel: Mmio<u8>, // Feature register, 7:0 // DWORD 1 pub lba0: Mmio<u8>, // LBA low register, 7:0 pub lba1: Mmio<u8>, // LBA mid register, 15:8 pub lba2: Mmio<u8>, // LBA high register, 23:16 pub device: Mmio<u8>, // Device register // DWORD 2 pub lba3: Mmio<u8>, // LBA register, 31:24 pub lba4: Mmio<u8>, // LBA register, 39:32 pub lba5: Mmio<u8>, // LBA register, 47:40 pub featureh: Mmio<u8>, // Feature register, 15:8 // DWORD 3 pub countl: Mmio<u8>, // Count register, 7:0 pub counth: Mmio<u8>, // Count register, 15:8 pub icc: Mmio<u8>, // Isochronous command completion pub control: Mmio<u8>, // Control register // DWORD 4 pub rsv1: [Mmio<u8>; 4], // Reserved } /// Register FIS - device to host #[repr(packed)] pub struct FisRegD2H { // DWORD 0 pub fis_type: Mmio<u8>, // FIS_TYPE_REG_D2H pub pm: Mmio<u8>, // Port multiplier, Interrupt bit: 2 pub status: Mmio<u8>, // Status register pub error: Mmio<u8>, // Error register // DWORD 1 pub lba0: Mmio<u8>, // LBA low register, 7:0 pub lba1: Mmio<u8>, // LBA mid register, 15:8 pub lba2: Mmio<u8>, // LBA high register, 23:16 pub device: Mmio<u8>, // Device register // DWORD 2 pub lba3: Mmio<u8>, // LBA register, 31:24 pub lba4: Mmio<u8>, // LBA register, 39:32 pub lba5: Mmio<u8>, // LBA register, 47:40 pub rsv2: Mmio<u8>, // Reserved // DWORD 3 pub countl: Mmio<u8>, // Count register, 7:0 pub counth: Mmio<u8>, // Count register, 15:8 pub rsv3: [Mmio<u8>; 2], // Reserved // DWORD 4 pub rsv4: [Mmio<u8>; 4], // Reserved } /// Data FIS - bidirectional #[repr(packed)] pub struct FisData { // DWORD 0 pub fis_type: Mmio<u8>, // FIS_TYPE_DATA pub pm: Mmio<u8>, // Port multiplier pub rsv1: [Mmio<u8>; 2], // Reserved // DWORD 1 ~ N pub data: [Mmio<u8>; 252], // Payload } /// PIO setup FIS - device to host #[repr(packed)] pub struct FisPioSetup { // DWORD 0 pub fis_type: Mmio<u8>, // FIS_TYPE_PIO_SETUP pub pm: Mmio<u8>, // Port multiplier, direction: 4 - device to host, interrupt: 2 pub status: Mmio<u8>, // Status register pub error: Mmio<u8>, // Error register // DWORD 1 pub lba0: Mmio<u8>, // LBA low register, 7:0 pub lba1: Mmio<u8>, // LBA mid register, 15:8 pub lba2: Mmio<u8>, // LBA high register, 23:16 pub device: Mmio<u8>, // Device register // DWORD 2 pub lba3: Mmio<u8>, // LBA register, 31:24 pub lba4: Mmio<u8>, // LBA register, 39:32 pub lba5: Mmio<u8>, // LBA register, 47:40 pub rsv2: Mmio<u8>, // Reserved // DWORD 3 pub countl: Mmio<u8>, // Count register, 7:0 pub counth: Mmio<u8>, // Count register, 15:8 pub rsv3: Mmio<u8>, // Reserved pub e_status: Mmio<u8>, // New value of status register // DWORD 4 pub tc: Mmio<u16>, // Transfer count pub rsv4: [Mmio<u8>; 2], // Reserved } /// DMA setup FIS - bidirectional #[repr(packed)] pub struct FisDmaSetup { // DWORD 0 pub fis_type: Mmio<u8>, // FIS_TYPE_DMA_SETUP pub pm: Mmio<u8>, // Port multiplier, direction: 4 - device to host, interrupt: 2, auto-activate: 1 pub rsv1: [Mmio<u8>; 2], // Reserved // DWORD 1&2 pub dma_buffer_id: Mmio<u64>, /* DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. */ // DWORD 3 pub rsv3: Mmio<u32>, // More reserved // DWORD 4 pub dma_buffer_offset: Mmio<u32>, // Byte offset into buffer. First 2 bits must be 0 // DWORD 5 pub transfer_count: Mmio<u32>, // Number of bytes to transfer. Bit 0 must be 0 // DWORD 6 pub rsv6: Mmio<u32>, // Reserved } /// Set device bits FIS - device to host #[repr(packed)] pub struct FisSetDeviceBits { // DWORD 0 pub fis_type: Mmio<u8>, // FIS_TYPE_DMA_SETUP pub i: Mmio<u8>, // interrupt bit, 6 pub status: Mmio<u8>, // status hi 6:4, status lo 2:0 pub error: Mmio<u8>, // error 7:0 // DWORD 1 pub _rsv: Mmio<u32>, // Reserved }