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
11 * advanced host controller interface (sata)
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 */
27 Efatal = Eidnf | Eicrc, /* must sw reset */
32 ASerr = 1 << 0, /* error */
33 ASdrq = 1 << 3, /* request */
34 ASdf = 1 << 5, /* fault, command specific */
35 ASdrdy = 1 << 6, /* ready, command specific */
36 ASbsy = 1 << 7, /* busy */
38 ASobs = 1 << 1 | 1 << 2 | 1 << 4,
41 /* pci configuration */
47 * ahci memory configuration
49 * 0000-0023 generic host control
51 * 00a0-00ff vendor specific.
57 /* Capability bits: supported features */
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 */
69 Hsam = 1 << 18, /* ahci-mode only */
70 Hspm = 1 << 17, /* port multiplier */
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 */
84 Hae = 1 << 31, /* enable ahci */
85 Hie = 1 << 1, /* " interrupts */
86 Hhr = 1 << 0, /* hba reset */
89 #define HBA_CAP 0x00 // Host Capabilities
90 #define HBA_GHC 0x04 // Global Host Control
91 #define HBA_ISR 0x08 // Interrupt Status Register
92 #define HBA_PI 0x0C // Ports Implemented
93 #define HBA_VS 0x10 // Version
94 #define HBA_CCC_CTL 0x14 // Command Completion Coalescing Control
95 #define HBA_CCC_PORTS 0x18 // Command Completion Coalescing Ports
96 #define HBA_EM_LOC 0x1C // Enclosure Management Location
97 #define HBA_EM_CTL 0x20 // Enclosure Management Control
98 #define HBA_CAP2 0x24 // Host Capabilities Extended
99 #define HBA_BOHC 0x28 // BIOS/OS Hand-Off Control and Status
101 /* Interrupt Status bits */
103 Acpds = 1 << 31, /* cold port detect status */
104 Atfes = 1 << 30, /* task file error status */
105 Ahbfs = 1 << 29, /* hba fatal */
106 Ahbds = 1 << 28, /* hba error (parity error) */
107 Aifs = 1 << 27, /* interface fatal §6.1.2 */
108 Ainfs = 1 << 26, /* interface error (recovered) */
109 Aofs = 1 << 24, /* too many bytes from disk */
110 Aipms = 1 << 23, /* incorrect prt mul status */
111 Aprcs = 1 << 22, /* PhyRdy change status Pxserr.diag.n */
112 Adpms = 1 << 7, /* mechanical presence status */
113 Apcs = 1 << 6, /* port connect diag.x */
114 Adps = 1 << 5, /* descriptor processed */
115 Aufs = 1 << 4, /* unknown fis diag.f */
116 Asdbs = 1 << 3, /* set device bits fis received w/ i bit set */
117 Adss = 1 << 2, /* dma setup */
118 Apio = 1 << 1, /* pio setup fis */
119 Adhrs = 1 << 0, /* device to host register fis */
121 IEM = Acpds | Atfes | Ahbds | Ahbfs | Ahbds | Aifs | Ainfs | Aprcs | Apcs |
122 Adps | Aufs | Asdbs | Adss | Adhrs,
123 Ifatal = Atfes | Ahbfs | Ahbds | Aifs,
128 SerrX = 1 << 26, /* exchanged */
129 SerrF = 1 << 25, /* unknown fis */
130 SerrT = 1 << 24, /* transition error */
131 SerrS = 1 << 23, /* link sequence */
132 SerrH = 1 << 22, /* handshake */
133 SerrC = 1 << 21, /* crc */
134 SerrD = 1 << 20, /* not used by ahci */
135 SerrB = 1 << 19, /* 10-tp-8 decode */
136 SerrW = 1 << 18, /* comm wake */
137 SerrI = 1 << 17, /* phy internal */
138 SerrN = 1 << 16, /* phyrdy change */
140 ErrE = 1 << 11, /* internal */
141 ErrP = 1 << 10, /* ata protocol violation */
142 ErrC = 1 << 9, /* communication */
143 ErrT = 1 << 8, /* transient */
144 ErrM = 1 << 1, /* recoverd comm */
145 ErrI = 1 << 0, /* recovered data integrety */
147 ErrAll = ErrE | ErrP | ErrC | ErrT | ErrM | ErrI,
148 SerrAll = SerrX | SerrF | SerrT | SerrS | SerrH | SerrC | SerrD | SerrB |
149 SerrW | SerrI | SerrN | ErrAll,
150 SerrBad = 0x7f << 19,
153 /* Command/Status register bits */
155 Aicc = 1 << 28, /* interface communcations control. 4 bits */
156 Aasp = 1 << 27, /* aggressive slumber & partial sleep */
157 Aalpe = 1 << 26, /* aggressive link pm enable */
158 Adlae = 1 << 25, /* drive led on atapi */
159 Aatapi = 1 << 24, /* device is atapi */
160 Aesp = 1 << 21, /* external sata port */
161 Acpd = 1 << 20, /* cold presence detect */
162 Ampsp = 1 << 19, /* mechanical pres. */
163 Ahpcp = 1 << 18, /* hot plug capable */
164 Apma = 1 << 17, /* pm attached */
165 Acps = 1 << 16, /* cold presence state */
166 Acr = 1 << 15, /* cmdlist running */
167 Afr = 1 << 14, /* fis running */
168 Ampss = 1 << 13, /* mechanical presence switch state */
169 Accs = 1 << 8, /* current command slot 12:08 */
170 Afre = 1 << 4, /* fis enable receive */
171 Aclo = 1 << 3, /* command list override */
172 Apod = 1 << 2, /* power on dev (requires cold-pres. detect) */
173 Asud = 1 << 1, /* spin-up device; requires ss capability */
174 Ast = 1 << 0, /* start */
176 Arun = Ast | Acr | Afre | Afr,
179 /* SControl register bits */
181 Aipm = 1 << 8, /* interface power mgmt. 3=off */
183 Adis = 1 << 2, // Disable SATA interface and put Phy in offline mode
184 Adet = 1 << 0, /* device detection */
187 #define PORT_CLB 0x00 // Port Command List Base address
188 #define PORT_CLBU 0x04 // Port Command List Base address Upper 32-bits
189 #define PORT_FB 0x08 // Port FIS Base address
190 #define PORT_FBU 0x0C // Port FIS Base address Upper 32-bits
191 #define PORT_IS 0x10 // Port Interrupt Status
192 #define PORT_IE 0x14 // Port Interrupt Enable
193 #define PORT_CMD 0x18 // Port Command and status
194 #define PORT_RES1 0x1C // Reserved
195 #define PORT_TFD 0x20 // Port Task File Data
196 #define PORT_SIG 0x24 // Port Signature
197 #define PORT_SSTS 0x28 // Port Serial ATA Status (SCR0: SStatus)
198 #define PORT_SCTL 0x2C // Port Serial ATA Control (SCR2: SControl)
199 #define PORT_SERR 0x30 // Port Serial ATA Error (SCR1: SError)
200 #define PORT_SACT 0x34 // Port Serial ATA Active (SCR3: SActive)
201 #define PORT_CI 0x38 // Port Command Issue
202 #define PORT_SNTF 0x3C // Port Serial ATA Notification (SCR4: SNotification)
203 #define PORT_FBS 0x40 // Port FIS-Based Switching control
204 #define PORT_DEVSLP 0x44 // Port Device Sleep
205 #define PORT_RES2 0x48 // Reserved
206 #define PORT_VS 0x70 // Vendor Specific
210 * Aport sstatus bits (actually states):
211 * 11-8 interface power management
212 * 7-4 current interface speed (generation #)
213 * 3-0 device detection
221 Devphycomm = 2, /* phy communication established */
223 Devdet = Devpresent | Devphycomm | Devphyoffline,
226 /* in host's memory; not memory mapped */
233 uint32_t *devicebits;
236 // Command header flags
238 Lprdtl = 1 << 16, /* physical region descriptor table len */
239 Lpmp = 1 << 12, /* port multiplier port */
240 Lclear = 1 << 10, /* clear busy on R_OK */
243 Lpref = 1 << 7, /* prefetchable */
246 Lcfl = 1 << 0, /* command fis length in double words */
249 // AHCI Command List Command Header
250 // Each header is an element in the list which is up to 32 elements long
251 #define ALIST_SIZE 0x20 // Size of the struct in memory, not for access
252 #define ALIST_FLAGS 0x00 // Flags and PRDTL (PRDT Length)
253 #define ALIST_LEN 0x04 // PRD byte count transferred
254 #define ALIST_CTAB 0x08 // Physical address of 128-bit aligned Command Table
255 #define ALIST_CTABHI 0x0C // CTAB physical address upper 32 bits
256 #define ALIST_RES 0x10 // Reserved
258 // AHCI Physical Region Descriptor Table Element
259 // Each of these elements is part of a table with up to 65,535 entries
260 #define APRDT_SIZE 0x10 // Size of the struct in memory, not for access
261 #define APRDT_DBA 0x00 // Data Base Address (physical)
262 #define APRDT_DBAHI 0x04 // Data Base Address upper 32 bits
263 #define APRDT_RES 0x08 // Reserved
264 #define APRDT_COUNT 0x0C // 31=Intr on Completion, 30:22=Reserved, 21:0=DBC
266 // AHCI Command Table
267 // Note that there is no fixed size specified - there are 1 to 65,535 PRDT's
268 // Size = ACTAB_PRDT + APRDT*N_APRDT
269 #define ACTAB_CFIS 0x00 // Command Frame Information Struct (up to 64 bytes)
270 #define ACTAB_ATAPI 0x40 // ATAPI Command (12 or 16 bytes)
271 #define ACTAB_RES 0x50 // Reserved
272 #define ACTAB_PRDT 0x80 // PRDT (up to 65,535 entries in spec, this has one)
274 // Portm flags (status flags?)
280 // Portm feature flags
292 struct rendez Rendez;