ahci.h 7.1 KB

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