]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ahci.h
[9front] [PATCH] audiohda: add PCI ID for Intel C610/X99
[plan9front.git] / sys / src / 9 / pc / ahci.h
1 /*
2  * advanced host controller interface (sata)
3  * © 2007-9  coraid, inc
4  */
5
6 /* pci configuration */
7 enum {
8         Abar    = 5,
9 };
10
11 /*
12  * ahci memory configuration
13  *
14  * 0000-0023    generic host control
15  * 0024-009f    reserved
16  * 00a0-00ff    vendor specific.
17  * 0100-017f    port 0
18  * ...
19  * 1080-1100    port 31
20  */
21
22 /* cap bits: supported features */
23 enum {
24         H64a    = 1<<31,        /* 64-bit addressing */
25         Hncq    = 1<<30,        /* ncq */
26         Hsntf   = 1<<29,        /* snotification reg. */
27         Hmps    = 1<<28,        /* mech pres switch */
28         Hss     = 1<<27,        /* staggered spinup */
29         Halp    = 1<<26,        /* aggressive link pm */
30         Hal     = 1<<25,        /* activity led */
31         Hclo    = 1<<24,        /* command-list override */
32         Hiss    = 1<<20,        /* for interface speed */
33         Ham     = 1<<18,        /* ahci-mode only */
34         Hpm     = 1<<17,        /* port multiplier */
35         Hfbs    = 1<<16,        /* fis-based switching */
36         Hpmb    = 1<<15,        /* multiple-block pio */
37         Hssc    = 1<<14,        /* slumber state */
38         Hpsc    = 1<<13,        /* partial-slumber state */
39         Hncs    = 1<<8,         /* n command slots */
40         Hcccs   = 1<<7,         /* coal */
41         Hems    = 1<<6,         /* enclosure mgmt. */
42         Hxs     = 1<<5,         /* external sata */
43         Hnp     = 1<<0,         /* n ports */
44 };
45
46 /* ghc bits */
47 enum {
48         Hae     = 1<<31,        /* enable ahci */
49         Hie     = 1<<1,         /* " interrupts */
50         Hhr     = 1<<0,         /* hba reset */
51 };
52
53 /* cap2 bits */
54 enum {
55         Apts    = 1<<2, /* automatic partial to slumber */
56         Nvmp    = 1<<1, /* nvmhci present; nvram */
57         Boh     = 1<<0, /* bios/os handoff supported */
58 };
59
60 /* bios bits */
61 enum {
62         Bos     = 1<<0,
63         Oos     = 1<<1,
64 };
65
66 /* emctl bits */
67 enum {
68         Pm      = 1<<27,        /* port multiplier support */
69         Alhd    = 1<<26,        /* activity led hardware driven */
70         Xonly   = 1<<25,        /* rx messages not supported */
71         Smb     = 1<<24,        /* single msg buffer; rx limited */
72         Esgpio  = 1<<19,        /* sgpio messages supported */
73         Eses2   = 1<<18,        /* ses-2 supported */
74         Esafte  = 1<<17,        /* saf-te supported */
75         Elmt    = 1<<16,        /* led msg types support */
76         Emrst   = 1<<9, /* reset all em logic */
77         Tmsg    = 1<<8, /* transmit message */
78         Mr      = 1<<0, /* message rx'd */
79         Emtype  = Esgpio | Eses2 | Esafte | Elmt,
80 };
81
82 typedef struct {
83         ulong   cap;
84         ulong   ghc;
85         ulong   isr;
86         ulong   pi;             /* ports implemented */
87         ulong   ver;
88         ulong   ccc;            /* coaleasing control */
89         ulong   cccports;
90         ulong   emloc;
91         ulong   emctl;
92         ulong   cap2;
93         ulong   bios;
94 } Ahba;
95
96 enum {
97         Acpds   = 1<<31,        /* cold port detect status */
98         Atfes   = 1<<30,        /* task file error status */
99         Ahbfs   = 1<<29,        /* hba fatal */
100         Ahbds   = 1<<28,        /* hba error (parity error) */
101         Aifs    = 1<<27,        /* interface fatal  §6.1.2 */
102         Ainfs   = 1<<26,        /* interface error (recovered) */
103         Aofs    = 1<<24,        /* too many bytes from disk */
104         Aipms   = 1<<23,        /* incorrect prt mul status */
105         Aprcs   = 1<<22,        /* PhyRdy change status Pxserr.diag.n */
106         Adpms   = 1<<7,         /* mechanical presence status */
107         Apcs    = 1<<6,         /* port connect  diag.x */
108         Adps    = 1<<5,         /* descriptor processed */
109         Aufs    = 1<<4,         /* unknown fis diag.f */
110         Asdbs   = 1<<3,         /* set device bits fis received w/ i bit set */
111         Adss    = 1<<2,         /* dma setup */
112         Apio    = 1<<1,         /* pio setup fis */
113         Adhrs   = 1<<0,         /* device to host register fis */
114
115         IEM     = Acpds|Atfes|Ahbds|Ahbfs|Ahbds|Aifs|Ainfs|Aprcs|Apcs|Adps|
116                         Aufs|Asdbs|Adss|Adhrs,
117         Ifatal  = Ahbfs|Ahbds|Aifs,
118 };
119
120 /* serror bits */
121 enum {
122         SerrX   = 1<<26,        /* exchanged */
123         SerrF   = 1<<25,        /* unknown fis */
124         SerrT   = 1<<24,        /* transition error */
125         SerrS   = 1<<23,        /* link sequence */
126         SerrH   = 1<<22,        /* handshake */
127         SerrC   = 1<<21,        /* crc */
128         SerrD   = 1<<20,        /* not used by ahci */
129         SerrB   = 1<<19,        /* 10-tp-8 decode */
130         SerrW   = 1<<18,        /* comm wake */
131         SerrI   = 1<<17,        /* phy internal */
132         SerrN   = 1<<16,        /* phyrdy change */
133
134         ErrE    = 1<<11,        /* internal */
135         ErrP    = 1<<10,        /* ata protocol violation */
136         ErrC    = 1<<9,         /* communication */
137         ErrT    = 1<<8,         /* transient */
138         ErrM    = 1<<1,         /* recoverd comm */
139         ErrI    = 1<<0,         /* recovered data integrety */
140
141         ErrAll  = ErrE|ErrP|ErrC|ErrT|ErrM|ErrI,
142         SerrAll = SerrX|SerrF|SerrT|SerrS|SerrH|SerrC|SerrD|SerrB|SerrW|
143                         SerrI|SerrN|ErrAll,
144         SerrBad = 0x7f<<19,
145 };
146
147 /* cmd register bits */
148 enum {
149         Aicc    = 1<<28,        /* interface communcations control. 4 bits */
150         Aasp    = 1<<27,        /* aggressive slumber & partial sleep */
151         Aalpe   = 1<<26,        /* aggressive link pm enable */
152         Adlae   = 1<<25,        /* drive led on atapi */
153         Aatapi  = 1<<24,        /* device is atapi */
154         Apste   = 1<<23,        /* automatic slumber to partial cap */
155         Afbsc   = 1<<22,        /* fis-based switching capable */
156         Aesp    = 1<<21,        /* external sata port */
157         Acpd    = 1<<20,        /* cold presence detect */
158         Ampsp   = 1<<19,        /* mechanical pres. */
159         Ahpcp   = 1<<18,        /* hot plug capable */
160         Apma    = 1<<17,        /* pm attached */
161         Acps    = 1<<16,        /* cold presence state */
162         Acr     = 1<<15,        /* cmdlist running */
163         Afr     = 1<<14,        /* fis running */
164         Ampss   = 1<<13,        /* mechanical presence switch state */
165         Accs    = 1<<8,         /* current command slot 12:08 */
166         Afre    = 1<<4,         /* fis enable receive */
167         Aclo    = 1<<3,         /* command list override */
168         Apod    = 1<<2,         /* power on dev (requires cold-pres. detect) */
169         Asud    = 1<<1,         /* spin-up device;  requires ss capability */
170         Ast     = 1<<0,         /* start */
171
172         Arun    = Ast|Acr|Afre|Afr,
173         Apwr    = Apod|Asud,
174 };
175
176 /* ctl register bits */
177 enum {
178         Aipm    = 1<<8,         /* interface power mgmt. 3=off */
179         Aspd    = 1<<4,
180         Adet    = 1<<0,         /* device detection */
181 };
182
183 /* sstatus register bits */
184 enum{
185         /* sstatus det */
186         Smissing                = 0<<0,
187         Spresent                = 1<<0,
188         Sphylink                = 3<<0,
189         Sbist           = 4<<0,
190         Smask           = 7<<0,
191
192         /* sstatus speed */
193         Gmissing                = 0<<4,
194         Gi              = 1<<4,
195         Gii             = 2<<4,
196         Giii            = 3<<4,
197         Gmask           = 7<<4,
198
199         /* sstatus ipm */
200         Imissing                = 0<<8,
201         Iactive         = 1<<8,
202         Isleepy         = 2<<8,
203         Islumber                = 6<<8,
204         Imask           = 7<<8,
205
206         SImask          = Smask | Imask,
207         SSmask          = Smask | Isleepy,
208 };
209
210 #define sstatus scr0
211 #define sctl    scr2
212 #define serror  scr1
213 #define sactive scr3
214 #define ntf     scr4
215
216 typedef struct {
217         ulong   list;           /* PxCLB must be 1kb aligned */
218         ulong   listhi;
219         ulong   fis;            /* 256-byte aligned */
220         ulong   fishi;
221         ulong   isr;
222         ulong   ie;             /* interrupt enable */
223         ulong   cmd;
224         ulong   res1;
225         ulong   task;
226         ulong   sig;
227         ulong   scr0;
228         ulong   scr2;
229         ulong   scr1;
230         ulong   scr3;
231         ulong   ci;             /* command issue */
232         ulong   scr4;
233         ulong   fbs;
234         ulong   res2[11];
235         ulong   vendor[4];
236 } Aport;
237
238 /* in host's memory; not memory mapped */
239 typedef struct {
240         uchar   *base;
241         uchar   *d;
242         uchar   *p;
243         uchar   *r;
244         uchar   *u;
245         ulong   *devicebits;
246 } Afis;
247
248 enum {
249         Lprdtl  = 1<<16,        /* physical region descriptor table len */
250         Lpmp    = 1<<12,        /* port multiplier port */
251         Lclear  = 1<<10,        /* clear busy on R_OK */
252         Lbist   = 1<<9,
253         Lreset  = 1<<8,
254         Lpref   = 1<<7,         /* prefetchable */
255         Lwrite  = 1<<6,
256         Latapi  = 1<<5,
257         Lcfl    = 1<<0,         /* command fis length in double words */
258 };
259
260 /* in hosts memory; memory mapped */
261 typedef struct {
262         ulong   flags;
263         ulong   len;
264         ulong   ctab;
265         ulong   ctabhi;
266         uchar   reserved[16];
267 } Alist;
268
269 typedef struct {
270         ulong   dba;
271         ulong   dbahi;
272         ulong   pad;
273         ulong   count;
274 } Aprdt;
275
276 typedef struct {
277         uchar   cfis[0x40];
278         uchar   atapi[0x10];
279         uchar   pad[0x30];
280         Aprdt   prdt;
281 } Actab;
282
283 /* enclosure message header */
284 enum {
285         Mled    = 0,
286         Msafte  = 1,
287         Mses2   = 2,
288         Msgpio  = 3,
289 };
290
291 typedef struct {
292         uchar   dummy;
293         uchar   msize;
294         uchar   dsize;
295         uchar   type;
296         uchar   hba;            /* bits 0:4 are the port */
297         uchar   pm;
298         uchar   led[2];
299 } Aledmsg;
300
301 enum {
302         Aled    = 1<<0,
303         Locled  = 1<<3,
304         Errled  = 1<<6,
305
306         Ledoff  = 0,
307         Ledon   = 1,
308 };
309
310 typedef struct {
311         uint    encsz;
312         ulong   *enctx;
313         ulong   *encrx;
314 } Aenc;
315
316 enum {
317         Ferror  = 1,
318         Fdone   = 2,
319 };
320
321 typedef struct {
322         QLock;
323         Rendez;
324         uchar   flag;
325         Sfis;
326         Afis    fis;
327         Alist   *list;
328         Actab   *ctab;
329 } Aportm;
330
331 typedef struct {
332         Aport   *p;
333         Aportm  *m;
334 } Aportc;