1 /* 2 * 3 * Copyright (C) 2012 secunet Security Networks AG 4 * Copyright (C) 2013 Edward O'Callaghan <[email protected]> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifndef _AHCI_PRIVATE_H 31 #define _AHCI_PRIVATE_H 32 33 #include <stdint.h> 34 #include <storage/ata.h> 35 #include <storage/atapi.h> 36 37 typedef volatile struct { 38 u64 cmdlist_base; 39 u64 frameinfo_base; 40 u32 intr_status; 41 u32 intr_enable; 42 u32 cmd_stat; 43 u32 _reserved0; 44 u32 taskfile_data; 45 u32 signature; 46 u32 sata_status; 47 u32 sata_control; 48 u32 sata_error; 49 u32 sata_active; 50 u32 cmd_issue; 51 u32 sata_notify; 52 u32 fis_based_switch; 53 u32 _reserved1[11]; 54 u32 _vendor[4]; 55 } hba_port_t; 56 57 #define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */ 58 #define HBA_PxIS_HBFS (1 << 29) /* HBFS - Host Bus Fatal Error Status */ 59 #define HBA_PxIS_HBDS (1 << 28) /* HBDS - Host Bus Data Error Status */ 60 #define HBA_PxIS_IFS (1 << 27) /* IFS - Interface Fatal Error Status */ 61 #define HBA_PxIS_FATAL (HBA_PxIS_TFES | HBA_PxIS_HBFS | \ 62 HBA_PxIS_HBDS | HBA_PxIS_IFS) 63 #define HBA_PxIS_PCS (1 << 6) /* PCS - Port Connect Change Status */ 64 65 #define HBA_PxCMD_ICC_SHIFT 28 66 #define HBA_PxCMD_ICC_MASK (0xf << HBA_PxCMD_ICC_SHIFT) 67 #define HBA_PxCMD_ICC_ACTIVE (0x1 << HBA_PxCMD_ICC_SHIFT) 68 #define HBA_PxCMD_CR (1 << 15) /* CR - Command list Running */ 69 #define HBA_PxCMD_FR (1 << 14) /* FR - FIS receive Running */ 70 #define HBA_PxCMD_FRE (1 << 4) /* FRE - FIS Receive Enable */ 71 #define HBA_PxCMD_SUD (1 << 1) /* SUD - Spin-Up Device */ 72 #define HBA_PxCMD_ST (1 << 0) /* ST - Start (command processing) */ 73 74 #define HBA_PxTFD_BSY (1 << 7) 75 #define HBA_PxTFD_DRQ (1 << 3) 76 77 #define HBA_PxSSTS_IPM_SHIFT 8 78 #define HBA_PxSSTS_IPM_MASK (0xf << HBA_PxSSTS_IPM_SHIFT) 79 #define HBA_PxSSTS_IPM_ACTIVE (1 << HBA_PxSSTS_IPM_SHIFT) 80 #define HBA_PxSSTS_DET_SHIFT 0 81 #define HBA_PxSSTS_DET_MASK (0xf << HBA_PxSSTS_DET_SHIFT) 82 #define HBA_PxSSTS_DET_ESTABLISHED (3 << HBA_PxSSTS_DET_SHIFT) 83 84 #define HBA_PxSCTL_DET_SHIFT 0 85 #define HBA_PxSCTL_DET_MASK (0xf << HBA_PxSCTL_DET_SHIFT) 86 #define HBA_PxSCTL_DET_COMRESET (0x1 << HBA_PxSCTL_DET_SHIFT) 87 88 #define HBA_PxSIG_ATA 0x00000101 /* SATA drive */ 89 #define HBA_PxSIG_ATAPI 0xeb140101 /* SATAPI drive */ 90 #define HBA_PxSIG_SEMB 0xc33c0101 /* Enclosure management bridge */ 91 #define HBA_PxSIG_PM 0x96690101 /* Port multiplier */ 92 93 typedef volatile struct { 94 u32 caps; 95 u32 global_ctrl; 96 u32 intr_status; 97 u32 ports_impl; 98 u32 version; 99 u32 ccc_ctrl; /* CCC - Command Completion Coalescing */ 100 u32 ccc_ports; 101 u32 em_location; /* EM - Enclosure Management */ 102 u32 em_ctrl; 103 u32 ext_caps; 104 u32 handoff_ctrl_stat; 105 u32 _reserved0[13]; 106 u32 _reserved_nvmchi[16]; 107 u32 _vendor[24]; 108 hba_port_t ports[32]; 109 } hba_ctrl_t; 110 111 #define HBA_CAPS_SSS (1 << 27) /* SSS - Supports Staggered Spin-up */ 112 #define HBA_CAPS_NCS_SHIFT 8 /* NCS - Number of Command Slots */ 113 #define HBA_CAPS_NCS_MASK (0x1f << HBA_CAPS_NCS_SHIFT) 114 115 #define HBA_CAPS_DECODE_NCS(caps) (((caps & HBA_CAPS_NCS_MASK) \ 116 >> HBA_CAPS_NCS_SHIFT) \ 117 + 1) 118 119 #define HBA_CTRL_AHCI_EN (1 << 31) 120 #define HBA_CTRL_INTR_EN (1 << 1) 121 #define HBA_CTRL_RESET (1 << 0) 122 123 typedef volatile struct { 124 u8 dma_setup_fis[28]; 125 u8 _reserved0[4]; 126 u8 pio_setup_fis[20]; 127 u8 _reserved1[12]; 128 u8 d2h_register_fis[20]; 129 u8 _reserved2[4]; 130 u8 set_device_bits_fis[8]; 131 u8 unknown_fis[64]; 132 u8 _reserved3[96]; 133 } rcvd_fis_t; 134 135 typedef volatile struct { 136 u16 cmd; 137 u16 prdt_length; 138 u32 prd_bytes; 139 u64 cmdtable_base; 140 u8 _reserved[16]; 141 } cmd_t; 142 143 #define CMD_PMP_SHIFT 12 /* PMP - Port Multiplier Port */ 144 #define CMD_PMP_MASK (0xf << CMD_PMP_SHIFT) 145 #define CMD_PMP(x) ((x << CMD_PMP_SHIFT) & CMD_PMP_MASK) 146 #define CMD_CBuROK (1 << 10) /* C - Clear Busy upon R_OK */ 147 #define CMD_BIST (1 << 9) /* B - BIST - Built-In Selft Test */ 148 #define CMD_RESET (1 << 8) /* R - Reset */ 149 #define CMD_PREFETCH (1 << 7) /* P - Prefetch (PRDTs or ATAPI cmd) */ 150 #define CMD_WRITE (1 << 6) /* W - Write (host to device) */ 151 #define CMD_ATAPI (1 << 5) /* A - ATAPI cmd */ 152 #define CMD_CFL_SHIFT 0 /* CFL - Command FIS Length */ 153 #define CMD_CFL_MASK (0xf << CMD_CFL_SHIFT) 154 #define CMD_CFL(x) ((((x) >> 2) << CMD_CFL_SHIFT) & CMD_CFL_MASK) 155 156 typedef volatile struct { 157 u8 fis[64]; 158 u8 atapi_cmd[16]; 159 u8 _reserved0[48]; 160 struct { 161 u64 data_base; 162 u32 _reserved0; 163 u32 flags; 164 } prdt[8]; /* Can be up to 65,535 prds, 165 but implementation needs multiple of 128 bytes. */ 166 } cmdtable_t; 167 168 #define BYTES_PER_PRD_SHIFT 20 169 #define BYTES_PER_PRD (4 << 20) 170 171 enum { 172 FIS_HOST_TO_DEVICE = 0x27, 173 }; 174 #define FIS_H2D_CMD (1 << 7) 175 #define FIS_H2D_FIS_LEN 20 176 #define FIS_H2D_DEV_LBA (1 << 6) 177 178 #define PRD_TABLE_I (1 << 31) /* I - Interrupt on Completion */ 179 #define PRD_TABLE_BYTES_MASK 0x3fffff 180 #define PRD_TABLE_BYTES(x) (((x) - 1) & PRD_TABLE_BYTES_MASK) 181 182 typedef struct { 183 union { 184 ata_dev_t ata_dev; 185 atapi_dev_t atapi_dev; 186 }; 187 188 hba_ctrl_t *ctrl; 189 hba_port_t *port; 190 191 cmd_t *cmdlist; 192 cmdtable_t *cmdtable; 193 rcvd_fis_t *rcvd_fis; 194 195 u8 *buf, *user_buf; 196 int write_back; 197 size_t buflen; 198 } ahci_dev_t; 199 200 /* 201 * ahci_common.c 202 */ 203 int ahci_cmdengine_start(hba_port_t *const port); 204 205 int ahci_cmdengine_stop(hba_port_t *const port); 206 207 ssize_t ahci_cmdslot_exec(ahci_dev_t *const dev); 208 209 size_t ahci_cmdslot_prepare(ahci_dev_t *const dev, 210 u8 *const user_buf, size_t buf_len, 211 const int out); 212 213 int ahci_identify_device(ata_dev_t *const ata_dev, u8 *const buf); 214 215 int ahci_error_recovery(ahci_dev_t *const dev, const u32 intr_status); 216 217 /* 218 * ahci_atapi.c 219 */ 220 ssize_t ahci_packet_read_cmd(atapi_dev_t *const _dev, 221 const u8 *const cmd, const size_t cmdlen, 222 u8 *const buf, const size_t buflen); 223 224 /* 225 * ahci_ata.c 226 */ 227 ssize_t ahci_ata_read_sectors(ata_dev_t *const ata_dev, 228 const lba_t start, size_t count, 229 u8 *const buf); 230 231 #endif /* _AHCI_PRIVATE_H */ 232