ahci.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  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. static long ahci_query_disk();
  11. // Find a free command list slot
  12. static int ahci_find_cmdslot(HBA_PORT *port);
  13. // 计算HBA_MEM的虚拟内存地址
  14. #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)))
  15. /**
  16. * @brief 初始化ahci模块
  17. *
  18. */
  19. void ahci_init()
  20. {
  21. pci_get_device_structure(0x1, 0x6, ahci_devs, &count_ahci_devices);
  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. // todo: 支持多个ahci控制器。
  33. ahci_port_base_vaddr = (uint64_t)kmalloc(1048576, 0);
  34. ahci_probe_port(0);
  35. port_rebase(&ahci_devices[0].hba_mem->ports[0], 0);
  36. // 初始化请求队列
  37. ahci_req_queue.in_service = NULL;
  38. list_init(&(ahci_req_queue.queue_list));
  39. ahci_req_queue.request_count = 0;
  40. }
  41. // Check device type
  42. static int check_type(HBA_PORT *port)
  43. {
  44. uint32_t ssts = port->ssts;
  45. uint8_t ipm = (ssts >> 8) & 0x0F;
  46. uint8_t det = ssts & 0x0F;
  47. if (det != HBA_PORT_DET_PRESENT) // Check drive status
  48. return AHCI_DEV_NULL;
  49. if (ipm != HBA_PORT_IPM_ACTIVE)
  50. return AHCI_DEV_NULL;
  51. switch (port->sig)
  52. {
  53. case SATA_SIG_ATAPI:
  54. return AHCI_DEV_SATAPI;
  55. case SATA_SIG_SEMB:
  56. return AHCI_DEV_SEMB;
  57. case SATA_SIG_PM:
  58. return AHCI_DEV_PM;
  59. default:
  60. return AHCI_DEV_SATA;
  61. }
  62. }
  63. /**
  64. * @brief 检测端口连接的设备的类型
  65. *
  66. * @param device_num ahci控制器号
  67. */
  68. static void ahci_probe_port(const uint32_t device_num)
  69. {
  70. HBA_MEM *abar = ahci_devices[device_num].hba_mem;
  71. uint32_t pi = abar->pi;
  72. for (int i = 0; i < 32; ++i, (pi >>= 1))
  73. {
  74. if (pi & 1)
  75. {
  76. uint dt = check_type(&abar->ports[i]);
  77. ahci_devices[i].type = dt;
  78. if (dt == AHCI_DEV_SATA)
  79. {
  80. kdebug("SATA drive found at port %d", i);
  81. }
  82. else if (dt == AHCI_DEV_SATAPI)
  83. {
  84. kdebug("SATAPI drive found at port %d", i);
  85. }
  86. else if (dt == AHCI_DEV_SEMB)
  87. {
  88. kdebug("SEMB drive found at port %d", i);
  89. }
  90. else if (dt == AHCI_DEV_PM)
  91. {
  92. kdebug("PM drive found at port %d", i);
  93. }
  94. else
  95. {
  96. // kdebug("No drive found at port %d", i);
  97. }
  98. }
  99. }
  100. }
  101. // Start command engine
  102. static void start_cmd(HBA_PORT *port)
  103. {
  104. // Wait until CR (bit15) is cleared
  105. while (port->cmd & HBA_PxCMD_CR)
  106. ;
  107. // Set FRE (bit4) and ST (bit0)
  108. port->cmd |= HBA_PxCMD_FRE;
  109. port->cmd |= HBA_PxCMD_ST;
  110. }
  111. // Stop command engine
  112. static void stop_cmd(HBA_PORT *port)
  113. {
  114. // Clear ST (bit0)
  115. port->cmd &= ~HBA_PxCMD_ST;
  116. // Clear FRE (bit4)
  117. port->cmd &= ~HBA_PxCMD_FRE;
  118. // Wait until FR (bit14), CR (bit15) are cleared
  119. while (1)
  120. {
  121. if (port->cmd & HBA_PxCMD_FR)
  122. continue;
  123. if (port->cmd & HBA_PxCMD_CR)
  124. continue;
  125. break;
  126. }
  127. }
  128. static void port_rebase(HBA_PORT *port, int portno)
  129. {
  130. // Before rebasing Port memory space, OS must wait for current pending commands to finish
  131. // and tell HBA to stop receiving FIS from the port. Otherwise an accidently incoming FIS may be
  132. // written into a partially configured memory area.
  133. stop_cmd(port); // Stop command engine
  134. // Command list offset: 1K*portno
  135. // Command list entry size = 32
  136. // Command list entry maxim count = 32
  137. // Command list maxim size = 32*32 = 1K per port
  138. port->clb = ahci_port_base_vaddr + (portno << 10);
  139. memset((void *)(port->clb), 0, 1024);
  140. // FIS offset: 32K+256*portno
  141. // FIS entry size = 256 bytes per port
  142. port->fb = ahci_port_base_vaddr + (32 << 10) + (portno << 8);
  143. memset((void *)(port->fb), 0, 256);
  144. // Command table offset: 40K + 8K*portno
  145. // Command table size = 256*32 = 8K per port
  146. HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)(port->clb);
  147. for (int i = 0; i < 32; ++i)
  148. {
  149. cmdheader[i].prdtl = 8; // 8 prdt entries per command table
  150. // 256 bytes per command table, 64+16+48+16*8
  151. // Command table offset: 40K + 8K*portno + cmdheader_index*256
  152. cmdheader[i].ctba = ahci_port_base_vaddr + (40 << 10) + (portno << 13) + (i << 8);
  153. memset((void *)cmdheader[i].ctba, 0, 256);
  154. }
  155. start_cmd(port); // Start command engine
  156. }
  157. /**
  158. * @brief read data from SATA device using 48bit LBA address
  159. *
  160. * @param port HBA PORT
  161. * @param startl low 32bits of start addr
  162. * @param starth high 32bits of start addr
  163. * @param count total sectors to read
  164. * @param buf buffer
  165. * @return true done
  166. * @return false failed
  167. */
  168. static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count, uint64_t buf)
  169. {
  170. port->is = (uint32_t)-1; // Clear pending interrupt bits
  171. int spin = 0; // Spin lock timeout counter
  172. int slot = ahci_find_cmdslot(port);
  173. if (slot == -1)
  174. return E_NOEMPTYSLOT;
  175. HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
  176. cmdheader += slot;
  177. cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
  178. cmdheader->w = 0; // Read from device
  179. cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
  180. HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
  181. memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
  182. // 8K bytes (16 sectors) per PRDT
  183. int i;
  184. for (i = 0; i < cmdheader->prdtl - 1; ++i)
  185. {
  186. cmdtbl->prdt_entry[i].dba = buf;
  187. cmdtbl->prdt_entry[i].dbc = 8 * 1024 - 1; // 8K bytes (this value should always be set to 1 less than the actual value)
  188. cmdtbl->prdt_entry[i].i = 1;
  189. buf += 4 * 1024; // 4K uint16_ts
  190. count -= 16; // 16 sectors
  191. }
  192. // Last entry
  193. cmdtbl->prdt_entry[i].dba = buf;
  194. cmdtbl->prdt_entry[i].dbc = (count << 9) - 1; // 512 bytes per sector
  195. cmdtbl->prdt_entry[i].i = 1;
  196. // Setup command
  197. FIS_REG_H2D *cmdfis = (FIS_REG_H2D *)(&cmdtbl->cfis);
  198. cmdfis->fis_type = FIS_TYPE_REG_H2D;
  199. cmdfis->c = 1; // Command
  200. cmdfis->command = ATA_CMD_READ_DMA_EXT;
  201. cmdfis->lba0 = (uint8_t)startl;
  202. cmdfis->lba1 = (uint8_t)(startl >> 8);
  203. cmdfis->lba2 = (uint8_t)(startl >> 16);
  204. cmdfis->device = 1 << 6; // LBA mode
  205. cmdfis->lba3 = (uint8_t)(startl >> 24);
  206. cmdfis->lba4 = (uint8_t)starth;
  207. cmdfis->lba5 = (uint8_t)(starth >> 8);
  208. cmdfis->countl = count & 0xFF;
  209. cmdfis->counth = (count >> 8) & 0xFF;
  210. // The below loop waits until the port is no longer busy before issuing a new command
  211. while ((port->tfd & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && spin < 1000000)
  212. {
  213. spin++;
  214. }
  215. if (spin == 1000000)
  216. {
  217. kerror("Port is hung");
  218. return E_PORT_HUNG;
  219. }
  220. kdebug("slot=%d", slot);
  221. port->ci = 1 << slot; // Issue command
  222. // Wait for completion
  223. while (1)
  224. {
  225. // In some longer duration reads, it may be helpful to spin on the DPS bit
  226. // in the PxIS port field as well (1 << 5)
  227. if ((port->ci & (1 << slot)) == 0)
  228. break;
  229. if (port->is & HBA_PxIS_TFES) // Task file error
  230. {
  231. kerror("Read disk error");
  232. return E_TASK_FILE_ERROR;
  233. }
  234. }
  235. // Check again
  236. if (port->is & HBA_PxIS_TFES)
  237. {
  238. kerror("Read disk error");
  239. return E_TASK_FILE_ERROR;
  240. }
  241. return AHCI_SUCCESS;
  242. }
  243. static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count,
  244. uint64_t buf)
  245. {
  246. port->is = 0xffff; // Clear pending interrupt bits
  247. int slot = ahci_find_cmdslot(port);
  248. if (slot == -1)
  249. return E_NOEMPTYSLOT;
  250. HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
  251. cmdheader += slot;
  252. cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
  253. cmdheader->w = 1;
  254. cmdheader->c = 1;
  255. cmdheader->p = 1;
  256. cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
  257. HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
  258. memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
  259. int i = 0;
  260. for (i = 0; i < cmdheader->prdtl - 1; ++i)
  261. {
  262. cmdtbl->prdt_entry[i].dba = buf;
  263. cmdtbl->prdt_entry[i].dbc = 8 * 1024 - 1; // 8K bytes
  264. cmdtbl->prdt_entry[i].i = 0;
  265. buf += 4 * 1024; // 4K words
  266. count -= 16; // 16 sectors
  267. }
  268. cmdtbl->prdt_entry[i].dba = buf;
  269. cmdtbl->prdt_entry[i].dbc = count << 9; // 512 bytes per sector
  270. cmdtbl->prdt_entry[i].i = 0;
  271. FIS_REG_H2D *cmdfis = (FIS_REG_H2D *)(&cmdtbl->cfis);
  272. cmdfis->fis_type = FIS_TYPE_REG_H2D;
  273. cmdfis->c = 1; // Command
  274. cmdfis->command = ATA_CMD_WRITE_DMA_EXT;
  275. cmdfis->lba0 = (uint8_t)startl;
  276. cmdfis->lba1 = (uint8_t)(startl >> 8);
  277. cmdfis->lba2 = (uint8_t)(startl >> 16);
  278. cmdfis->lba3 = (uint8_t)(startl >> 24);
  279. cmdfis->lba4 = (uint8_t)starth;
  280. cmdfis->lba5 = (uint8_t)(starth >> 8);
  281. cmdfis->device = 1 << 6; // LBA mode
  282. cmdfis->countl = count & 0xff;
  283. cmdfis->counth = count >> 8;
  284. // printk("[slot]{%d}", slot);
  285. port->ci = 1; // Issue command
  286. while (1)
  287. {
  288. // In some longer duration reads, it may be helpful to spin on the DPS bit
  289. // in the PxIS port field as well (1 << 5)
  290. if ((port->ci & (1 << slot)) == 0)
  291. break;
  292. if (port->is & HBA_PxIS_TFES)
  293. { // Task file error
  294. kerror("Write disk error");
  295. return E_TASK_FILE_ERROR;
  296. }
  297. }
  298. if (port->is & HBA_PxIS_TFES)
  299. {
  300. kerror("Write disk error");
  301. return E_TASK_FILE_ERROR;
  302. }
  303. return AHCI_SUCCESS;
  304. }
  305. // Find a free command list slot
  306. static int ahci_find_cmdslot(HBA_PORT *port)
  307. {
  308. // If not set in SACT and CI, the slot is free
  309. uint32_t slots = (port->sact | port->ci);
  310. int num_of_cmd_clots = (ahci_devices[0].hba_mem->cap & 0x0f00) >> 8; // bit 12-8
  311. for (int i = 0; i < num_of_cmd_clots; i++)
  312. {
  313. if ((slots & 1) == 0)
  314. return i;
  315. slots >>= 1;
  316. }
  317. kerror("Cannot find free command list entry");
  318. return -1;
  319. }
  320. long ahci_open()
  321. {
  322. return 0;
  323. }
  324. long ahci_close()
  325. {
  326. return 0;
  327. }
  328. /**
  329. * @brief 创建ahci磁盘请求包
  330. *
  331. * @param cmd 控制命令
  332. * @param base_addr 48位LBA地址
  333. * @param count total sectors to read
  334. * @param buf 缓冲区线性地址
  335. * @param ahci_ctrl_num ahci控制器号
  336. * @param port_num ahci控制器端口号
  337. * @return struct block_device_request_packet*
  338. */
  339. static struct block_device_request_packet *ahci_make_request(long cmd, uint64_t base_addr, uint64_t count, uint64_t buffer, uint8_t ahci_ctrl_num, uint8_t port_num)
  340. {
  341. struct block_device_request_packet *pack = (struct block_device_request_packet *)kmalloc(sizeof(struct block_device_request_packet), 0);
  342. list_init(&pack->list);
  343. // 由于ahci不需要中断即可读取磁盘,因此end handler为空
  344. switch (cmd)
  345. {
  346. case ATA_CMD_READ_DMA_EXT:
  347. pack->end_handler = NULL;
  348. pack->cmd = ATA_CMD_READ_DMA_EXT;
  349. break;
  350. case ATA_CMD_WRITE_DMA_EXT:
  351. pack->end_handler = NULL;
  352. pack->cmd = ATA_CMD_WRITE_DMA_EXT;
  353. break;
  354. default:
  355. pack->end_handler = NULL;
  356. pack->cmd = cmd;
  357. break;
  358. }
  359. pack->LBA_start = base_addr;
  360. pack->count = count;
  361. pack->buffer_vaddr = buffer;
  362. pack->ahci_ctrl_num = ahci_ctrl_num;
  363. pack->port_num = port_num;
  364. return pack;
  365. }
  366. /**
  367. * @brief 结束磁盘请求
  368. *
  369. */
  370. static void ahci_end_request()
  371. {
  372. kfree((uint64_t *)ahci_req_queue.in_service);
  373. ahci_req_queue.in_service = NULL;
  374. // 进行下一轮的磁盘请求 (由于未实现单独的io调度器,这里会造成长时间的io等待)
  375. if (ahci_req_queue.request_count>0)
  376. ahci_query_disk();
  377. }
  378. static long ahci_query_disk()
  379. {
  380. struct block_device_request_packet *pack = container_of(list_next(&ahci_req_queue.queue_list), struct block_device_request_packet, list);
  381. ahci_req_queue.in_service = pack;
  382. list_del(&(ahci_req_queue.in_service->list));
  383. --ahci_req_queue.request_count;
  384. long ret_val;
  385. switch (pack->cmd)
  386. {
  387. case ATA_CMD_READ_DMA_EXT:
  388. ret_val = ahci_read(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->LBA_start & 0xFFFFFFFF, ((pack->LBA_start) >> 32) & 0xFFFFFFFF, pack->count, pack->buffer_vaddr);
  389. break;
  390. case ATA_CMD_WRITE_DMA_EXT:
  391. ret_val = ahci_write(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->LBA_start & 0xFFFFFFFF, ((pack->LBA_start) >> 32) & 0xFFFFFFFF, pack->count, pack->buffer_vaddr);
  392. break;
  393. default:
  394. kerror("Unsupport ahci command: %#05lx", pack->cmd);
  395. ret_val = E_UNSUPPORTED_CMD;
  396. break;
  397. }
  398. ahci_end_request();
  399. return ret_val;
  400. }
  401. /**
  402. * @brief 将请求包提交到io队列
  403. *
  404. * @param pack
  405. */
  406. static void ahci_submit(struct block_device_request_packet *pack)
  407. {
  408. list_append(&(ahci_req_queue.queue_list), &(pack->list));
  409. ++ahci_req_queue.request_count;
  410. if (ahci_req_queue.in_service == NULL) // 当前没有正在请求的io包,立即执行磁盘请求
  411. ahci_query_disk();
  412. }
  413. /**
  414. * @brief ahci驱动程序的传输函数
  415. *
  416. * @param cmd 控制命令
  417. * @param base_addr 48位LBA地址
  418. * @param count total sectors to read
  419. * @param buf 缓冲区线性地址
  420. * @param ahci_ctrl_num ahci控制器号
  421. * @param port_num ahci控制器端口号
  422. * @return long
  423. */
  424. static long ahci_transfer(long cmd, uint64_t base_addr, uint64_t count, uint64_t buf, uint8_t ahci_ctrl_num, uint8_t port_num)
  425. {
  426. struct block_device_request_packet *pack = NULL;
  427. if (cmd == ATA_CMD_READ_DMA_EXT || cmd == ATA_CMD_WRITE_DMA_EXT)
  428. {
  429. pack = ahci_make_request(cmd, base_addr, count, buf, ahci_ctrl_num, port_num);
  430. ahci_submit(pack);
  431. }
  432. else
  433. return E_UNSUPPORTED_CMD;
  434. return AHCI_SUCCESS;
  435. }
  436. /**
  437. * @brief todo: io控制器函数
  438. *
  439. * @param cmd 命令
  440. * @param arg 参数
  441. * @return long
  442. */
  443. static long ahci_ioctl(long cmd, long arg)
  444. {
  445. }
  446. struct block_device_operation ahci_operation =
  447. {
  448. .open = ahci_open,
  449. .close = ahci_close,
  450. .ioctl = ahci_ioctl,
  451. .transfer = ahci_transfer,
  452. };