ahci.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. #include "ahci.h"
  2. #include "../../../common/kprint.h"
  3. #include "../../../mm/slab.h"
  4. struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES];
  5. uint32_t count_ahci_devices = 0;
  6. uint64_t ahci_port_base_vaddr; // 端口映射base addr
  7. static void start_cmd(HBA_PORT *port);
  8. static void stop_cmd(HBA_PORT *port);
  9. static void port_rebase(HBA_PORT *port, int portno);
  10. // Find a free command list slot
  11. static int ahci_find_cmdslot(HBA_PORT *port);
  12. // 计算HBA_MEM的虚拟内存地址
  13. #define cal_HBA_MEM_VIRT_ADDR(device_num) (AHCI_MAPPING_BASE + (ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[device_num]))->BAR5 - ((((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5) & PAGE_2M_MASK)))
  14. /**
  15. * @brief 初始化ahci模块
  16. *
  17. */
  18. void ahci_init()
  19. {
  20. pci_get_device_structure(0x1, 0x6, ahci_devs, &count_ahci_devices);
  21. kdebug("phys addr=%#018lx", (ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5));
  22. // 映射ABAR
  23. mm_map_phys_addr(AHCI_MAPPING_BASE, ((ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5)) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
  24. kdebug("ABAR mapped!");
  25. for (int i = 0; i < count_ahci_devices; ++i)
  26. {
  27. kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
  28. // 赋值HBA_MEM结构体
  29. ahci_devices[i].dev_struct = ahci_devs[i];
  30. ahci_devices[i].hba_mem = (HBA_MEM *)(cal_HBA_MEM_VIRT_ADDR(i));
  31. }
  32. ahci_port_base_vaddr = (uint64_t)kmalloc(1048576, 0);
  33. ahci_probe_port(0);
  34. port_rebase(&ahci_devices[0].hba_mem->ports[0], 0);
  35. uint64_t buf[100];
  36. bool res = ahci_read(&(ahci_devices[0].hba_mem->ports[0]), 0, 0, 1, (uint64_t)&buf);
  37. kdebug("res=%d, buf[0]=%#010lx", (uint)res, (uint32_t)buf[0]);
  38. buf[0] = 0xa0;
  39. res = ahci_write(&(ahci_devices[0].hba_mem->ports[0]), 0, 0, 1, (uint64_t)&buf);
  40. res = ahci_read(&(ahci_devices[0].hba_mem->ports[0]), 0, 0, 1, (uint64_t)&buf);
  41. kdebug("res=%d, buf[0]=%#010lx", (uint)res, (uint32_t)buf[0]);
  42. }
  43. // Check device type
  44. static int check_type(HBA_PORT *port)
  45. {
  46. uint32_t ssts = port->ssts;
  47. uint8_t ipm = (ssts >> 8) & 0x0F;
  48. uint8_t det = ssts & 0x0F;
  49. if (det != HBA_PORT_DET_PRESENT) // Check drive status
  50. return AHCI_DEV_NULL;
  51. if (ipm != HBA_PORT_IPM_ACTIVE)
  52. return AHCI_DEV_NULL;
  53. switch (port->sig)
  54. {
  55. case SATA_SIG_ATAPI:
  56. return AHCI_DEV_SATAPI;
  57. case SATA_SIG_SEMB:
  58. return AHCI_DEV_SEMB;
  59. case SATA_SIG_PM:
  60. return AHCI_DEV_PM;
  61. default:
  62. return AHCI_DEV_SATA;
  63. }
  64. }
  65. /**
  66. * @brief 检测端口连接的设备的类型
  67. *
  68. * @param device_num ahci设备号
  69. */
  70. void ahci_probe_port(const uint32_t device_num)
  71. {
  72. HBA_MEM *abar = ahci_devices[device_num].hba_mem;
  73. uint32_t pi = abar->pi;
  74. for (int i = 0; i < 32; ++i, (pi >>= 1))
  75. {
  76. if (pi & 1)
  77. {
  78. uint dt = check_type(&abar->ports[i]);
  79. ahci_devices[i].type = dt;
  80. if (dt == AHCI_DEV_SATA)
  81. {
  82. kdebug("SATA drive found at port %d", i);
  83. }
  84. else if (dt == AHCI_DEV_SATAPI)
  85. {
  86. kdebug("SATAPI drive found at port %d", i);
  87. }
  88. else if (dt == AHCI_DEV_SEMB)
  89. {
  90. kdebug("SEMB drive found at port %d", i);
  91. }
  92. else if (dt == AHCI_DEV_PM)
  93. {
  94. kdebug("PM drive found at port %d", i);
  95. }
  96. else
  97. {
  98. kdebug("No drive found at port %d", i);
  99. }
  100. }
  101. }
  102. }
  103. // Start command engine
  104. static void start_cmd(HBA_PORT *port)
  105. {
  106. // Wait until CR (bit15) is cleared
  107. while (port->cmd & HBA_PxCMD_CR)
  108. ;
  109. // Set FRE (bit4) and ST (bit0)
  110. port->cmd |= HBA_PxCMD_FRE;
  111. port->cmd |= HBA_PxCMD_ST;
  112. }
  113. // Stop command engine
  114. static void stop_cmd(HBA_PORT *port)
  115. {
  116. // Clear ST (bit0)
  117. port->cmd &= ~HBA_PxCMD_ST;
  118. // Clear FRE (bit4)
  119. port->cmd &= ~HBA_PxCMD_FRE;
  120. // Wait until FR (bit14), CR (bit15) are cleared
  121. while (1)
  122. {
  123. if (port->cmd & HBA_PxCMD_FR)
  124. continue;
  125. if (port->cmd & HBA_PxCMD_CR)
  126. continue;
  127. break;
  128. }
  129. }
  130. static void port_rebase(HBA_PORT *port, int portno)
  131. {
  132. // Before rebasing Port memory space, OS must wait for current pending commands to finish
  133. // and tell HBA to stop receiving FIS from the port. Otherwise an accidently incoming FIS may be
  134. // written into a partially configured memory area.
  135. stop_cmd(port); // Stop command engine
  136. // Command list offset: 1K*portno
  137. // Command list entry size = 32
  138. // Command list entry maxim count = 32
  139. // Command list maxim size = 32*32 = 1K per port
  140. port->clb = ahci_port_base_vaddr + (portno << 10);
  141. memset((void *)(port->clb), 0, 1024);
  142. // FIS offset: 32K+256*portno
  143. // FIS entry size = 256 bytes per port
  144. port->fb = ahci_port_base_vaddr + (32 << 10) + (portno << 8);
  145. memset((void *)(port->fb), 0, 256);
  146. // Command table offset: 40K + 8K*portno
  147. // Command table size = 256*32 = 8K per port
  148. HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)(port->clb);
  149. for (int i = 0; i < 32; ++i)
  150. {
  151. cmdheader[i].prdtl = 8; // 8 prdt entries per command table
  152. // 256 bytes per command table, 64+16+48+16*8
  153. // Command table offset: 40K + 8K*portno + cmdheader_index*256
  154. cmdheader[i].ctba = ahci_port_base_vaddr + (40 << 10) + (portno << 13) + (i << 8);
  155. memset((void *)cmdheader[i].ctba, 0, 256);
  156. }
  157. start_cmd(port); // Start command engine
  158. }
  159. /**
  160. * @brief read data from SATA device using 48bit LBA address
  161. *
  162. * @param port HBA PORT
  163. * @param startl low 32bits of start addr
  164. * @param starth high 32bits of start addr
  165. * @param count total sectors to read
  166. * @param buf buffer
  167. * @return true done
  168. * @return false failed
  169. */
  170. bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count, uint64_t buf)
  171. {
  172. port->is = (uint32_t)-1; // Clear pending interrupt bits
  173. int spin = 0; // Spin lock timeout counter
  174. int slot = ahci_find_cmdslot(port);
  175. if (slot == -1)
  176. return false;
  177. HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
  178. cmdheader += slot;
  179. cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
  180. cmdheader->w = 0; // Read from device
  181. cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
  182. HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
  183. memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
  184. // 8K bytes (16 sectors) per PRDT
  185. int i;
  186. for (i = 0; i < cmdheader->prdtl - 1; ++i)
  187. {
  188. cmdtbl->prdt_entry[i].dba = buf;
  189. cmdtbl->prdt_entry[i].dbc = 8 * 1024 - 1; // 8K bytes (this value should always be set to 1 less than the actual value)
  190. cmdtbl->prdt_entry[i].i = 1;
  191. buf += 4 * 1024; // 4K uint16_ts
  192. count -= 16; // 16 sectors
  193. }
  194. // Last entry
  195. cmdtbl->prdt_entry[i].dba = buf;
  196. cmdtbl->prdt_entry[i].dbc = (count << 9) - 1; // 512 bytes per sector
  197. cmdtbl->prdt_entry[i].i = 1;
  198. // Setup command
  199. FIS_REG_H2D *cmdfis = (FIS_REG_H2D *)(&cmdtbl->cfis);
  200. cmdfis->fis_type = FIS_TYPE_REG_H2D;
  201. cmdfis->c = 1; // Command
  202. cmdfis->command = ATA_CMD_READ_DMA_EXT;
  203. cmdfis->lba0 = (uint8_t)startl;
  204. cmdfis->lba1 = (uint8_t)(startl >> 8);
  205. cmdfis->lba2 = (uint8_t)(startl >> 16);
  206. cmdfis->device = 1 << 6; // LBA mode
  207. cmdfis->lba3 = (uint8_t)(startl >> 24);
  208. cmdfis->lba4 = (uint8_t)starth;
  209. cmdfis->lba5 = (uint8_t)(starth >> 8);
  210. cmdfis->countl = count & 0xFF;
  211. cmdfis->counth = (count >> 8) & 0xFF;
  212. // The below loop waits until the port is no longer busy before issuing a new command
  213. while ((port->tfd & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && spin < 1000000)
  214. {
  215. spin++;
  216. }
  217. if (spin == 1000000)
  218. {
  219. kerror("Port is hung");
  220. return false;
  221. }
  222. kdebug("slot=%d", slot);
  223. port->ci = 1 << slot; // Issue command
  224. // Wait for completion
  225. while (1)
  226. {
  227. // In some longer duration reads, it may be helpful to spin on the DPS bit
  228. // in the PxIS port field as well (1 << 5)
  229. if ((port->ci & (1 << slot)) == 0)
  230. break;
  231. if (port->is & HBA_PxIS_TFES) // Task file error
  232. {
  233. kerror("Read disk error");
  234. return false;
  235. }
  236. }
  237. // Check again
  238. if (port->is & HBA_PxIS_TFES)
  239. {
  240. kerror("Read disk error");
  241. return false;
  242. }
  243. return true;
  244. }
  245. bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count,
  246. uint64_t buf)
  247. {
  248. printk("Inside writeport \n ");
  249. port->is = 0xffff; // Clear pending interrupt bits
  250. int slot = ahci_find_cmdslot(port);
  251. if (slot == -1)
  252. return false;
  253. HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
  254. cmdheader += slot;
  255. cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
  256. cmdheader->w = 1;
  257. cmdheader->c = 1;
  258. cmdheader->p = 1;
  259. cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
  260. HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
  261. memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
  262. int i = 0;
  263. for (i = 0; i < cmdheader->prdtl - 1; i++)
  264. {
  265. cmdtbl->prdt_entry[i].dba = buf;
  266. cmdtbl->prdt_entry[i].dbc = 8 * 1024 - 1; // 8K bytes
  267. cmdtbl->prdt_entry[i].i = 0;
  268. buf += 4 * 1024; // 4K words
  269. count -= 16; // 16 sectors
  270. }
  271. cmdtbl->prdt_entry[i].dba = buf;
  272. cmdtbl->prdt_entry[i].dbc = count << 9; // 512 bytes per sector
  273. cmdtbl->prdt_entry[i].i = 0;
  274. FIS_REG_H2D *cmdfis = (FIS_REG_H2D *)(&cmdtbl->cfis);
  275. cmdfis->fis_type = FIS_TYPE_REG_H2D;
  276. cmdfis->c = 1; // Command
  277. cmdfis->command = ATA_CMD_WRITE_DMA_EXT;
  278. cmdfis->lba0 = (uint8_t)startl;
  279. cmdfis->lba1 = (uint8_t)(startl >> 8);
  280. cmdfis->lba2 = (uint8_t)(startl >> 16);
  281. cmdfis->lba3 = (uint8_t)(startl >> 24);
  282. cmdfis->lba4 = (uint8_t)starth;
  283. cmdfis->lba5 = (uint8_t)(starth >> 8);
  284. cmdfis->device = 1 << 6; // LBA mode
  285. cmdfis->countl = count & 0xff;
  286. cmdfis->counth = count >> 8;
  287. // printk("[slot]{%d}", slot);
  288. port->ci = 1; // Issue command
  289. while (1)
  290. {
  291. // In some longer duration reads, it may be helpful to spin on the DPS bit
  292. // in the PxIS port field as well (1 << 5)
  293. if ((port->ci & (1 << slot)) == 0)
  294. break;
  295. if (port->is & HBA_PxIS_TFES)
  296. { // Task file error
  297. kerror("Write disk error");
  298. return false;
  299. }
  300. }
  301. if (port->is & HBA_PxIS_TFES)
  302. {
  303. kerror("Write disk error");
  304. return false;
  305. }
  306. return true;
  307. }
  308. // Find a free command list slot
  309. static int ahci_find_cmdslot(HBA_PORT *port)
  310. {
  311. // If not set in SACT and CI, the slot is free
  312. uint32_t slots = (port->sact | port->ci);
  313. int num_of_cmd_clots = (ahci_devices[0].hba_mem->cap & 0x0f00) >> 8; // bit 12-8
  314. for (int i = 0; i < num_of_cmd_clots; i++)
  315. {
  316. if ((slots & 1) == 0)
  317. return i;
  318. slots >>= 1;
  319. }
  320. kerror("Cannot find free command list entry");
  321. return -1;
  322. }