xref: /aosp_15_r20/external/coreboot/payloads/libpayload/drivers/storage/ahci_private.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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