1/*
2 * Copyright (c) 2009, ETH Zurich. All rights reserved.
3 *
4 * This file is distributed under the terms in the attached LICENSE file.
5 * If you do not find this file, copies can be found by writing to:
6 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
7 */
8
9/*
10 * ahci_port.dev
11 *
12 * DESCRIPTION: AHCI (SATA) Host bus adaptor, per-port registers
13 *
14 * Section numbers refer to the Serial ATA Advanced Host Controller
15 *   Interface (AHCI) specification 1.3, June 2008
16 */
17
18device ahci_port msbfirst (addr b) "AHCI port" {
19
20    // 3.3.1-2
21    // Low 10 bits mbz
22    register clb rw addr(b,0x00) "Command list base address" type(uint64);
23
24    // 3.3.3-4
25    // Low 10 bits mbz
26    register fb rw addr(b,0x08) "FIS base address" type(uint64);
27
28    // 3.3.5
29    register is addr(b,0x10) "Interrupt status" {
30	cpds	1 rw1c "Cold port detect";
31	tfes	1 rw1c "Task file error";
32	hbfs	1 rw1c "Host bus fatal error";
33	hbds	1 rw1c "Host bus data error";
34	ifs	1 rw1c "Interface fatal error";
35	infs	1 rw1c "Interface non-fatal error";
36	_	1 rsvd;
37	ofs	1 rw1c "Overflow status";
38	ipms	1 rw1c "Incorrect port multiplier status";
39	prcs	1 ro   "PhyRdy change status";
40	_	14 rsvd;
41	dmps	1 rw1c "Device mechanical presence";
42	pcs	1 ro   "Port connect change";
43	dps	1 rw1c "Descriptor processed";
44	ufs	1 ro   "Unknown FIS interrupt";
45	sdbs	1 rw1c "Set device bits interrupt";
46	dss	1 rw1c "DMA setup FIS interrupt";
47	pss	1 rw1c "PIO setup FIS interrupt";
48	dhrs	1 rw1c "Device to host register FIS interrupt";
49    };
50
51    // 3.3.6
52    register ie addr(b,0x14) "Interrupt enable" {
53	cpde	1 rw "Cold port detect";
54	tfee	1 rw "Task file error";
55	hbfe	1 rw "Host bus fatal error";
56	hbde	1 rw "Host bus data error";
57	ife     1 rw "Interface fatal error";
58	infe	1 rw "Interface non-fatal error";
59	_	1 rsvd;
60	ofe	1 rw "Overflow enable";
61	ipme	1 rw "Incorrect port multiplier status";
62	prce	1 ro   "PhyRdy change status";
63	_	14 rsvd;
64	dmpe	1 rw "Device mechanical presence";
65	pce	1 ro   "Port connect change";
66	dpe	1 rw "Descriptor processed";
67	ufe	1 ro   "Unknown FIS interrupt";
68	sdbe	1 rw "Set device bits interrupt";
69	dse	1 rw "DMA setup FIS interrupt";
70	pse	1 rw "PIO setup FIS interrupt";
71	dhre	1 rw "Device to host register FIS interrupt";
72    };
73
74    // 3.3.7
75    constants icct "Interface communication control" {
76	slumber	= 0x6 "Slumber";
77	partial = 0x2 "Partial";
78	active  = 0x1 "Active";
79	idle	= 0x0 "No-Op / Idle";
80    };
81    register cmd addr(b,0x18) "Command and status" {
82	icc	4 rw type(icct) "Interface communication control";
83	asp	1 rw "Aggressive slumber / partial";
84	alpe	1 rw "Aggressive link power management enable";
85	dlae	1 rw "Drive LED on ATAPI enable";
86	atapi	1 rw "Device is ATAPI";
87	apste	1 rw "Automatic partial to slumber transitions enabled";
88	fbscp	1 ro "FIS-based switching capable port";
89	esp	1 ro "External SATA port";
90	cpd	1 ro "Cold presence detection";
91	mpsp	1 ro "Mechanical presence switch";
92	hpcp	1 ro "Hot plug capable port";
93	pma	1 rw "Port multiplier attached";
94	cps	1 ro "Cold presence state";
95	cr	1 ro "Command list running";
96	fr	1 ro "FIS receive running";
97	mpss	1 ro "Mechanical presence switch state";
98	ccs	5 ro "Current command slot";
99	_	3 rsvd;
100	fre	1 rw "FIS receive enable";
101	clo	1 rw "Command list override";
102	pod	1 rw "Power on device";
103	sud	1 rw "Spin-up device";
104	st	1 rw "Start";
105    };
106
107    // 3.3.8
108    register tfd ro addr(b,0x20) "Task file data" {
109	_	16 rsvd;
110	err	8 "Error";
111    bsy 1 ro    "Indicates the interface is busy";
112    cs2 3 ro    "Command specific";
113    drq 1 ro    "Indicates a data transfer is requested";
114    cs1 2 ro    "Command specific";
115    serr 1 ro    "Indicates an error during the transfer.";
116    };
117
118    // 3.3.9
119    register sig ro addr(b,0x24) "Signature" {
120	lbah	8 "LBA high";
121	lbam	8 "LBA mid";
122	lbal	8 "LBA low";
123	sectors 8 "Sector count";
124    };
125
126    // 3.3.10
127    constants speed "Interface speed" {
128	gen1	= 0b0001 "Gen 1 (1.5 Gbps)";
129	gen2	= 0b0010 "Gen 2 (3 Gbps)";
130	gen3	= 0b0011 "Gen 3 (6 Gbps)";
131    };
132    constants dets "Device detection state" {
133	nodev	= 0x0 "No device, no PHY";
134	nophy	= 0x1 "Device detected, no PHY comm. established";
135	detect  = 0x3 "Device detected and PHY comm. established";
136	offline = 0x4 "PHY in offline mode or loopback";
137    };
138    register ssts ro addr(b,0x28) "Serial ATA status" {
139	_	20 rsvd;
140	ipm	4 type(icct) "Interface power management";
141	spd	4 type(speed) "Current interface speed";
142	det	4 type(dets) "Device detection";
143    };
144
145    // 3.3.11
146    constants ipmall "Interface transitions" {
147	noipm	= 0x0 "No interface restrictions";
148	noprtl	= 0x1 "Transitions to Partial state disabled";
149	noslmb  = 0x2 "Transitions to Slumber state disabled";
150	noboth	= 0x3 "Transitions to both Partial and Slumber disabled";
151    };
152    register sctl addr(b,0x2c) "Serial ATA control" {
153	_	12 rsvd;
154	_	4 rsvd "Port multiplier port (unused)";
155	_	4 rsvd "Select power mgmt (unused)";
156	ipm	4 rw type(ipmall) "Interface power mgmt transitions allowed";
157	spd	4 rw type(speed) "Speed allowed";
158	det	4 rw type(dets) "Device detection initialization";
159    };
160
161    // 3.3.12
162    register serr rw1c addr(b,0x30) "Serial ATA error" {
163	_	5 rsvd;
164	dx	1 "Exchanged";
165	df	1 "Unknown FIS type";
166	dt	1 "Transport state transition error";
167	ds	1 "Link sequence error";
168	dh	1 "Handshake error";
169	dc	1 "CRC error";
170	dd	1 "Disparity error";
171	db	1 "10b to 8b decode error";
172	dw	1 "Comm wake";
173	di	1 "Phy internal error";
174	dn	1 "PhyRdy change";
175	_	4 rsvd;
176	ee	1 "Internal error";
177	ep	1 "Protocol error";
178	ec	1 "Persistent communication or data integrity error";
179	et	1 "Transient data integrity error";
180	_	6 rsvd;
181	em	1 "Recovered communications error";
182	ei	1 "Recovered data integrity error";
183    };
184
185    // 3.3.13
186    register sact rw addr(b,0x34) "Serial ATA active" type(uint32);
187
188    // 3.3.14
189    register ci rw addr(b,0x38) "Command issue" type(uint32);
190
191    // 3.3.15
192    register sntf addr(b,0x3c) "Serial ATA notification" {
193	_	16 mbz;
194	pmn	16 rw1c "PMN notify";
195    };
196
197    // 3.3.16
198    register fbs addr(b,0x40) "FIS-based switching control" {
199	_	12 mbz;
200	dwe	4 ro "Device with error";
201	ado	4 ro "Active device optimization";
202	dev	4 rw "Device to issue";
203	_	5 mbz;
204	sde	1 ro "Single device error";
205	dec	1 rw1c "Device error clear";
206	en	1 rw "Enable";
207    };
208
209    // 4.2.2 Command List Structure, elements are Command Headers
210    datatype chdr msbfirst(32) "Command Header" {
211	prdtl	16 "Physical region descriptor table length";
212	pmp	4  "Port multiplier port";
213	_	1;
214	c	1 "Clear busy upon R_OK";
215	b	1 "BIST";
216	r	1 "Reset";
217	p	1 "Prefetchable";
218	w	1 "Write";
219	a	1 "ATAPI";
220	cfl	5 "Command FIS length";
221
222	prdbc	32 "Physical region descriptor byte count";
223
224	ctba	64 "Command table descriptor base address";
225
226	_	32;
227	_	32;
228	_	32;
229	_	32;
230    };
231
232    // 4.2.3.3 Physical Region Descriptor Table
233    datatype prd msbfirst(32) "Physical region descriptor" {
234	dba	32 "Data base address";
235	dbau	32 "Data base address upper";
236	_	32;
237	i	1 "Interrupt on completion";
238	_	9;
239	dbc	22 "Data byte count";
240    };
241
242    // 12.2
243    constants emtype "Enclosure message type" {
244	led	= 0x0 "LED";
245	saf_te	= 0x1 "SAF-TE";
246	ses_2	= 0x2 "SES-2";
247	sgpio	= 0x3 "SGPOI (register-based interface";
248    };
249    datatype encmsg "Enclosure management message" {
250	_	4;
251	mtype	4 type(emtype) "Message type";
252	dsize	8 "Data size";
253	msize	8 "Message size";
254	_	8;
255    };
256
257    // 12.2.1
258    constants emledstate "Enclosure LED state" {
259	off	= 0b000 "LED shall be off";
260	solid	= 0b001 "LED shall be solid on";
261	vs1	= 0b100 "Vendor specific 1";
262	vs2	= 0b101 "Vendor specific 2";
263	vs3	= 0b110 "Vendor specific 3";
264	vs4	= 0b111 "Vendor specific 4";
265    };
266    datatype emledmsg "Enclosure LED message" {
267	_	7;
268	fault	3 type(emledstate) "Vendor-specific LED (e.g. fault)";
269	locate	3 type(emledstate) "Vendor-specific LED (e.g. locate)";
270	activity 3 type(emledstate) "Activity LED";
271	_	4;
272	pmi	4 "Port multiplier information";
273	_	2;
274	vsm	1 "Vendor-specific enclosure message";
275	hbapn	5 "HBA port number for update";
276    };
277};
278