AHCI initial commit.
[akaros.git] / kern / include / ahci.h
1 /*
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9
10 /*
11  * advanced host controller interface (sata)
12  * © 2007  coraid, inc
13  */
14
15 /* ata errors */
16 enum {
17         Emed    = 1<<0,         /* media error */
18         Enm     = 1<<1,         /* no media */
19         Eabrt   = 1<<2,         /* abort */
20         Emcr    = 1<<3,         /* media change request */
21         Eidnf   = 1<<4,         /* no user-accessible address */
22         Emc     = 1<<5,         /* media change */
23         Eunc    = 1<<6,         /* data error */
24         Ewp     = 1<<6,         /* write protect */
25         Eicrc   = 1<<7,         /* interface crc error */
26
27         Efatal  = Eidnf|Eicrc,  /* must sw reset */
28 };
29
30 /* ata status */
31 enum {
32         ASerr   = 1<<0,         /* error */
33         ASdrq   = 1<<3,         /* request */
34         ASdf    = 1<<5,         /* fault */
35         ASdrdy  = 1<<6,         /* ready */
36         ASbsy   = 1<<7,         /* busy */
37
38         ASobs   = 1<<1|1<<2|1<<4,
39 };
40
41 /* pci configuration */
42 enum {
43         Abar    = 5,
44 };
45
46 /*
47  * ahci memory configuration
48  *
49  * 0000-0023    generic host control
50  * 0024-009f    reserved
51  * 00a0-00ff    vendor specific.
52  * 0100-017f    port 0
53  * ...
54  * 1080-1100    port 31
55  */
56
57 /* cap bits: supported features */
58 enum {
59         Hs64a   = 1<<31,        /* 64-bit addressing */
60         Hsncq   = 1<<30,        /* ncq */
61         Hssntf  = 1<<29,        /* snotification reg. */
62         Hsmps   = 1<<28,        /* mech pres switch */
63         Hsss    = 1<<27,        /* staggered spinup */
64         Hsalp   = 1<<26,        /* aggressive link pm */
65         Hsal    = 1<<25,        /* activity led */
66         Hsclo   = 1<<24,        /* command-list override */
67         Hiss    = 1<<20,        /* for interface speed */
68 //      Hsnzo   = 1<<19,
69         Hsam    = 1<<18,        /* ahci-mode only */
70         Hspm    = 1<<17,        /* port multiplier */
71 //      Hfbss   = 1<<16,
72         Hpmb    = 1<<15,        /* multiple-block pio */
73         Hssc    = 1<<14,        /* slumber state */
74         Hpsc    = 1<<13,        /* partial-slumber state */
75         Hncs    = 1<<8,         /* n command slots */
76         Hcccs   = 1<<7,         /* coal */
77         Hems    = 1<<6,         /* enclosure mgmt. */
78         Hsxs    = 1<<5,         /* external sata */
79         Hnp     = 1<<0,         /* n ports */
80 };
81
82 /* ghc bits */
83 enum {
84         Hae     = 1<<31,        /* enable ahci */
85         Hie     = 1<<1,         /* " interrupts */
86         Hhr     = 1<<0,         /* hba reset */
87 };
88
89 typedef struct {
90         uint32_t        cap;
91         uint32_t        ghc;
92         uint32_t        isr;
93         uint32_t        pi;             /* ports implemented */
94         uint32_t        ver;
95         uint32_t        ccc;            /* coaleasing control */
96         uint32_t        cccports;
97         uint32_t        emloc;
98         uint32_t        emctl;
99 } Ahba;
100
101 enum {
102         Acpds   = 1<<31,        /* cold port detect status */
103         Atfes   = 1<<30,        /* task file error status */
104         Ahbfs   = 1<<29,        /* hba fatal */
105         Ahbds   = 1<<28,        /* hba error (parity error) */
106         Aifs    = 1<<27,        /* interface fatal  §6.1.2 */
107         Ainfs   = 1<<26,        /* interface error (recovered) */
108         Aofs    = 1<<24,        /* too many bytes from disk */
109         Aipms   = 1<<23,        /* incorrect prt mul status */
110         Aprcs   = 1<<22,        /* PhyRdy change status Pxserr.diag.n */
111         Adpms   = 1<<7,         /* mechanical presence status */
112         Apcs    = 1<<6,         /* port connect  diag.x */
113         Adps    = 1<<5,         /* descriptor processed */
114         Aufs    = 1<<4,         /* unknown fis diag.f */
115         Asdbs   = 1<<3,         /* set device bits fis received w/ i bit set */
116         Adss    = 1<<2,         /* dma setup */
117         Apio    = 1<<1,         /* pio setup fis */
118         Adhrs   = 1<<0,         /* device to host register fis */
119
120         IEM     = Acpds|Atfes|Ahbds|Ahbfs|Ahbds|Aifs|Ainfs|Aprcs|Apcs|Adps|
121                         Aufs|Asdbs|Adss|Adhrs,
122         Ifatal  = Atfes|Ahbfs|Ahbds|Aifs,
123 };
124
125 /* serror bits */
126 enum {
127         SerrX   = 1<<26,        /* exchanged */
128         SerrF   = 1<<25,        /* unknown fis */
129         SerrT   = 1<<24,        /* transition error */
130         SerrS   = 1<<23,        /* link sequence */
131         SerrH   = 1<<22,        /* handshake */
132         SerrC   = 1<<21,        /* crc */
133         SerrD   = 1<<20,        /* not used by ahci */
134         SerrB   = 1<<19,        /* 10-tp-8 decode */
135         SerrW   = 1<<18,        /* comm wake */
136         SerrI   = 1<<17,        /* phy internal */
137         SerrN   = 1<<16,        /* phyrdy change */
138
139         ErrE    = 1<<11,        /* internal */
140         ErrP    = 1<<10,        /* ata protocol violation */
141         ErrC    = 1<<9,         /* communication */
142         ErrT    = 1<<8,         /* transient */
143         ErrM    = 1<<1,         /* recoverd comm */
144         ErrI    = 1<<0,         /* recovered data integrety */
145
146         ErrAll  = ErrE|ErrP|ErrC|ErrT|ErrM|ErrI,
147         SerrAll = SerrX|SerrF|SerrT|SerrS|SerrH|SerrC|SerrD|SerrB|SerrW|
148                         SerrI|SerrN|ErrAll,
149         SerrBad = 0x7f<<19,
150 };
151
152 /* cmd register bits */
153 enum {
154         Aicc    = 1<<28,        /* interface communcations control. 4 bits */
155         Aasp    = 1<<27,        /* aggressive slumber & partial sleep */
156         Aalpe   = 1<<26,        /* aggressive link pm enable */
157         Adlae   = 1<<25,        /* drive led on atapi */
158         Aatapi  = 1<<24,        /* device is atapi */
159         Aesp    = 1<<21,        /* external sata port */
160         Acpd    = 1<<20,        /* cold presence detect */
161         Ampsp   = 1<<19,        /* mechanical pres. */
162         Ahpcp   = 1<<18,        /* hot plug capable */
163         Apma    = 1<<17,        /* pm attached */
164         Acps    = 1<<16,        /* cold presence state */
165         Acr     = 1<<15,        /* cmdlist running */
166         Afr     = 1<<14,        /* fis running */
167         Ampss   = 1<<13,        /* mechanical presence switch state */
168         Accs    = 1<<8,         /* current command slot 12:08 */
169         Afre    = 1<<4,         /* fis enable receive */
170         Aclo    = 1<<3,         /* command list override */
171         Apod    = 1<<2,         /* power on dev (requires cold-pres. detect) */
172         Asud    = 1<<1,         /* spin-up device;  requires ss capability */
173         Ast     = 1<<0,         /* start */
174
175         Arun    = Ast|Acr|Afre|Afr,
176 };
177
178 /* ctl register bits */
179 enum {
180         Aipm    = 1<<8,         /* interface power mgmt. 3=off */
181         Aspd    = 1<<4,
182         Adet    = 1<<0,         /* device detection */
183 };
184
185 #define sstatus scr0
186 #define sctl    scr2
187 #define serror  scr1
188 #define sactive scr3
189
190 typedef struct {
191         uint32_t        list;           /* PxCLB must be 1kb aligned. */
192         uint32_t        listhi;
193         uint32_t        fis;            /* 256-byte aligned */
194         uint32_t        fishi;
195         uint32_t        isr;
196         uint32_t        ie;             /* interrupt enable */
197         uint32_t        cmd;
198         uint32_t        res1;
199         uint32_t        task;
200         uint32_t        sig;
201         uint32_t        scr0;
202         uint32_t        scr2;
203         uint32_t        scr1;
204         uint32_t        scr3;
205         uint32_t        ci;             /* command issue */
206         uint32_t        ntf;
207         unsigned char   res2[8];
208         uint32_t        vendor;
209 } Aport;
210
211 enum {
212         /*
213          * Aport sstatus bits (actually states):
214          * 11-8 interface power management
215          *  7-4 current interface speed (generation #)
216          *  3-0 device detection
217          */
218         Intslumber      = 0x600,
219         Intpartpwr      = 0x200,
220         Intactive       = 0x100,
221         Intpm           = 0xf00,
222
223         Devphyoffline   = 4,
224         Devphycomm      = 2,            /* phy communication established */
225         Devpresent      = 1,
226         Devdet          = Devpresent | Devphycomm | Devphyoffline,
227 };
228
229 /* in host's memory; not memory mapped */
230 typedef struct {
231         unsigned char   *base;
232         unsigned char   *d;
233         unsigned char   *p;
234         unsigned char   *r;
235         unsigned char   *u;
236         uint32_t        *devicebits;
237 } Afis;
238
239 enum {
240         Lprdtl  = 1<<16,        /* physical region descriptor table len */
241         Lpmp    = 1<<12,        /* port multiplier port */
242         Lclear  = 1<<10,        /* clear busy on R_OK */
243         Lbist   = 1<<9,
244         Lreset  = 1<<8,
245         Lpref   = 1<<7,         /* prefetchable */
246         Lwrite  = 1<<6,
247         Latapi  = 1<<5,
248         Lcfl    = 1<<0,         /* command fis length in double words */
249 };
250
251 /* in hosts memory; memory mapped */
252 typedef struct {
253         uint32_t        flags;
254         uint32_t        len;
255         uint32_t        ctab;
256         uint32_t        ctabhi;
257         unsigned char   reserved[16];
258 } Alist;
259
260 typedef struct {
261         uint32_t        dba;
262         uint32_t        dbahi;
263         uint32_t        pad;
264         uint32_t        count;
265 } Aprdt;
266
267 typedef struct {
268         unsigned char   cfis[0x40];
269         unsigned char   atapi[0x10];
270         unsigned char   pad[0x30];
271         Aprdt   prdt;
272 } Actab;
273
274 enum {
275         Ferror  = 1,
276         Fdone   = 2,
277 };
278
279 enum {
280         Dllba   = 1,
281         Dsmart  = 1<<1,
282         Dpower  = 1<<2,
283         Dnop    = 1<<3,
284         Datapi  = 1<<4,
285         Datapi16= 1<<5,
286 };
287
288 typedef struct {
289         QLock ql;
290         Rendez Rendez;
291         unsigned char   flag;
292         unsigned char   feat;
293         unsigned char   smart;
294         Afis    fis;
295         Alist   *list;
296         Actab   *ctab;
297 } Aportm;
298
299 typedef struct {
300         Aport   *p;
301         Aportm  *pm;
302 } Aportc;