source: mainline/uspace/drv/block/ahci/ahci_hw.h@ 9904eb90

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9904eb90 was 9904eb90, checked in by Martin Decky <martin@…>, 13 years ago

cherrypick initial SATA (AHCI) support, originally by Petr Jerman

  • Property mode set to 100644
File size: 30.4 KB
Line 
1/*
2 * Copyright (c) 2012 Petr Jerman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - 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 ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file
30 * Header for AHCI driver (AHCI 1.3 specification).
31 */
32
33#ifndef __AHCI_HW_H__
34#define __AHCI_HW_H__
35
36#include <sys/types.h>
37
38/*----------------------------------------------------------------------------*/
39/*-- AHCI PCI Registers ------------------------------------------------------*/
40/*----------------------------------------------------------------------------*/
41
42/** AHCI PCI register Identifiers offset. */
43#define AHCI_PCI_ID 0x00
44/** AHCI PCI register Command offset. */
45#define AHCI_PCI_CMD 0x04
46/** AHCI PCI register Device Status offset. */
47#define AHCI_PCI_STS 0x06
48/** AHCI PCI register Revision ID offset. */
49#define AHCI_PCI_RID 0x08
50/** AHCI PCI register Class Codes offset. */
51#define AHCI_PCI_CC 0x09
52/** AHCI PCI register Cache Line Size offset. */
53#define AHCI_PCI_CLS 0x0C
54/** AHCI PCI register Master Latency Timer offset. */
55#define AHCI_PCI_MLT 0x0D
56/** AHCI PCI register Header Type offset. */
57#define AHCI_PCI_HTYPE 0x0E
58/** AHCI PCI register Built In Self Test (Optional) offset. */
59#define AHCI_PCI_BIST 0x0F
60/** AHCI PCI register Other Base Address Registres (Optional). */
61#define AHCI_PCI_BAR0 0x10
62/** AHCI PCI register Other Base Address Registres (Optional). */
63#define AHCI_PCI_BAR1 0x14
64/** AHCI PCI register Other Base Address Registres (Optional). */
65#define AHCI_PCI_BAR2 0x18
66/** AHCI PCI register Other Base Address Registres (Optional). */
67#define AHCI_PCI_BAR3 0x1C
68/** AHCI PCI register Other Base Address Registres (Optional). */
69#define AHCI_PCI_BAR4 0x20
70/** AHCI PCI register AHCI Base Address offset. */
71#define AHCI_PCI_ABAR 0x24
72/** AHCI PCI register Subsystem Identifiers offset. */
73#define AHCI_PCI_SS 0x2C
74/** AHCI PCI register Expansion ROM Base Address (Optional) offset. */
75#define AHCI_PCI_EROM 0x30
76/** AHCI PCI register Capabilities Pointer offset. */
77#define AHCI_PCI_CAP 0x34
78/** AHCI PCI register Interrupt Information offset. */
79#define AHCI_PCI_INTR 0x3C
80/** AHCI PCI register Min Grant (Optional) offset. */
81#define AHCI_PCI_MGNT 0x3E
82/** AHCI PCI register Max Latency (Optional) offset. */
83#define AHCI_PCI_MLAT 0x3F
84
85/** AHCI PCI register Identifiers. */
86typedef struct {
87 /** Indicates the company vendor assigned by the PCI SIG. */
88 uint16_t vendorid;
89 /** Indicates what device number assigned by the vendor */
90 uint16_t deviceid;
91} __attribute__((packed)) ahci_pcireg_id_t;
92
93/** AHCI PCI register Command. */
94typedef union {
95 struct {
96 /** I/O Space Enable. */
97 unsigned int iose : 1;
98 /** Memory Space Enable. */
99 unsigned int mse : 1;
100 /** Bus Master Enable. */
101 unsigned int bme : 1;
102 /** Special Cycle Enable. */
103 unsigned int sce : 1;
104 /** Memory Write and Invalidate Enable. */
105 unsigned int mwie : 1;
106 /** VGA Palette Snooping Enable. */
107 unsigned int vga : 1;
108 /** Parity Error Response Enable. */
109 unsigned int pee : 1;
110 /** Wait Cycle Enable. */
111 unsigned int wcc : 1;
112 /** SERR# Enable. */
113 unsigned int see : 1;
114 /** Fast Back-to-Back Enable. */
115 unsigned int fbe : 1;
116 /** Interrupt Disable - disables the HBA from generating interrupts.
117 * This bit does not have any effect on MSI operation.
118 */
119 unsigned int id : 1;
120 /** Reserved. */
121 unsigned int reserved : 5;
122 } __attribute__((packed));
123 uint16_t u16;
124} __attribute__((packed)) ahci_pcireg_cmd_t;
125
126/** AHCI PCI register Command - Interrupt Disable bit. */
127#define AHCI_PCIREG_CMD_ID 0x0400
128
129/** AHCI PCI register Command - Bus Master Enable bit. */
130#define AHCI_PCIREG_CMD_BME 0x0004
131
132/** AHCI PCI register Device status. */
133typedef union {
134 struct {
135 /** Reserved. */
136 unsigned int reserved1 : 3;
137 /** Indicate the interrupt status of the device (1 = asserted). */
138 unsigned int is : 1;
139 /** Indicates presence of capatibility list. */
140 unsigned int cl : 1;
141 /** 66 Mhz capable. */
142 unsigned int c66 : 1;
143 /** Reserved. */
144 unsigned int reserved2 : 1;
145 /** Fast back to back capable. */
146 unsigned int fbc : 1;
147 /** Master data parity error detected. */
148 unsigned int dpd : 1;
149 /** Device select timing. */
150 unsigned int devt : 2;
151 /** Signaled target abort. */
152 unsigned int sta : 1;
153 /** Received target abort. */
154 unsigned int rta : 1;
155 /** Received master abort. */
156 unsigned int rma : 1;
157 /** Signaled system error. */
158 unsigned int sse : 1;
159 /** Detected parity error. */
160 unsigned int dpe : 1;
161 } __attribute__((packed));
162 uint16_t u16;
163} __attribute__((packed)) ahci_pcireg_sts_t;
164
165/** AHCI PCI register Revision ID. */
166typedef struct {
167 /** Indicates stepping of the HBA hardware. */
168 uint8_t u8;
169} __attribute__((packed)) ahci_pcireg_rid_t;
170
171/** AHCI PCI register Class Codes. */
172typedef struct {
173 /** Programing interface, when set to 01h and the scc is set to 06h,
174 * indicates that this an AHCI HBA major revision 1.
175 */
176 uint8_t pi;
177 /** When set to 06h, indicates that is a SATA device. */
178 uint8_t scc;
179 /** Value 01 indicates that is a mass storage device. */
180 uint8_t bcc;
181} __attribute__((packed)) ahci_pcireg_cc_t_t;
182
183/** AHCI PCI register Cache Line Size. */
184typedef struct {
185 /** Cache line sizefor use with the memory write and invalidate command. */
186 uint8_t u8;
187} __attribute__((packed)) ahci_pcireg_cls_t;
188
189/** AHCI PCI register Master Latency Timer. */
190typedef struct {
191 /** Master latency timer,indicates the number of clocks the HBA is allowed
192 * to acts as master on PCI.
193 */
194 uint8_t u8;
195} __attribute__((packed)) ahci_pcireg_mlt_t;
196
197/** AHCI PCI register Header Type. */
198typedef union {
199 struct {
200 /** Header layout. */
201 unsigned int hl : 7;
202 /** Multi function device. */
203 unsigned int mfd : 1;
204 } __attribute__((packed));
205 uint8_t u8;
206} __attribute__((packed)) ahci_pciregs_htype_t;
207
208/** AHCI PCI register Built in self test. */
209typedef union {
210 struct {
211 /** Indicates the completion status of BIST
212 * non-zero value indicates a failure.
213 */
214 unsigned int cc : 4;
215 /** Reserved. */
216 unsigned int reserved : 2;
217 /** Software sets this bit to 1 to invoke BIST,
218 * the HBA clears this bit to 0 when BIST is complete.
219 */
220 unsigned int sb : 1;
221 /** BIST capable. */
222 unsigned int bc : 1;
223 } __attribute__((packed));
224 uint8_t u8;
225} __attribute__((packed)) ahci_pciregs_bist_t;
226
227/** AHCI PCI register AHCI Base Address <BAR 5>. */
228typedef union {
229 struct {
230 /** Indicates a request for register memory space. */
231 unsigned int rte : 1;
232 /** Indicates the this range can be mapped anywhere in 32-bit address
233 * space.
234 */
235 unsigned int tp : 2;
236 /** Indicate that this range is not prefetchable. */
237 unsigned int pf : 1;
238 /** Reserved. */
239 unsigned int reserved : 9;
240 /** Base address of registry memory space. */
241 unsigned int ba : 19;
242 } __attribute__((packed));
243 uint32_t u32;
244} __attribute__((packed)) ahci_pciregs_abar_t;
245
246/** AHCI PCI register Subsystem Identifiers. */
247typedef struct
248{
249 /** Sub system vendor identifier. */
250 uint8_t ssvid;
251 /** Sub system identifier. */
252 uint8_t ssid;
253} __attribute__((packed)) ahci_pcireg_ss_t;
254
255/** AHCI PCI registers Expansion ROM Base Address. */
256typedef struct
257{
258 /** Indicates the base address of the HBA expansion ROM. */
259 uint32_t u32;
260} __attribute__((packed)) ahci_pcireg_erom_t;
261
262/** AHCI PCI register Capabilities Pointer. */
263typedef struct
264{
265 /** Indicates the first capability pointer offset. */
266 uint8_t u8;
267} __attribute__((packed)) ahci_pcireg_cap_t;
268
269/** AHCI PCI register Interrupt Information. */
270typedef struct
271{
272 /* Software written value to indicate which interrupt vector
273 * the interrupt is connected to.
274 */
275 uint8_t iline;
276 /** This indicates the interrupt pin the HBA uses. */
277 uint8_t ipin;
278} __attribute__((packed)) ahci_pcireg_intr;
279
280/** AHCI PCI register Min Grant (Optional). */
281typedef struct
282{
283 /** Indicates the minimum grant time (in ? microseconds)
284 * that the device wishes grant asserted.
285 */
286 uint8_t u8;
287} __attribute__((packed)) ahci_pcireg_mgnt_t;
288
289/** AHCI PCI register Max Latency (Optional). */
290typedef struct
291{
292 /** Indicates the maximum latency that the device can withstand. */
293 uint8_t u8;
294} __attribute__((packed)) ahci_pcireg_mlat_t;
295
296/*----------------------------------------------------------------------------*/
297/*-- AHCI Memory Registers ---------------------------------------------------*/
298/*----------------------------------------------------------------------------*/
299
300/** AHCI Memory register Generic Host Control - HBA Capabilities. */
301typedef union {
302 struct {
303 /** Number of Ports. */
304 unsigned int np : 5;
305 /** Supports External SATA. */
306 unsigned int sxs : 1;
307 /** Enclosure Management Supported. */
308 unsigned int ems : 1;
309 /** Command Completion Coalescing Supported. */
310 unsigned int cccs : 1;
311 /** Number of Command Slots. */
312 unsigned int ncs : 5;
313 /** Partial State Capable. */
314 unsigned int psc : 1;
315 /** Slumber State Capable. */
316 unsigned int ssc : 1;
317 /** PIO Multiple DRQ Block. */
318 unsigned int pmd : 1;
319 /** FIS-based Switching Supported. */
320 unsigned int fbss : 1;
321 /** Supports Port Multiplier. */
322 unsigned int spm : 1;
323 /** Supports AHCI mode only. */
324 unsigned int sam : 1;
325 /** Reserved. */
326 unsigned int reserved : 1;
327 /** Interface Speed Support. */
328 unsigned int iss : 4;
329 /** Supports Command List Override. */
330 unsigned int sclo : 1;
331 /** Supports Activity LED. */
332 unsigned int sal : 1;
333 /** Supports Aggressive Link Power Management. */
334 unsigned int salp : 1;
335 /** Supports Staggered Spin-up. */
336 unsigned int sss : 1;
337 /** Supports Mechanical Presence Switch. */
338 unsigned int smps : 1;
339 /** Supports SNotification Register. */
340 unsigned int ssntf : 1;
341 /** Supports Native Command Queuing. */
342 unsigned int sncq : 1;
343 /** Supports 64-bit Addressing. */
344 unsigned int s64a : 1;
345 } __attribute__((packed));
346 uint32_t u32;
347} __attribute__((packed)) ahci_ghc_cap_t;
348
349/** AHCI Memory register Generic Host Control Global Host Control. */
350typedef union {
351 struct {
352 /** HBA Reset. */
353 unsigned int hr : 1;
354 /** Interrupt Enable. */
355 unsigned int ie : 1;
356 /** MSI Revert to Single Message. */
357 unsigned int mrsm : 1;
358 /** Reserved. */
359 unsigned int reserved : 28;
360 /** AHCI Enable. */
361 unsigned int ae : 1;
362 } __attribute__((packed));
363 uint32_t u32;
364} __attribute__((packed)) ahci_ghc_ghc_t;
365
366/** AHCI Enable mask bit. */
367#define AHCI_GHC_GHC_AE 0x80000000
368
369/** AHCI Interrupt Enable mask bit. */
370#define AHCI_GHC_GHC_IE 0x00000002
371
372/** AHCI Memory register Interrupt pending register. */
373typedef struct {
374 /** Interrupt pending status, if set, indicates that
375 * the corresponding port has an interrupt pending.
376 */
377 uint32_t u32;
378} __attribute__((packed)) ahci_ghc_is_t;
379
380/** AHCI Memory register Ports implemented. */
381typedef struct {
382 /** If a bit is set to 1, the corresponding port
383 * is available for software use.
384 */
385 uint32_t u32;
386} __attribute__((packed)) ahci_ghc_pi_t;
387
388/** AHCI Memory register AHCI version. */
389typedef struct {
390 /** Indicates the minor version */
391 uint16_t mnr;
392 /** Indicates the major version */
393 uint16_t mjr;
394} __attribute__((packed)) ahci_ghc_vs_t;
395
396/** AHCI Memory register Command completion coalesce control. */
397typedef union {
398 struct {
399 /** Enable CCC features. */
400 unsigned int en : 1;
401 /** Reserved. */
402 unsigned int reserved : 2;
403 /** Interrupt number for CCC. */
404 unsigned int intr : 5;
405 /** Number of command completions that are necessary to cause
406 * a CCC interrupt.
407 */
408 uint8_t cc;
409 /** Timeout value in ms. */
410 uint16_t tv;
411 } __attribute__((packed));
412 uint32_t u32;
413} __attribute__((packed)) ahci_ghc_ccc_ctl_t;
414
415/** AHCI Memory register Command completion coalescing ports. */
416typedef struct
417{
418 /** If a bit is set to 1, the corresponding port is
419 * part of the command completion coalescing feature.
420 */
421 uint32_t u32;
422} __attribute__((packed)) ahci_ghc_ccc_ports_t;
423
424/** AHCI Memory register Enclosure management location. */
425typedef struct
426{
427 /** Size of the transmit message buffer area in dwords. */
428 uint16_t sz;
429 /* Offset of the transmit message buffer area in dwords
430 * from the beginning of ABAR
431 */
432 uint16_t ofst;
433} __attribute__((packed)) ahci_ghc_em_loc;
434
435/** AHCI Memory register Enclosure management control. */
436typedef union {
437 struct {
438 /** Message received. */
439 unsigned int mr : 1;
440 /** Reserved. */
441 unsigned int reserved : 7;
442 /** Transmit message. */
443 unsigned int tm : 1;
444 /** Reset. */
445 unsigned int rst : 1;
446 /** Reserved. */
447 unsigned int reserved2 : 6;
448 /** LED message types. */
449 unsigned int led : 1;
450 /** Support SAFT-TE message type. */
451 unsigned int safte : 1;
452 /** Support SES-2 message type. */
453 unsigned int ses2 : 1;
454 /** Support SGPIO register. */
455 unsigned int sgpio : 1;
456 /** Reserved. */
457 unsigned int reserved3 : 4;
458 /** Single message buffer. */
459 unsigned int smb : 1;
460 /** Support transmitting only. */
461 unsigned int xmt : 1;
462 /** Activity LED hardware driven. */
463 unsigned int alhd : 1;
464 /** port multiplier support. */
465 unsigned int pm : 1;
466 /** Reserved. */
467 unsigned int reserved4 : 4;
468 } __attribute__((packed));
469 uint32_t u32;
470} __attribute__((packed)) ahci_ghc_em_ctl_t;
471
472/** AHCI Memory register HBA capatibilities extended. */
473typedef union {
474 struct {
475 /** HBA support BIOS/OS handoff mechanism,
476 * implemented BOHC register.
477 */
478 unsigned int boh : 1;
479 /** Support for NVMHCI register. */
480 unsigned int nvmp : 1;
481 /** Automatic partial to slumber transition support. */
482 unsigned int apst : 1;
483 /** Reserved. */
484 unsigned int reserved : 29;
485 } __attribute__((packed));
486 uint32_t u32;
487} __attribute__((packed)) ahci_ghc_cap2_t;
488
489/** AHCI Memory register BIOS/OS Handoff control and status. */
490typedef union {
491 struct {
492 /** BIOS Owned semaphore. */
493 unsigned int bos : 1;
494 /** OS Owned semaphore. */
495 unsigned int oos : 1;
496 /** SMI on OS ownership change enable. */
497 unsigned int sooe : 1;
498 /** OS ownership change. */
499 unsigned int ooc : 1;
500 /** BIOS Busy. */
501 unsigned int bb : 1;
502 /** Reserved. */
503 unsigned int reserved : 27;
504 } __attribute__((packed));
505 uint32_t u32;
506} __attribute__((packed)) ahci_ghc_bohc_t;
507
508/** AHCI Memory register Generic Host Control. */
509typedef struct
510{
511 /** Host Capabilities. */
512 uint32_t cap;
513 /** Global Host Control. */
514 uint32_t ghc;
515 /** Interrupt Status. */
516 uint32_t is;
517 /** Ports Implemented. */
518 uint32_t pi;
519 /** Version. */
520 uint32_t vs;
521 /** Command Completion Coalescing Control. */
522 uint32_t ccc_ctl;
523 /** Command Completion Coalsecing Ports. */
524 uint32_t ccc_ports;
525 /** Enclosure Management Location. */
526 uint32_t em_loc;
527 /** Enclosure Management Control. */
528 uint32_t em_ctl;
529 /** Host Capabilities Extended. */
530 uint32_t cap2;
531 /** BIOS/OS Handoff Control and Status. */
532 uint32_t bohc;
533} __attribute__((packed)) ahci_ghc_t;
534
535/** AHCI Memory register Port x Command List Base Address. */
536typedef union {
537 struct {
538 /** Reserved. */
539 unsigned int reserved : 10;
540 /** Command List Base Address (CLB) - Indicates the 32-bit base physical
541 * address for the command list for this port. This base is used when
542 * fetching commands to execute. The structure pointed to by this
543 * address range is 1K-bytes in length. This address must be 1K-byte
544 * aligned as indicated by bits 09:00 being read only.
545 */
546 unsigned int clb : 22;
547 } __attribute__((packed));
548 uint32_t u32;
549} __attribute__((packed)) ahci_port_clb_t;
550
551/** AHCI Memory register Port x Command List Base Address Upper 32-Bits. */
552typedef struct {
553 /** Command List Base Address Upper (CLBU): Indicates the upper 32-bits
554 * for the command list base physical address for this port. This base
555 * is used when fetching commands to execute. This register shall
556 * be read only for HBAs that do not support 64-bit addressing.
557 */
558 uint32_t u32;
559} __attribute__((packed)) ahci_port_clbu_t;
560
561/** AHCI Memory register Port x FIS Base Address. */
562typedef union {
563 struct {
564 /** Reserved. */
565 uint8_t reserved;
566 /** FIS Base Address (FB) - Indicates the 32-bit base physical address
567 * for received FISes. The structure pointed to by this address range
568 * is 256 bytes in length. This address must be 256-byte aligned as
569 * indicated by bits 07:00 being read only. When FIS-based switching
570 * is in use, this structure is 4KB in length and the address shall be
571 * 4KB aligned.
572 */
573 unsigned int fb : 24;
574 } __attribute__((packed));
575 uint32_t u32;
576} __attribute__((packed)) ahci_port_fb_t;
577
578/** AHCI Memory register Port x FIS Base Address Upper 32-Bits. */
579typedef struct {
580 /** FIS Base Address Upper (FBU) - Indicates the upper 32-bits
581 * for the received FIS base physical address for this port. This register
582 * shall be read only for HBAs that do not support 64-bit addressing.
583 */
584 uint32_t u32;
585} __attribute__((packed)) ahci_port_fbu_t;
586
587/** AHCI Memory register Port x Interrupt Status. */
588typedef union {
589 struct {
590 /** Device to Host Register FIS Interrupt. */
591 unsigned int dhrs : 1;
592 /** PIO Setup FIS Interrupt. */
593 unsigned int pss : 1;
594 /** DMA Setup FIS Interrupt. */
595 unsigned int dss : 1;
596 /** Set Device Bits Interrupt. */
597 unsigned int sdbs : 1;
598 /** Unknown FIS Interrupt. */
599 unsigned int ufs : 1;
600 /** Descriptor Processed. */
601 unsigned int dps : 1;
602 /** Port Connect Change Status. */
603 unsigned int pcs : 1;
604 /** Device Mechanical Presence Status. */
605 unsigned int dmps : 1;
606 /** Reserved. */
607 unsigned int reserved1 : 14;
608 /** PhyRdy Change Status. */
609 unsigned int prcs : 1;
610 /** Incorrect Port Multiplier Status. */
611 unsigned int ipms : 1;
612 /** Overflow Status. */
613 unsigned int ofs : 1;
614 /** Reserved. */
615 unsigned int reserved2 : 1;
616 /** Interface Non-fatal Error Status. */
617 unsigned int infs : 1;
618 /** Interface Fatal Error Status. */
619 unsigned int ifs : 1;
620 /** Host Bus Data Error Status. */
621 unsigned int hbds : 1;
622 /** Host Bus Fatal Error Status. */
623 unsigned int hbfs : 1;
624 /** Task File Error Status. */
625 unsigned int tfes : 1;
626 /** Cold Port Detect Status. */
627 unsigned int cpds : 1;
628 } __attribute__((packed));
629 uint32_t u32;
630} __attribute__((packed)) ahci_port_is_t;
631
632#define AHCI_PORT_IS_DHRS (1 << 0)
633#define AHCI_PORT_IS_PSS (1 << 1)
634#define AHCI_PORT_IS_DSS (1 << 2)
635#define AHCI_PORT_IS_SDBS (1 << 3)
636#define AHCI_PORT_IS_UFS (1 << 4)
637#define AHCI_PORT_IS_DPS (1 << 5)
638#define AHCI_PORT_IS_PCS (1 << 6)
639#define AHCI_PORT_IS_DMPS (1 << 7)
640
641#define AHCI_PORT_IS_PRCS (1 << 22)
642#define AHCI_PORT_IS_IPMS (1 << 23)
643#define AHCI_PORT_IS_OFS (1 << 24)
644#define AHCI_PORT_IS_INFS (1 << 26)
645#define AHCI_PORT_IS_IFS (1 << 27)
646#define AHCI_PORT_IS_HDBS (1 << 28)
647#define AHCI_PORT_IS_HBFS (1 << 29)
648#define AHCI_PORT_IS_TFES (1 << 30)
649#define AHCI_PORT_IS_CPDS (1 << 31)
650
651#define AHCI_PORT_END_OF_OPERATION \
652 (AHCI_PORT_IS_DHRS | \
653 AHCI_PORT_IS_SDBS )
654
655#define AHCI_PORT_IS_ERROR \
656 (AHCI_PORT_IS_UFS | \
657 AHCI_PORT_IS_PCS | \
658 AHCI_PORT_IS_DMPS | \
659 AHCI_PORT_IS_PRCS | \
660 AHCI_PORT_IS_IPMS | \
661 AHCI_PORT_IS_OFS | \
662 AHCI_PORT_IS_INFS | \
663 AHCI_PORT_IS_IFS | \
664 AHCI_PORT_IS_HDBS | \
665 AHCI_PORT_IS_HBFS | \
666 AHCI_PORT_IS_TFES | \
667 AHCI_PORT_IS_CPDS)
668
669#define AHCI_PORT_IS_PERMANENT_ERROR \
670 (AHCI_PORT_IS_PCS | \
671 AHCI_PORT_IS_DMPS | \
672 AHCI_PORT_IS_PRCS | \
673 AHCI_PORT_IS_IPMS | \
674 AHCI_PORT_IS_CPDS )
675
676/** Evaluate end of operation status from port interrupt status.
677 *
678 * @param port_is Value of port interrupt status.
679 *
680 * @return Indicate end of operation status.
681 *
682 */
683static inline int ahci_port_is_end_of_operation(ahci_port_is_t port_is)
684{
685 return port_is.u32 & AHCI_PORT_END_OF_OPERATION;
686}
687
688/** Evaluate error status from port interrupt status.
689 *
690 * @param port_is Value of port interrupt status.
691 *
692 * @return Indicate error status.
693 *
694 */
695static inline int ahci_port_is_error(ahci_port_is_t port_is)
696{
697 return port_is.u32 & AHCI_PORT_IS_ERROR;
698}
699
700/** Evaluate permanent error status from port interrupt status.
701 *
702 * @param port_is Value of port interrupt status.
703 *
704 * @return Indicate permanent error status.
705 *
706 */
707static inline int ahci_port_is_permanent_error(ahci_port_is_t port_is)
708{
709 return port_is.u32 & AHCI_PORT_IS_PERMANENT_ERROR;
710}
711
712/** Evaluate task file error status from port interrupt status.
713 *
714 * @param port_is Value of port interrupt status.
715 *
716 * @return Indicate error status.
717 *
718 */
719static inline int ahci_port_is_tfes(ahci_port_is_t port_is)
720{
721 return port_is.u32 & AHCI_PORT_IS_TFES;
722}
723
724/** AHCI Memory register Port x Interrupt Enable. */
725typedef union {
726 struct {
727 /** Device to Host Register FIS Interrupt Enable. */
728 unsigned int dhre : 1;
729 /** PIO Setup FIS Interrupt Enable. */
730 unsigned int pse : 1;
731 /** DMA Setup FIS Interrupt Enable. */
732 unsigned int dse : 1;
733 /** Set Device Bits Interrupt Eenable. */
734 unsigned int sdbe : 1;
735 /** Unknown FIS Interrupt Enable. */
736 unsigned int ufe : 1;
737 /** Descriptor Processed Interrupt Enable. */
738 unsigned int dpe : 1;
739 /** Port Change Interrupt Enable. */
740 unsigned int pce : 1;
741 /** Device Mechanical Presence Enable. */
742 unsigned int dmpe : 1;
743 /** Reserved. */
744 unsigned int reserved1 : 14;
745 /** PhyRdy Change Interrupt Enable. */
746 unsigned int prce : 1;
747 /** Incorrect Port Multiplier Enable. */
748 unsigned int ipme : 1;
749 /** Overflow Status Enable. */
750 unsigned int ofe : 1;
751 /** Reserved. */
752 unsigned int reserved2 : 1;
753 /** Interface Non-fatal Error Enable. */
754 unsigned int infe : 1;
755 /** Interface Fatal Error Enable. */
756 unsigned int ife : 1;
757 /** Host Bus Data Error Enable. */
758 unsigned int hbde : 1;
759 /** Host Bus Fatal Error Enable. */
760 unsigned int hbfe : 1;
761 /** Task File Error Enable. */
762 unsigned int tfee : 1;
763 /** Cold Port Detect Enable. */
764 unsigned int cpde : 1;
765 } __attribute__((packed));
766 uint32_t u32;
767} __attribute__((packed)) ahci_port_ie_t;
768
769/** AHCI Memory register Port x Command and Status. */
770typedef union {
771 struct {
772 /** Start - when set, the HBA may process the command list. */
773 unsigned int st : 1;
774 /** Spin-Up Device. */
775 unsigned int sud : 1;
776 /** Power On Device. */
777 unsigned int pod : 1;
778 /** Command List Override. */
779 unsigned int clo : 1;
780 /** FIS Receive Enable. */
781 unsigned int fre : 1;
782 /** Reserved. */
783 unsigned int reserved : 3;
784 /** Current Command Slot. */
785 unsigned int ccs : 5;
786 /** Mechanical Presence Switch State. */
787 unsigned int mpss : 1;
788 /** FIS Receive Running. */
789 unsigned int fr : 1;
790 /** Command List Running. */
791 unsigned int cr : 1;
792 /** Cold Presence State. */
793 unsigned int cps : 1;
794 /** Port Multiplier Attached. */
795 unsigned int pma : 1;
796 /** Hot Plug Capable Port. */
797 unsigned int hpcp : 1;
798 /** Mechanical Presence Switch Attached to Port. */
799 unsigned int mpsp : 1;
800 /** Cold Presence Detection. */
801 unsigned int cpd : 1;
802 /** External SATA Port. */
803 unsigned int esp : 1;
804 /** FIS-based Switching Capable Port. */
805 unsigned int fbscp : 1;
806 /** Automatic Partial to Slumber Transitions Enabled. */
807 unsigned int apste : 1;
808 /** Device is ATAPI. */
809 unsigned int atapi : 1;
810 /** Drive LED on ATAPI Enable. */
811 unsigned int dlae : 1;
812 /** Aggressive Link Power Management Enable. */
813 unsigned int alpe : 1;
814 /** Aggressive Slumber / Partial. */
815 unsigned int asp : 1;
816 /** Interface Communication Control.
817 * Values:
818 * 7h - fh Reserved,
819 * 6h Slumber - This shall cause the HBA to request a transition of the
820 * interface to the Slumber state,
821 * 3h - 5h Reserved,
822 * 2h Partial - This shall cause the HBA to request a transition of the
823 * interface to the Partial state,
824 * 1h Active,
825 * 0h No-Op / Idle.
826 */
827 unsigned int icc : 4;
828 } __attribute__((packed));
829 uint32_t u32;
830} __attribute__((packed)) ahci_port_cmd_t;
831
832/** AHCI Memory register Port x Task File Data. */
833typedef union {
834 struct {
835 /** Status (STS): Contains the latest copy of the task file
836 * status register.
837 */
838 uint8_t sts;
839 /** Error (ERR) - Contains the latest copy of the task file
840 * error register.
841 */
842 uint8_t err;
843 /** Reserved. */
844 uint16_t reserved;
845 } __attribute__((packed));
846 uint32_t u32;
847} __attribute__((packed)) ahci_port_tfd_t;
848
849/** AHCI Memory register Port x Signature. */
850typedef union {
851 struct {
852 /** Sector Count Register */
853 uint8_t sector_count;
854 /** LBA Low Register */
855 uint8_t lba_lr;
856 /** LBA Mid Register */
857 uint8_t lba_mr;
858 /** LBA High Register */
859 uint8_t lba_hr;
860 } __attribute__((packed));
861 uint32_t u32;
862} __attribute__((packed)) ahci_port_sig_t;
863
864/** AHCI Memory register Port x Serial ATA Status (SCR0: SStatus). */
865typedef union {
866 struct {
867 /** Device Detection */
868 unsigned int det : 4;
869 /** Current Interface Speed */
870 unsigned int spd : 4;
871 /** Interface Power Management */
872 unsigned int ipm : 4;
873 /** Reserved. */
874 unsigned int reserved : 20;
875 } __attribute__((packed));
876 uint32_t u32;
877} __attribute__((packed)) ahci_port_ssts_t;
878
879/** AHCI Memory register Port x Serial ATA Control (SCR2: SControl). */
880typedef union {
881 struct {
882 /** Device Detection Initialization */
883 unsigned int det : 4;
884 /** Speed Allowed */
885 unsigned int spd : 4;
886 /** Interface Power Management Transitions Allowed */
887 unsigned int ipm : 4;
888 /** Reserved. */
889 unsigned int reserved : 20;
890 } __attribute__((packed));
891 uint32_t u32;
892} __attribute__((packed)) ahci_port_sctl_t;
893
894/** AHCI Memory register Port x Port x Serial ATA Error (SCR1: SError). */
895typedef struct {
896 /** Error (ERR) - The ERR field contains error information for use
897 * by host software in determining the appropriate response to the
898 * error condition.
899 */
900 uint16_t err;
901 /** Diagnostics (DIAG) - Contains diagnostic error information for use
902 * by diagnostic software in validating correct operation or isolating
903 * failure modes.
904 */
905 uint16_t diag;
906} __attribute__((packed)) ahci_port_serr_t;
907
908/** AHCI Memory register Port x Serial ATA Active (SCR3: SActive). */
909typedef struct {
910 /** Device Status - Each bit corresponds to the TAG and
911 * command slot of a native queued command, where bit 0 corresponds
912 * to TAG 0 and command slot 0.
913 */
914 uint32_t u32;
915} __attribute__((packed)) ahci_port_sact_t;
916
917/** AHCI Memory register Port x Command Issue. */
918typedef struct {
919 /** Commands Issued - Each bit corresponds to a command slot,
920 * where bit 0 corresponds to command slot 0.
921 */
922 uint32_t u32;
923} __attribute__((packed)) ahci_port_ci_t;
924
925/** AHCI Memory register Port x Serial ATA Notification
926 * (SCR4: SNotification).
927 */
928typedef struct {
929 /** PM Notify (PMN): This field indicates whether a particular device with
930 * the corresponding PM Port number issued a Set Device Bits FIS
931 * to the host with the Notification bit set.
932 */
933 uint16_t pmn;
934 /** Reserved. */
935 uint16_t reserved;
936} __attribute__((packed)) ahci_port_sntf_t;
937
938/** AHCI Memory register Port x FIS-based Switching Control.
939 * This register is used to control and obtain status
940 * for Port Multiplier FIS-based switching.
941 */
942typedef union {
943 struct {
944 /** Enable */
945 unsigned int en : 1;
946 /** Device Error Clear */
947 unsigned int dec : 1;
948 /** Single Device Error */
949 unsigned int sde : 1;
950 /** Reserved. */
951 unsigned int reserved1 : 5;
952 /** Device To Issue */
953 unsigned int dev : 1;
954 /** Active Device Optimization */
955 unsigned int ado : 1;
956 /** Device With Error */
957 unsigned int dwe : 1;
958 /** Reserved. */
959 unsigned int reserved2 : 1;
960 } __attribute__((packed));
961 uint32_t u32;
962} __attribute__((packed)) ahci_port_fbs_t;
963
964/** AHCI Memory register Port. */
965typedef volatile struct
966{
967 /** Port x Command List Base Address. */
968 uint32_t pxclb;
969 /** Port x Command List Base Address Upper 32-Bits. */
970 uint32_t pxclbu;
971 /** Port x FIS Base Address. */
972 uint32_t pxfb;
973 /** Port x FIS Base Address Upper 32-Bits. */
974 uint32_t pxfbu;
975 /** Port x Interrupt Status. */
976 uint32_t pxis;
977 /** Port x Interrupt Enable. */
978 uint32_t pxie;
979 /** Port x Command and Status. */
980 uint32_t pxcmd;
981 /** Reserved. */
982 uint32_t reserved1;
983 /** Port x Task File Data. */
984 uint32_t pxtfd;
985 /** Port x Signature. */
986 uint32_t pxsig;
987 /** Port x Serial ATA Status (SCR0: SStatus). */
988 uint32_t pxssts;
989 /** Port x Serial ATA Control (SCR2: SControl). */
990 uint32_t pxsctl;
991 /** Port x Serial ATA Error (SCR1: SError). */
992 uint32_t pxserr;
993 /** Port x Serial ATA Active (SCR3: SActive). */
994 uint32_t pxsact;
995 /** Port x Command Issue. */
996 uint32_t pxci;
997 /** Port x Serial ATA Notification (SCR4: SNotification). */
998 uint32_t pxsntf;
999 /** Port x FIS-based Switching Control. */
1000 uint32_t pxfbs;
1001 /** Reserved. */
1002 uint32_t reserved2[11];
1003 /** Port x Vendor Specific. */
1004 uint32_t pxvs[4];
1005} __attribute__((packed)) ahci_port_t;
1006
1007/** AHCI Memory Registers. */
1008typedef volatile struct {
1009 /** Generic Host Control. */
1010 ahci_ghc_t ghc;
1011 /** Reserved. */
1012 uint8_t reserved[52];
1013 /** Reserved for NVMHCI. */
1014 uint8_t reservedfornvmhci[64];
1015 /** Vendor Specific registers. */
1016 uint8_t vendorspecificsregs[96];
1017 /** Ports. */
1018 ahci_port_t ports[32];
1019} __attribute__((packed)) ahci_memregs_t;
1020
1021/** AHCI Command header entry. */
1022typedef volatile struct {
1023 /** Flags. */
1024 uint16_t flags;
1025 /** Physical Region Descriptor Table Length. */
1026 uint16_t prdtl;
1027 /** Physical Region Descriptor Byte Count. */
1028 uint32_t bytesprocessed;
1029 /** Command Table Descriptor Base Address. */
1030 uint32_t cmdtable;
1031 /** Command Table Descriptor Base Address Upper 32-bits. */
1032 uint32_t cmdtableu;
1033} __attribute__((packed)) ahci_cmdhdr_t;
1034
1035/** AHCI Command Physical Region Descriptor entry. */
1036typedef volatile struct {
1037 /** Word aligned 32-bit data base address. */
1038 uint32_t data_address_low;
1039 /** Upper data base address, valid only for 64-bit HBA addressing. */
1040 uint32_t data_address_upper;
1041 /** Reserved. */
1042 uint32_t reserved1;
1043 /** Data byte count */
1044 unsigned int dbc : 22;
1045 /** Reserved */
1046 unsigned int reserved2 : 9;
1047 /** Interrupt on completion */
1048 unsigned int ioc : 1;
1049} __attribute__((packed)) ahci_cmd_prdt_t;
1050
1051#endif
Note: See TracBrowser for help on using the repository browser.