ahcidisk.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. use super::{_port, hba::HbaCmdTable, virt_2_phys};
  2. use crate::driver::base::block::block_device::{BlockDevice, BlockId};
  3. use crate::driver::base::block::disk_info::Partition;
  4. use crate::driver::base::class::Class;
  5. use crate::driver::base::device::bus::Bus;
  6. use crate::driver::base::device::driver::Driver;
  7. use crate::driver::base::device::{Device, DeviceType, IdTable};
  8. use crate::driver::base::kobject::{KObjType, KObject, KObjectState};
  9. use crate::driver::base::kset::KSet;
  10. use crate::driver::disk::ahci::HBA_PxIS_TFES;
  11. use crate::filesystem::kernfs::KernFSInode;
  12. use crate::filesystem::mbr::MbrDiskPartionTable;
  13. use crate::driver::disk::ahci::hba::{
  14. FisRegH2D, FisType, HbaCmdHeader, ATA_CMD_READ_DMA_EXT, ATA_CMD_WRITE_DMA_EXT, ATA_DEV_BUSY,
  15. ATA_DEV_DRQ,
  16. };
  17. use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard};
  18. use crate::libs::spinlock::SpinLock;
  19. use crate::mm::{phys_2_virt, verify_area, VirtAddr};
  20. use log::error;
  21. use system_error::SystemError;
  22. use alloc::sync::Weak;
  23. use alloc::{string::String, sync::Arc, vec::Vec};
  24. use core::fmt::Debug;
  25. use core::sync::atomic::{compiler_fence, Ordering};
  26. use core::{mem::size_of, ptr::write_bytes};
  27. /// @brief: 只支持MBR分区格式的磁盘结构体
  28. pub struct AhciDisk {
  29. pub name: String,
  30. pub flags: u16, // 磁盘的状态flags
  31. pub partitions: Vec<Arc<Partition>>, // 磁盘分区数组
  32. // port: &'static mut HbaPort, // 控制硬盘的端口
  33. pub ctrl_num: u8,
  34. pub port_num: u8,
  35. /// 指向LockAhciDisk的弱引用
  36. self_ref: Weak<LockedAhciDisk>,
  37. }
  38. /// @brief: 带锁的AhciDisk
  39. #[derive(Debug)]
  40. pub struct LockedAhciDisk(pub SpinLock<AhciDisk>);
  41. /// 函数实现
  42. impl Debug for AhciDisk {
  43. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  44. write!(
  45. f,
  46. "{{ name: {}, flags: {}, part_s: {:?} }}",
  47. self.name, self.flags, self.partitions
  48. )?;
  49. return Ok(());
  50. }
  51. }
  52. impl AhciDisk {
  53. fn read_at(
  54. &self,
  55. lba_id_start: BlockId, // 起始lba编号
  56. count: usize, // 读取lba的数量
  57. buf: &mut [u8],
  58. ) -> Result<usize, SystemError> {
  59. assert!((buf.len() & 511) == 0);
  60. compiler_fence(Ordering::SeqCst);
  61. let check_length = ((count - 1) >> 4) + 1; // prdt length
  62. if count * 512 > buf.len() || check_length > 8_usize {
  63. error!("ahci read: e2big");
  64. // 不可能的操作
  65. return Err(SystemError::E2BIG);
  66. } else if count == 0 {
  67. return Ok(0);
  68. }
  69. let port = _port(self.ctrl_num, self.port_num);
  70. volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits
  71. let slot = port.find_cmdslot().unwrap_or(u32::MAX);
  72. if slot == u32::MAX {
  73. return Err(SystemError::EIO);
  74. }
  75. #[allow(unused_unsafe)]
  76. let cmdheader: &mut HbaCmdHeader = unsafe {
  77. (phys_2_virt(
  78. volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(),
  79. ) as *mut HbaCmdHeader)
  80. .as_mut()
  81. .unwrap()
  82. };
  83. cmdheader.cfl = (size_of::<FisRegH2D>() / size_of::<u32>()) as u8;
  84. volatile_set_bit!(cmdheader.cfl, 1 << 6, false); // Read/Write bit : Read from device
  85. volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count
  86. // 设置数据存放地址
  87. let mut buf_ptr = buf as *mut [u8] as *mut usize as usize;
  88. // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
  89. // TODO:在内存管理重构后,可以直接使用用户空间的内存地址
  90. let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
  91. let mut kbuf = if user_buf {
  92. let x: Vec<u8> = vec![0; buf.len()];
  93. Some(x)
  94. } else {
  95. None
  96. };
  97. if kbuf.is_some() {
  98. buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
  99. }
  100. #[allow(unused_unsafe)]
  101. let cmdtbl = unsafe {
  102. (phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable)
  103. .as_mut()
  104. .unwrap() // 必须使用 as_mut ,得到的才是原来的变量
  105. };
  106. let mut tmp_count = count;
  107. unsafe {
  108. // 清空整个table的旧数据
  109. write_bytes(cmdtbl, 0, 1);
  110. }
  111. // debug!("cmdheader.prdtl={}", volatile_read!(cmdheader.prdtl));
  112. // 8K bytes (16 sectors) per PRDT
  113. for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) {
  114. volatile_write!(cmdtbl.prdt_entry[i].dba, virt_2_phys(buf_ptr) as u64);
  115. cmdtbl.prdt_entry[i].dbc = 8 * 1024 - 1;
  116. volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断 prdt_entry.i
  117. buf_ptr += 8 * 1024;
  118. tmp_count -= 16;
  119. }
  120. // Last entry
  121. let las = (volatile_read!(cmdheader.prdtl) - 1) as usize;
  122. volatile_write!(cmdtbl.prdt_entry[las].dba, virt_2_phys(buf_ptr) as u64);
  123. cmdtbl.prdt_entry[las].dbc = ((tmp_count << 9) - 1) as u32; // 数据长度
  124. volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断
  125. // 设置命令
  126. let cmdfis = unsafe {
  127. ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D)
  128. .as_mut()
  129. .unwrap()
  130. };
  131. volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8);
  132. volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set
  133. volatile_write!(cmdfis.command, ATA_CMD_READ_DMA_EXT);
  134. volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8);
  135. volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8);
  136. volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8);
  137. volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8);
  138. volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8);
  139. volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8);
  140. volatile_write!(cmdfis.countl, (count & 0xFF) as u8);
  141. volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8);
  142. volatile_write!(cmdfis.device, 1 << 6); // LBA Mode
  143. // 等待之前的操作完成
  144. let mut spin_count = 0;
  145. const SPIN_LIMIT: u32 = 10000;
  146. while (volatile_read!(port.tfd) as u8 & (ATA_DEV_BUSY | ATA_DEV_DRQ)) > 0
  147. && spin_count < SPIN_LIMIT
  148. {
  149. spin_count += 1;
  150. }
  151. if spin_count == SPIN_LIMIT {
  152. error!("Port is hung");
  153. return Err(SystemError::EIO);
  154. }
  155. volatile_set_bit!(port.ci, 1 << slot, true); // Issue command
  156. // debug!("To wait ahci read complete.");
  157. // 等待操作完成
  158. loop {
  159. if (volatile_read!(port.ci) & (1 << slot)) == 0 {
  160. break;
  161. }
  162. if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 {
  163. error!("Read disk error");
  164. return Err(SystemError::EIO);
  165. }
  166. }
  167. if let Some(kbuf) = &kbuf {
  168. buf.copy_from_slice(kbuf);
  169. }
  170. compiler_fence(Ordering::SeqCst);
  171. // successfully read
  172. return Ok(count * 512);
  173. }
  174. fn write_at(
  175. &self,
  176. lba_id_start: BlockId,
  177. count: usize,
  178. buf: &[u8],
  179. ) -> Result<usize, SystemError> {
  180. assert!((buf.len() & 511) == 0);
  181. compiler_fence(Ordering::SeqCst);
  182. let check_length = ((count - 1) >> 4) + 1; // prdt length
  183. if count * 512 > buf.len() || check_length > 8 {
  184. // 不可能的操作
  185. return Err(SystemError::E2BIG);
  186. } else if count == 0 {
  187. return Ok(0);
  188. }
  189. let port = _port(self.ctrl_num, self.port_num);
  190. volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits
  191. let slot = port.find_cmdslot().unwrap_or(u32::MAX);
  192. if slot == u32::MAX {
  193. return Err(SystemError::EIO);
  194. }
  195. compiler_fence(Ordering::SeqCst);
  196. #[allow(unused_unsafe)]
  197. let cmdheader: &mut HbaCmdHeader = unsafe {
  198. (phys_2_virt(
  199. volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(),
  200. ) as *mut HbaCmdHeader)
  201. .as_mut()
  202. .unwrap()
  203. };
  204. compiler_fence(Ordering::SeqCst);
  205. volatile_write_bit!(
  206. cmdheader.cfl,
  207. (1 << 5) - 1_u8,
  208. (size_of::<FisRegH2D>() / size_of::<u32>()) as u8
  209. ); // Command FIS size
  210. volatile_set_bit!(cmdheader.cfl, 7 << 5, true); // (p,c,w)都设置为1, Read/Write bit : Write from device
  211. volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count
  212. // 设置数据存放地址
  213. compiler_fence(Ordering::SeqCst);
  214. let mut buf_ptr = buf as *const [u8] as *mut usize as usize;
  215. // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
  216. // TODO:在内存管理重构后,可以直接使用用户空间的内存地址
  217. let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
  218. let mut kbuf = if user_buf {
  219. let mut x: Vec<u8> = vec![0; buf.len()];
  220. x.resize(buf.len(), 0);
  221. x.copy_from_slice(buf);
  222. Some(x)
  223. } else {
  224. None
  225. };
  226. if kbuf.is_some() {
  227. buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
  228. }
  229. #[allow(unused_unsafe)]
  230. let cmdtbl = unsafe {
  231. (phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable)
  232. .as_mut()
  233. .unwrap()
  234. };
  235. let mut tmp_count = count;
  236. compiler_fence(Ordering::SeqCst);
  237. unsafe {
  238. // 清空整个table的旧数据
  239. write_bytes(cmdtbl, 0, 1);
  240. }
  241. // 8K bytes (16 sectors) per PRDT
  242. for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) {
  243. volatile_write!(cmdtbl.prdt_entry[i].dba, virt_2_phys(buf_ptr) as u64);
  244. volatile_write_bit!(cmdtbl.prdt_entry[i].dbc, (1 << 22) - 1, 8 * 1024 - 1); // 数据长度
  245. volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断
  246. buf_ptr += 8 * 1024;
  247. tmp_count -= 16;
  248. }
  249. // Last entry
  250. let las = (volatile_read!(cmdheader.prdtl) - 1) as usize;
  251. volatile_write!(cmdtbl.prdt_entry[las].dba, virt_2_phys(buf_ptr) as u64);
  252. volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断
  253. volatile_write_bit!(
  254. cmdtbl.prdt_entry[las].dbc,
  255. (1 << 22) - 1,
  256. ((tmp_count << 9) - 1) as u32
  257. ); // 数据长度
  258. // 设置命令
  259. let cmdfis = unsafe {
  260. ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D)
  261. .as_mut()
  262. .unwrap()
  263. };
  264. volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8);
  265. volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set
  266. volatile_write!(cmdfis.command, ATA_CMD_WRITE_DMA_EXT);
  267. volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8);
  268. volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8);
  269. volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8);
  270. volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8);
  271. volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8);
  272. volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8);
  273. volatile_write!(cmdfis.countl, (count & 0xFF) as u8);
  274. volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8);
  275. volatile_write!(cmdfis.device, 1 << 6); // LBA Mode
  276. volatile_set_bit!(port.ci, 1 << slot, true); // Issue command
  277. // 等待操作完成
  278. loop {
  279. if (volatile_read!(port.ci) & (1 << slot)) == 0 {
  280. break;
  281. }
  282. if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 {
  283. error!("Write disk error");
  284. return Err(SystemError::EIO);
  285. }
  286. }
  287. compiler_fence(Ordering::SeqCst);
  288. // successfully read
  289. return Ok(count * 512);
  290. }
  291. fn sync(&self) -> Result<(), SystemError> {
  292. // 由于目前没有block cache, 因此sync返回成功即可
  293. return Ok(());
  294. }
  295. }
  296. impl LockedAhciDisk {
  297. pub fn new(
  298. name: String,
  299. flags: u16,
  300. ctrl_num: u8,
  301. port_num: u8,
  302. ) -> Result<Arc<LockedAhciDisk>, SystemError> {
  303. // 构建磁盘结构体
  304. let result: Arc<LockedAhciDisk> = Arc::new_cyclic(|self_ref| {
  305. LockedAhciDisk(SpinLock::new(AhciDisk {
  306. name,
  307. flags,
  308. partitions: Default::default(),
  309. ctrl_num,
  310. port_num,
  311. self_ref: self_ref.clone(),
  312. }))
  313. });
  314. let table: MbrDiskPartionTable = result.read_mbr_table()?;
  315. // 求出有多少可用分区
  316. let partitions = table.partitions(Arc::downgrade(&result) as Weak<dyn BlockDevice>);
  317. result.0.lock().partitions = partitions;
  318. return Ok(result);
  319. }
  320. /// @brief: 从磁盘中读取 MBR 分区表结构体
  321. pub fn read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError> {
  322. let disk = self.0.lock().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
  323. MbrDiskPartionTable::from_disk(disk)
  324. }
  325. }
  326. impl KObject for LockedAhciDisk {
  327. fn as_any_ref(&self) -> &dyn core::any::Any {
  328. self
  329. }
  330. fn inode(&self) -> Option<Arc<KernFSInode>> {
  331. todo!()
  332. }
  333. fn kobj_type(&self) -> Option<&'static dyn KObjType> {
  334. todo!()
  335. }
  336. fn kset(&self) -> Option<Arc<KSet>> {
  337. todo!()
  338. }
  339. fn parent(&self) -> Option<Weak<dyn KObject>> {
  340. todo!()
  341. }
  342. fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) {
  343. todo!()
  344. }
  345. fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
  346. todo!()
  347. }
  348. fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
  349. todo!()
  350. }
  351. fn set_kobj_state(&self, _state: KObjectState) {
  352. todo!()
  353. }
  354. fn name(&self) -> alloc::string::String {
  355. todo!()
  356. }
  357. fn set_name(&self, _name: alloc::string::String) {
  358. todo!()
  359. }
  360. fn set_kset(&self, _kset: Option<Arc<KSet>>) {
  361. todo!()
  362. }
  363. fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) {
  364. todo!()
  365. }
  366. fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
  367. todo!()
  368. }
  369. }
  370. impl Device for LockedAhciDisk {
  371. fn dev_type(&self) -> DeviceType {
  372. return DeviceType::Block;
  373. }
  374. fn id_table(&self) -> IdTable {
  375. todo!()
  376. }
  377. fn bus(&self) -> Option<Weak<dyn Bus>> {
  378. todo!("LockedAhciDisk::bus()")
  379. }
  380. fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
  381. todo!("LockedAhciDisk::set_bus()")
  382. }
  383. fn driver(&self) -> Option<Arc<dyn Driver>> {
  384. todo!("LockedAhciDisk::driver()")
  385. }
  386. fn is_dead(&self) -> bool {
  387. false
  388. }
  389. fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
  390. todo!("LockedAhciDisk::set_driver()")
  391. }
  392. fn can_match(&self) -> bool {
  393. todo!()
  394. }
  395. fn set_can_match(&self, _can_match: bool) {
  396. todo!()
  397. }
  398. fn state_synced(&self) -> bool {
  399. todo!()
  400. }
  401. fn set_class(&self, _class: Option<Weak<dyn Class>>) {
  402. todo!()
  403. }
  404. }
  405. impl BlockDevice for LockedAhciDisk {
  406. #[inline]
  407. fn as_any_ref(&self) -> &dyn core::any::Any {
  408. self
  409. }
  410. #[inline]
  411. fn blk_size_log2(&self) -> u8 {
  412. 9
  413. }
  414. fn sync(&self) -> Result<(), SystemError> {
  415. return self.0.lock().sync();
  416. }
  417. #[inline]
  418. fn device(&self) -> Arc<dyn Device> {
  419. return self.0.lock().self_ref.upgrade().unwrap();
  420. }
  421. fn block_size(&self) -> usize {
  422. todo!()
  423. }
  424. fn partitions(&self) -> Vec<Arc<Partition>> {
  425. return self.0.lock().partitions.clone();
  426. }
  427. #[inline]
  428. fn read_at_sync(
  429. &self,
  430. lba_id_start: BlockId, // 起始lba编号
  431. count: usize, // 读取lba的数量
  432. buf: &mut [u8],
  433. ) -> Result<usize, SystemError> {
  434. self.0.lock().read_at(lba_id_start, count, buf)
  435. }
  436. #[inline]
  437. fn write_at_sync(
  438. &self,
  439. lba_id_start: BlockId,
  440. count: usize,
  441. buf: &[u8],
  442. ) -> Result<usize, SystemError> {
  443. self.0.lock().write_at(lba_id_start, count, buf)
  444. }
  445. }