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