mod.rs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // 导出 ahci 相关的 module
  2. pub mod ahci_inode;
  3. pub mod ahcidisk;
  4. pub mod hba;
  5. use crate::filesystem::vfs::io::device::BlockDevice;
  6. // 依赖的rust工具包
  7. use crate::driver::pci::pci::{
  8. get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
  9. };
  10. use crate::filesystem::devfs::devfs_register;
  11. use crate::filesystem::vfs::io::disk_info::BLK_GF_AHCI;
  12. use crate::kerror;
  13. use crate::libs::rwlock::RwLockWriteGuard;
  14. use crate::libs::spinlock::{SpinLock, SpinLockGuard};
  15. use crate::mm::virt_2_phys;
  16. use crate::syscall::SystemError;
  17. use crate::{
  18. driver::disk::ahci::{
  19. ahcidisk::LockedAhciDisk,
  20. hba::HbaMem,
  21. hba::{HbaPort, HbaPortType},
  22. },
  23. kdebug,
  24. };
  25. use ahci_inode::LockedAhciInode;
  26. use alloc::{
  27. boxed::Box,
  28. collections::LinkedList,
  29. format,
  30. string::{String, ToString},
  31. sync::Arc,
  32. vec::Vec,
  33. };
  34. use core::sync::atomic::compiler_fence;
  35. // 仅module内可见 全局数据区 hbr_port, disks
  36. static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
  37. static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new());
  38. const AHCI_CLASS: u8 = 0x1;
  39. const AHCI_SUBCLASS: u8 = 0x6;
  40. /* TFES - Task File Error Status */
  41. #[allow(non_upper_case_globals)]
  42. pub const HBA_PxIS_TFES: u32 = 1 << 30;
  43. #[no_mangle]
  44. pub extern "C" fn ahci_init() -> i32 {
  45. let r = ahci_rust_init();
  46. if r.is_ok() {
  47. return 0;
  48. } else {
  49. return r.unwrap_err().to_posix_errno();
  50. }
  51. }
  52. /// @brief 寻找所有的ahci设备
  53. /// @param list 链表的写锁
  54. /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err
  55. fn ahci_device_search<'a>(
  56. list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
  57. ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> {
  58. let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS);
  59. if result.is_empty() {
  60. return Err(SystemError::ENODEV);
  61. }
  62. kdebug!("{}", result.len());
  63. Ok(result)
  64. }
  65. /// @brief: 初始化 ahci
  66. pub fn ahci_rust_init() -> Result<(), SystemError> {
  67. let mut list = PCI_DEVICE_LINKEDLIST.write();
  68. let ahci_device = ahci_device_search(&mut list)?;
  69. // 全局数据 - 列表
  70. let mut disks_list = LOCKED_DISKS_LIST.lock();
  71. for device in ahci_device {
  72. let standard_device = device.as_standard_device_mut().unwrap();
  73. standard_device.bar_ioremap();
  74. // 对于每一个ahci控制器分配一块空间 (目前slab algorithm最大支持1MB)
  75. let ahci_port_base_vaddr =
  76. Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
  77. let virtaddr = standard_device
  78. .bar()
  79. .ok_or(SystemError::EACCES)?
  80. .get_bar(5)
  81. .or(Err(SystemError::EACCES))?
  82. .virtual_address()
  83. .unwrap();
  84. // 最后把这个引用列表放入到全局列表
  85. let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
  86. //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度
  87. let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() };
  88. hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() });
  89. let pi = volatile_read!(hba_mem.pi);
  90. let hba_mem_index = hba_mem_list.len() - 1;
  91. drop(hba_mem_list);
  92. // 初始化所有的port
  93. let mut id = 0;
  94. for j in 0..32 {
  95. if (pi >> j) & 1 > 0 {
  96. let hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
  97. let hba_mem_port = &mut hba_mem.ports[j];
  98. let tp = hba_mem_port.check_type();
  99. match tp {
  100. HbaPortType::None => {
  101. kdebug!("<ahci_rust_init> Find a None type Disk.");
  102. }
  103. HbaPortType::Unknown(err) => {
  104. kdebug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err);
  105. }
  106. _ => {
  107. kdebug!("<ahci_rust_init> Find a {:?} type Disk.", tp);
  108. // 计算地址
  109. let fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (j << 8));
  110. let clb = virt_2_phys(ahci_port_base_vaddr + (j << 10));
  111. let ctbas = (0..32)
  112. .map(|x| {
  113. virt_2_phys(
  114. ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8),
  115. ) as u64
  116. })
  117. .collect::<Vec<_>>();
  118. // 初始化 port
  119. hba_mem_port.init(clb as u64, fb as u64, &ctbas);
  120. drop(hba_mem_list);
  121. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  122. // 创建 disk
  123. disks_list.push(LockedAhciDisk::new(
  124. format!("ahci_disk_{}", id),
  125. BLK_GF_AHCI,
  126. hba_mem_index as u8,
  127. j as u8,
  128. )?);
  129. id += 1; // ID 从0开始
  130. kdebug!("start register ahci device");
  131. // 挂载到devfs上面去
  132. let ret = devfs_register(
  133. format!("ahci_{}", id).as_str(),
  134. LockedAhciInode::new(disks_list.last().unwrap().clone()),
  135. );
  136. if let Err(err) = ret {
  137. kerror!(
  138. "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}",
  139. id,
  140. hba_mem_index as u8,
  141. j,
  142. err
  143. );
  144. }
  145. }
  146. }
  147. }
  148. }
  149. }
  150. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  151. return Ok(());
  152. }
  153. /// @brief: 获取所有的 disk
  154. #[allow(dead_code)]
  155. pub fn disks() -> Vec<Arc<LockedAhciDisk>> {
  156. let disks_list = LOCKED_DISKS_LIST.lock();
  157. return disks_list.clone();
  158. }
  159. /// @brief: 通过 name 获取 disk
  160. pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> {
  161. let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock();
  162. let result = disks_list
  163. .iter()
  164. .find(|x| x.0.lock().name == name)
  165. .ok_or(SystemError::ENXIO)?
  166. .clone();
  167. return Ok(result);
  168. }
  169. /// @brief: 通过 ctrl_num 和 port_num 获取 port
  170. fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
  171. let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();
  172. let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize];
  173. return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() };
  174. }
  175. /// @brief: 测试函数
  176. pub fn __test_ahci() {
  177. let _res = ahci_rust_init();
  178. let disk: Arc<LockedAhciDisk> = get_disks_by_name("ahci_disk_0".to_string()).unwrap();
  179. #[deny(overflowing_literals)]
  180. let mut buf = [0u8; 3000usize];
  181. for i in 0..2000 {
  182. buf[i] = i as u8;
  183. }
  184. let _dd = disk;
  185. // 测试1, 写两个块,读4个块
  186. // _dd.write_at(123, 2, &buf).unwrap();
  187. let mut read_buf = [0u8; 3000usize];
  188. _dd.read_at(122, 4, &mut read_buf).unwrap();
  189. // 测试2, 只读写一个字节
  190. for i in 0..512 {
  191. buf[i] = 233;
  192. }
  193. // _dd.write_at(123, 2, &buf).unwrap();
  194. let mut read_buf2 = [0u8; 3000usize];
  195. _dd.read_at(122, 4, &mut read_buf2).unwrap();
  196. }