ahcidisk.rs 18 KB

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