ahci.h 7.9 KB

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