1 /* 2 * PROJECT: FreeLoader 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: ATA/ATAPI programmed I/O driver header file. 5 * COPYRIGHT: Copyright 2019-2020 Dmitry Borisov (di.sean@protonmail.com) 6 */ 7 8 /* GLOBALS ********************************************************************/ 9 10 /* Some definitions were taken from UniATA driver by Alter */ 11 12 /* 13 * IDE registers offsets 14 */ 15 #if defined(SARCH_PC98) 16 #define IDX_IO1_i_Data 0x00 17 #define IDX_IO1_i_Error 0x02 18 #define IDX_IO1_i_BlockCount 0x04 19 #define IDX_IO1_i_BlockNumber 0x06 20 #define IDX_IO1_i_CylinderLow 0x08 21 #define IDX_IO1_i_CylinderHigh 0x0A 22 #define IDX_IO1_i_DriveSelect 0x0C 23 #define IDX_IO1_i_Status 0x0E 24 25 #define IDX_IO2_i_AltStatus 0x10C 26 #define IDX_IO2_i_DriveAddress 0x10E 27 #define IDE_IO_i_Bank 0x432 28 29 #define IDX_IO1_o_Data 0x00 30 #define IDX_IO1_o_Feature 0x02 31 #define IDX_IO1_o_BlockCount 0x04 32 #define IDX_IO1_o_BlockNumber 0x06 33 #define IDX_IO1_o_CylinderLow 0x08 34 #define IDX_IO1_o_CylinderHigh 0x0A 35 #define IDX_IO1_o_DriveSelect 0x0C 36 #define IDX_IO1_o_Command 0x0E 37 38 #define IDX_IO2_o_Control 0x10C 39 #define IDE_IO_o_BankSelect 0x432 40 #else /* SARCH_PC98 */ 41 #define IDX_IO1_i_Data 0x00 42 #define IDX_IO1_i_Error 0x01 43 #define IDX_IO1_i_BlockCount 0x02 44 #define IDX_IO1_i_BlockNumber 0x03 45 #define IDX_IO1_i_CylinderLow 0x04 46 #define IDX_IO1_i_CylinderHigh 0x05 47 #define IDX_IO1_i_DriveSelect 0x06 48 #define IDX_IO1_i_Status 0x07 49 50 #define IDX_IO2_i_AltStatus 0x206 51 #define IDX_IO2_i_DriveAddress 0x207 52 53 #define IDX_IO1_o_Data 0x00 54 #define IDX_IO1_o_Feature 0x01 55 #define IDX_IO1_o_BlockCount 0x02 56 #define IDX_IO1_o_BlockNumber 0x03 57 #define IDX_IO1_o_CylinderLow 0x04 58 #define IDX_IO1_o_CylinderHigh 0x05 59 #define IDX_IO1_o_DriveSelect 0x06 60 #define IDX_IO1_o_Command 0x07 61 62 #define IDX_IO2_o_Control 0x206 63 #endif 64 65 /* 66 * ATAPI registers offsets 67 */ 68 #if defined(SARCH_PC98) 69 #define IDX_ATAPI_IO1_i_Data 0x00 70 #define IDX_ATAPI_IO1_i_Error 0x02 71 #define IDX_ATAPI_IO1_i_InterruptReason 0x04 72 #define IDX_ATAPI_IO1_i_Unused1 0x06 73 #define IDX_ATAPI_IO1_i_ByteCountLow 0x08 74 #define IDX_ATAPI_IO1_i_ByteCountHigh 0x0A 75 #define IDX_ATAPI_IO1_i_DriveSelect 0x0C 76 #define IDX_ATAPI_IO1_i_Status 0x0E 77 78 #define IDX_ATAPI_IO1_o_Data 0x00 79 #define IDX_ATAPI_IO1_o_Feature 0x02 80 #define IDX_ATAPI_IO1_o_Unused0 0x04 81 #define IDX_ATAPI_IO1_o_Unused1 0x06 82 #define IDX_ATAPI_IO1_o_ByteCountLow 0x08 83 #define IDX_ATAPI_IO1_o_ByteCountHigh 0x0A 84 #define IDX_ATAPI_IO1_o_DriveSelect 0x0C 85 #define IDX_ATAPI_IO1_o_Command 0x0E 86 #else /* SARCH_PC98 */ 87 #define IDX_ATAPI_IO1_i_Data 0x00 88 #define IDX_ATAPI_IO1_i_Error 0x01 89 #define IDX_ATAPI_IO1_i_InterruptReason 0x02 90 #define IDX_ATAPI_IO1_i_Unused1 0x03 91 #define IDX_ATAPI_IO1_i_ByteCountLow 0x04 92 #define IDX_ATAPI_IO1_i_ByteCountHigh 0x05 93 #define IDX_ATAPI_IO1_i_DriveSelect 0x06 94 #define IDX_ATAPI_IO1_i_Status 0x07 95 96 #define IDX_ATAPI_IO1_o_Data 0x00 97 #define IDX_ATAPI_IO1_o_Feature 0x01 98 #define IDX_ATAPI_IO1_o_Unused0 0x02 99 #define IDX_ATAPI_IO1_o_Unused1 0x03 100 #define IDX_ATAPI_IO1_o_ByteCountLow 0x04 101 #define IDX_ATAPI_IO1_o_ByteCountHigh 0x05 102 #define IDX_ATAPI_IO1_o_DriveSelect 0x06 103 #define IDX_ATAPI_IO1_o_Command 0x07 104 #endif 105 106 /* 107 * IDE status definitions 108 */ 109 #define IDE_STATUS_SUCCESS 0x00 110 #define IDE_STATUS_ERROR 0x01 111 #define IDE_STATUS_INDEX 0x02 112 #define IDE_STATUS_CORRECTED_ERROR 0x04 113 #define IDE_STATUS_DRQ 0x08 114 #define IDE_STATUS_DSC 0x10 115 #define IDE_STATUS_DMA 0x20 /* DMA ready */ 116 #define IDE_STATUS_DWF 0x20 /* drive write fault */ 117 #define IDE_STATUS_DRDY 0x40 118 #define IDE_STATUS_IDLE 0x50 119 #define IDE_STATUS_BUSY 0x80 120 121 #define IDE_STATUS_WRONG 0xff 122 #define IDE_STATUS_MASK 0xff 123 124 /* 125 * IDE drive select/head definitions 126 */ 127 #define IDE_DRIVE_SELECT 0xA0 128 #define IDE_DRIVE_1 0x00 129 #define IDE_DRIVE_2 0x10 130 #define IDE_DRIVE_SELECT_1 (IDE_DRIVE_SELECT | IDE_DRIVE_1) 131 #define IDE_DRIVE_SELECT_2 (IDE_DRIVE_SELECT | IDE_DRIVE_2) 132 #define IDE_DRIVE_MASK (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2) 133 #define IDE_USE_LBA 0x40 134 135 /* 136 * IDE drive control definitions 137 */ 138 #define IDE_DC_DISABLE_INTERRUPTS 0x02 139 #define IDE_DC_RESET_CONTROLLER 0x04 140 #define IDE_DC_A_4BIT 0x80 141 #define IDE_DC_USE_HOB 0x80 // use high-order byte(s) 142 #define IDE_DC_REENABLE_CONTROLLER 0x00 143 144 /* 145 * IDE error definitions 146 */ 147 #define IDE_ERROR_ICRC 0x80 148 #define IDE_ERROR_BAD_BLOCK 0x80 149 #define IDE_ERROR_DATA_ERROR 0x40 150 #define IDE_ERROR_MEDIA_CHANGE 0x20 151 #define IDE_ERROR_ID_NOT_FOUND 0x10 152 #define IDE_ERROR_MEDIA_CHANGE_REQ 0x08 153 #define IDE_ERROR_COMMAND_ABORTED 0x04 154 #define IDE_ERROR_END_OF_MEDIA 0x02 155 #define IDE_ERROR_NO_MEDIA 0x02 156 #define IDE_ERROR_ILLEGAL_LENGTH 0x01 157 158 /* 159 * Values for TransferMode 160 */ 161 #define ATA_PIO 0x00 162 163 /* 164 * IDENTIFY data 165 */ 166 #include <pshpack1.h> 167 typedef struct _IDENTIFY_DATA 168 { 169 UCHAR AtapiCmdSize:2; // 00 00 General configuration 170 UCHAR Unused1:3; 171 UCHAR DrqType:2; 172 UCHAR Removable:1; 173 UCHAR DeviceType:5; 174 UCHAR Unused2:1; 175 UCHAR CmdProtocol:2; 176 USHORT NumberOfCylinders; // 02 1 177 USHORT Reserved1; // 04 2 178 USHORT NumberOfHeads; // 06 3 179 USHORT UnformattedBytesPerTrack; // 08 4 180 USHORT UnformattedBytesPerSector; // 0A 5 181 USHORT SectorsPerTrack; // 0C 6 182 USHORT VendorUnique1[3]; // 0E 7-9 183 USHORT SerialNumber[10]; // 14 10-19 184 USHORT BufferType; // 28 20 185 USHORT BufferSectorSize; // 2A 21 186 USHORT NumberOfEccBytes; // 2C 22 187 USHORT FirmwareRevision[4]; // 2E 23-26 188 USHORT ModelNumber[20]; // 36 27-46 189 UCHAR ReadWriteMultipleSupport; // 5E 47 190 UCHAR VendorUnique2; // 5F 191 USHORT DoubleWordIo; // 60 48 192 USHORT Reserved62_0:8; // 62 49 Capabilities 193 USHORT SupportDma:1; 194 USHORT SupportLba:1; 195 USHORT DisableIordy:1; 196 USHORT SupportIordy:1; 197 USHORT SoftReset:1; 198 USHORT StandbyOverlap:1; 199 USHORT SupportQTag:1; 200 USHORT SupportIDma:1; 201 USHORT Reserved2; // 64 50 202 UCHAR VendorUnique3; // 66 51 203 UCHAR PioCycleTimingMode; // 67 204 UCHAR VendorUnique4; // 68 52 205 UCHAR DmaCycleTimingMode; // 69 206 USHORT TranslationFieldsValid:1; // 6A 53 207 USHORT Reserved3:15; 208 USHORT NumberOfCurrentCylinders; // 6C 54 209 USHORT NumberOfCurrentHeads; // 6E 55 210 USHORT CurrentSectorsPerTrack; // 70 56 211 ULONG CurrentSectorCapacity; // 72 57-58 212 USHORT CurrentMultiSectorSetting; // 59 213 ULONG UserAddressableSectors; // 60-61 214 USHORT SingleWordDMASupport:8; // 62 215 USHORT SingleWordDMAActive:8; 216 USHORT MultiWordDMASupport:8; // 63 217 USHORT MultiWordDMAActive:8; 218 USHORT AdvancedPIOModes:8; // 64 219 USHORT Reserved4:8; 220 USHORT MinimumMWXferCycleTime; // 65 221 USHORT RecommendedMWXferCycleTime; // 66 222 USHORT MinimumPIOCycleTime; // 67 223 USHORT MinimumPIOCycleTimeIORDY; // 68 224 USHORT Reserved5[2]; // 69-70 225 USHORT ReleaseTimeOverlapped; // 71 226 USHORT ReleaseTimeServiceCommand; // 72 227 USHORT Reserved73_74[2]; // 73-74 228 USHORT QueueLength:5; // 75 229 USHORT Reserved75_6:11; 230 USHORT SataCapabilities; // 76 231 USHORT Reserved77; // 77 232 USHORT SataSupport; // 78 233 USHORT SataEnable; // 79 234 USHORT MajorRevision; // 80 235 USHORT MinorRevision; // 81 236 struct { 237 USHORT Smart:1; // 82 238 USHORT Security:1; 239 USHORT Removable:1; 240 USHORT PowerMngt:1; 241 USHORT Packet:1; 242 USHORT WriteCache:1; 243 USHORT LookAhead:1; 244 USHORT ReleaseDRQ:1; 245 USHORT ServiceDRQ:1; 246 USHORT Reset:1; 247 USHORT Protected:1; 248 USHORT Reserved_82_11:1; 249 USHORT WriteBuffer:1; 250 USHORT ReadBuffer:1; 251 USHORT Nop:1; 252 USHORT Reserved_82_15:1; 253 USHORT Microcode:1; // 83/86 254 USHORT Queued:1; 255 USHORT CFA:1; 256 USHORT APM:1; 257 USHORT Notify:1; 258 USHORT Standby:1; 259 USHORT Spinup:1; 260 USHORT Reserver_83_7:1; 261 USHORT MaxSecurity:1; 262 USHORT AutoAcoustic:1; 263 USHORT Address48:1; 264 USHORT ConfigOverlay:1; 265 USHORT FlushCache:1; 266 USHORT FlushCache48:1; 267 USHORT SupportOne:1; 268 USHORT SupportZero:1; 269 USHORT SmartErrorLog:1; // 84/87 270 USHORT SmartSelfTest:1; 271 USHORT MediaSerialNo:1; 272 USHORT MediaCardPass:1; 273 USHORT Streaming:1; 274 USHORT Logging:1; 275 USHORT Reserver_84_6:8; 276 USHORT ExtendedOne:1; 277 USHORT ExtendedZero:1; 278 } FeaturesSupport, FeaturesEnabled; 279 USHORT Reserved6[13]; // 88-99 280 ULONGLONG UserAddressableSectors48; // 100-103 281 USHORT Reserved7[151]; // 104-255 282 } IDENTIFY_DATA, *PIDENTIFY_DATA; 283 #include <poppack.h> 284 #define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA) 285 286 #define ATAPI_MAGIC_LSB 0x14 287 #define ATAPI_MAGIC_MSB 0xEB 288 #define MAXIMUM_CDROM_SIZE 804 289 290 typedef struct _DEVICE_UNIT 291 { 292 UCHAR Channel; 293 UCHAR DeviceNumber; 294 ULONG Cylinders; 295 ULONG Heads; 296 ULONG Sectors; 297 ULONG SectorSize; 298 ULONGLONG TotalSectors; /* This number starts from 0 */ 299 USHORT Flags; 300 IDENTIFY_DATA IdentifyData; 301 } DEVICE_UNIT, *PDEVICE_UNIT; 302 303 #define ATA_DEVICE_ATAPI (1 << 0) 304 #define ATA_DEVICE_NO_MEDIA (1 << 1) 305 #define ATA_DEVICE_NOT_READY (1 << 2) 306 #define ATA_DEVICE_LBA48 (1 << 3) 307 #define ATA_DEVICE_LBA (1 << 4) 308 #define ATA_DEVICE_CHS (1 << 5) 309 310 /* PROTOTYPES ****************************************************************/ 311 312 BOOLEAN 313 AtaInit( 314 OUT PUCHAR DetectedCount 315 ); 316 317 VOID 318 AtaFree(); 319 320 PDEVICE_UNIT 321 AtaGetDevice( 322 IN UCHAR UnitNumber 323 ); 324 325 BOOLEAN 326 AtaAtapiReadLogicalSectorsLBA( 327 IN OUT PDEVICE_UNIT DeviceUnit, 328 IN ULONGLONG SectorNumber, 329 IN ULONG SectorCount, 330 OUT PVOID Buffer 331 ); 332