1 /* 2 * Copyright 2007, Marcus Overhagen. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _AHCI_DEFS_H 6 #define _AHCI_DEFS_H 7 8 #include <bus/PCI.h> 9 #include <bus/SCSI.h> 10 #include <PCI_x86.h> 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 #define AHCI_DEVICE_MODULE_NAME "busses/scsi/ahci/driver_v1" 17 #define AHCI_SIM_MODULE_NAME "busses/scsi/ahci/sim/driver_v1" 18 19 // RW1 = Write 1 to set bit (writing 0 is ignored) 20 // RWC = Write 1 to clear bit (writing 0 is ignored) 21 22 23 enum { 24 CAP_S64A = (1 << 31), // Supports 64-bit Addressing 25 CAP_SNCQ = (1 << 30), // Supports Native Command Queuing 26 CAP_SSNTF = (1 << 29), // Supports SNotification Register 27 CAP_SMPS = (1 << 28), // Supports Mechanical Presence Switch 28 CAP_SSS = (1 << 27), // Supports Staggered Spin-up 29 CAP_SALP = (1 << 26), // Supports Aggressive Link Power Management 30 CAP_SAL = (1 << 25), // Supports Activity LED 31 CAP_SCLO = (1 << 24), // Supports Command List Override 32 CAP_ISS_MASK = 0xf, // Interface Speed Support 33 CAP_ISS_SHIFT = 20, 34 CAP_SNZO = (1 << 19), // Supports Non-Zero DMA Offsets 35 CAP_SAM = (1 << 18), // Supports AHCI mode only 36 CAP_SPM = (1 << 17), // Supports Port Multiplier 37 CAP_FBSS = (1 << 16), // FIS-based Switching Supported 38 CAP_PMD = (1 << 15), // PIO Multiple DRQ Block 39 CAP_SSC = (1 << 14), // Slumber State Capable 40 CAP_PSC = (1 << 13), // Partial State Capable 41 CAP_NCS_MASK = 0x1f, // Number of Command Slots (zero-based number) 42 CAP_NCS_SHIFT = 8, 43 CAP_CCCS = (1 << 7), // Command Completion Coalescing Supported 44 CAP_EMS = (1 << 6), // Enclosure Management Supported 45 CAP_SXS = (1 << 5), // Supports External SATA 46 CAP_NP_MASK = 0x1f, // Number of Ports (zero-based number) 47 CAP_NP_SHIFT = 0, 48 }; 49 50 51 enum { 52 GHC_AE = (1 << 31), // AHCI Enable 53 GHC_MRSM = (1 << 2), // MSI Revert to Single Message 54 GHC_IE = (1 << 1), // Interrupt Enable 55 GHC_HR = (1 << 0), // HBA Reset **RW1** 56 }; 57 58 59 enum { 60 INT_CPD = (1 << 31), // Cold Port Detect Status/Enable 61 INT_TFE = (1 << 30), // Task File Error Status/Enable 62 INT_HBF = (1 << 29), // Host Bus Fatal Error Status/Enable 63 INT_HBD = (1 << 28), // Host Bus Data Error Status/Enable 64 INT_IF = (1 << 27), // Interface Fatal Error Status/Enable 65 INT_INF = (1 << 26), // Interface Non-fatal Error Status/Enable 66 INT_OF = (1 << 24), // Overflow Status/Enable 67 INT_IPM = (1 << 23), // Incorrect Port Multiplier Status/Enable 68 INT_PRC = (1 << 22), // PhyRdy Change Status/Enable 69 INT_DMP = (1 << 7), // Device Mechanical Presence Status/Enable 70 INT_PC = (1 << 6), // Port Change Interrupt Status/Enable 71 INT_DP = (1 << 5), // Descriptor Processed Interrupt/Enable 72 INT_UF = (1 << 4), // Unknown FIS Interrupt/Enable 73 INT_SDB = (1 << 3), // Set Device Bits Interrupt/Enable 74 INT_DS = (1 << 2), // DMA Setup FIS Interrupt/Enable 75 INT_PS = (1 << 1), // PIO Setup FIS Interrupt/Enable 76 INT_DHR = (1 << 0), // Device to Host Register FIS Interrupt/Enable 77 }; 78 79 80 typedef struct { 81 uint32 clb; // Command List Base Address (alignment 1024 byte) 82 uint32 clbu; // Command List Base Address Upper 32-Bits 83 uint32 fb; // FIS Base Address (alignment 256 byte) 84 uint32 fbu; // FIS Base Address Upper 32-Bits 85 uint32 is; // Interrupt Status **RWC** 86 uint32 ie; // Interrupt Enable 87 uint32 cmd; // Command and Status 88 uint32 res1; // Reserved 89 uint32 tfd; // Task File Data 90 uint32 sig; // Signature 91 uint32 ssts; // Serial ATA Status (SCR0: SStatus) 92 uint32 sctl; // Serial ATA Control (SCR2: SControl) 93 uint32 serr; // Serial ATA Error (SCR1: SError) **RWC** 94 uint32 sact; // Serial ATA Active (SCR3: SActive) **RW1** 95 uint32 ci; // Command Issue **RW1** 96 uint32 sntf; // SNotification 97 uint32 res2; // Reserved for FIS-based Switching Definition 98 uint32 res[11]; // Reserved 99 uint32 vendor[4]; // Vendor Specific 100 } _PACKED ahci_port; 101 102 103 enum { 104 PORT_CMD_ICC_ACTIVE = (1 << 28), // Interface Communication control 105 PORT_CMD_ICC_SLUMBER = (6 << 28), // Interface Communication control 106 PORT_CMD_ICC_MASK = (0xf<<28), // Interface Communication control 107 PORT_CMD_ATAPI = (1 << 24), // Device is ATAPI 108 PORT_CMD_CR = (1 << 15), // Command List Running (DMA active) 109 PORT_CMD_FR = (1 << 14), // FIS Receive Running 110 PORT_CMD_FER = (1 << 4), // FIS Receive Enable 111 PORT_CMD_CLO = (1 << 3), // Command List Override 112 PORT_CMD_POD = (1 << 2), // Power On Device 113 PORT_CMD_SUD = (1 << 1), // Spin-up Device 114 PORT_CMD_ST = (1 << 0), // Start DMA 115 }; 116 117 118 enum { 119 PORT_INT_CPD = (1 << 31), // Cold Presence Detect Status/Enable 120 PORT_INT_TFE = (1 << 30), // Task File Error Status/Enable 121 PORT_INT_HBF = (1 << 29), // Host Bus Fatal Error Status/Enable 122 PORT_INT_HBD = (1 << 28), // Host Bus Data Error Status/Enable 123 PORT_INT_IF = (1 << 27), // Interface Fatal Error Status/Enable 124 PORT_INT_INF = (1 << 26), // Interface Non-fatal Error Status/Enable 125 PORT_INT_OF = (1 << 24), // Overflow Status/Enable 126 PORT_INT_IPM = (1 << 23), // Incorrect Port Multiplier Status/Enable 127 PORT_INT_PRC = (1 << 22), // PhyRdy Change Status/Enable 128 PORT_INT_DI = (1 << 7), // Device Interlock Status/Enable 129 PORT_INT_PC = (1 << 6), // Port Change Status/Enable 130 PORT_INT_DP = (1 << 5), // Descriptor Processed Interrupt 131 PORT_INT_UF = (1 << 4), // Unknown FIS Interrupt 132 PORT_INT_SDB = (1 << 3), // Set Device Bits FIS Interrupt 133 PORT_INT_DS = (1 << 2), // DMA Setup FIS Interrupt 134 PORT_INT_PS = (1 << 1), // PIO Setup FIS Interrupt 135 PORT_INT_DHR = (1 << 0), // Device to Host Register FIS Interrupt 136 }; 137 138 #define PORT_INT_ERROR (PORT_INT_TFE | PORT_INT_HBF | PORT_INT_HBD \ 139 | PORT_INT_IF | PORT_INT_INF | PORT_INT_OF \ 140 | PORT_INT_IPM | PORT_INT_PRC | PORT_INT_PC \ 141 | PORT_INT_UF) 142 143 #define PORT_INT_MASK (PORT_INT_ERROR | PORT_INT_DP | PORT_INT_SDB \ 144 | PORT_INT_DS | PORT_INT_PS | PORT_INT_DHR) 145 146 enum { 147 ATA_BSY = 0x80, 148 ATA_DF = 0x20, 149 ATA_DRQ = 0x08, 150 ATA_ERR = 0x01, 151 }; 152 153 154 typedef struct { 155 uint32 cap; // Host Capabilities 156 uint32 ghc; // Global Host Control 157 uint32 is; // Interrupt Status 158 uint32 pi; // Ports Implemented 159 uint32 vs; // Version 160 uint32 ccc_ctl; // Command Completion Coalescing Control 161 uint32 ccc_ports; // Command Completion Coalsecing Ports 162 uint32 em_loc; // Enclosure Management Location 163 uint32 em_ctl; // Enclosure Management Control 164 uint32 res[31]; // Reserved 165 uint32 vendor[24]; // Vendor Specific registers 166 ahci_port port[32]; 167 } _PACKED ahci_hba; 168 169 170 typedef struct { 171 uint8 dsfis[0x1c]; // DMA Setup FIS 172 uint8 res1[0x04]; 173 uint8 psfis[0x14]; // PIO Setup FIS 174 uint8 res2[0x0c]; 175 uint8 rfis[0x14]; // D2H Register FIS 176 uint8 res3[0x04]; 177 uint8 sdbfis[0x08]; // Set Device Bits FIS 178 uint8 ufis[0x40]; // Unknown FIS 179 uint8 res4[0x60]; 180 } _PACKED fis; 181 182 183 typedef struct { 184 union { 185 struct { 186 uint16 cfl : 5; // command FIS length 187 uint16 a : 1; // ATAPI 188 uint16 w : 1; // Write 189 uint16 p : 1; // Prefetchable 190 uint16 r : 1; // Reset 191 uint16 b : 1; // Build In Self Test 192 uint16 c : 1; // Clear Busy upon R_OK 193 uint16 : 1; 194 uint16 pmp : 4; // Port Multiplier Port 195 uint16 prdtl; // physical region description table length; 196 } _PACKED; 197 uint32 prdtl_flags_cfl; 198 } _PACKED; 199 uint32 prdbc; // PRD Byte Count 200 uint32 ctba; // command table desciptor base address 201 // (alignment 128 byte) 202 uint32 ctbau; // command table desciptor base address upper 203 uint8 res1[0x10]; 204 } _PACKED command_list_entry; 205 206 #define COMMAND_LIST_ENTRY_COUNT 32 207 208 209 // Command FIS layout - Host to Device (H2D) 210 // 0 - FIS Type (0x27) 211 // 1 - C bit (0x80) 212 // 2 - Command 213 // 3 - Features 214 // 4 - Sector Number (LBA Low, bits 0-7) 215 // 5 - Cylinder Low (LBA Mid, bits 8-15) 216 // 6 - Cylinder High (LBA High, bits 16-23) 217 // 7 - Device / Head (for 28-bit LBA commands, bits 24-27) 218 // 8 - Sector Number expanded (LBA Low-previous, bits 24-31) 219 // 9 - Cylinder Low expanded (LBA Mid-previous, bits 32-39) 220 // 10 - Cylinder High expanded (LBA High-previous, bits 40-47) 221 // 11 - Features expanded 222 // 12 - Sector Count (Sector count, bits 0-7) 223 // 13 - Sector Count expanded (Sector count, bits 8-15) 224 // 14 - Reserved (0) 225 // 15 - Control 226 // 16 - Reserved (0) 227 // 17 - Reserved (0) 228 // 18 - Reserved (0) 229 // 19 - Reserved (0) 230 typedef struct { 231 uint8 cfis[0x40]; // command FIS 232 uint8 acmd[0x20]; // ATAPI command 233 uint8 res[0x20]; // reserved 234 } _PACKED command_table; 235 236 237 typedef struct { 238 uint32 dba; // Data Base Address (2-byte aligned) 239 uint32 dbau; // Data Base Address Upper 240 uint32 res; 241 uint32 dbc; // Bytecount (0-based, even, max 4MB) 242 #define DBC_I 0x80000000 /* Interrupt on completition */ 243 } _PACKED prd; 244 245 #define PRD_TABLE_ENTRY_COUNT 168 246 #define PRD_MAX_DATA_LENGTH 0x400000 /* 4 MB */ 247 248 249 typedef struct { 250 uint16 vendor; 251 uint16 device; 252 const char *name; 253 uint32 flags; 254 } device_info; 255 256 status_t get_device_info(uint16 vendorID, uint16 deviceID, const char **name, 257 uint32 *flags); 258 259 260 extern scsi_sim_interface gAHCISimInterface; 261 extern device_manager_info *gDeviceManager; 262 extern scsi_for_sim_interface *gSCSI; 263 extern pci_x86_module_info* gPCIx86Module; 264 265 266 #define MAX_SECTOR_LBA_28 ((1ull << 28) - 1) 267 #define MAX_SECTOR_LBA_48 ((1ull << 48) - 1) 268 269 270 #define LO32(val) ((uint32)(addr_t)(val)) 271 #define HI32(val) ((uint32)(((uint64)(addr_t)(val)) >> 32)) 272 #define ASSERT(expr) if (expr) {} else panic(#expr) 273 274 #define PCI_VENDOR_INTEL 0x8086 275 #define PCI_VENDOR_JMICRON 0x197b 276 #define PCI_JMICRON_CONTROLLER_CONTROL_1 0x40 277 278 #ifdef __cplusplus 279 } 280 #endif 281 282 #ifdef __cplusplus 283 284 template <class T> 285 int count_bits_set(T value) 286 { 287 int count = 0; 288 for (T mask = 1; mask; mask <<= 1) 289 if (value & mask) 290 count++; 291 return count; 292 } 293 294 inline 295 status_t 296 wait_until_set(volatile uint32 *reg, uint32 bits, bigtime_t timeout) 297 { 298 int trys = (timeout + 9999) / 10000; 299 while (trys--) { 300 if (((*reg) & bits) == bits) 301 return B_OK; 302 snooze(10000); 303 } 304 return B_TIMED_OUT; 305 } 306 307 inline 308 status_t 309 wait_until_clear(volatile uint32 *reg, uint32 bits, bigtime_t timeout) 310 { 311 int trys = (timeout + 9999) / 10000; 312 while (trys--) { 313 if (((*reg) & bits) == 0) 314 return B_OK; 315 snooze(10000); 316 } 317 return B_TIMED_OUT; 318 } 319 320 #endif /* __cplusplus */ 321 322 #endif /* _AHCI_DEFS_H */ 323