1 // 导出 ahci 相关的 module
2 pub mod ahci_inode;
3 pub mod ahcidisk;
4 pub mod hba;
5
6 use crate::arch::MMArch;
7 use crate::driver::base::block::manager::block_dev_manager;
8 use crate::driver::block::cache::cached_block_device::BlockCache;
9 use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk;
10 use crate::driver::pci::pci::{
11 get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
12 };
13
14 use crate::driver::disk::ahci::{
15 hba::HbaMem,
16 hba::{HbaPort, HbaPortType},
17 };
18 use crate::libs::rwlock::RwLockWriteGuard;
19 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
20 use crate::mm::{MemoryManagementArch, VirtAddr};
21 use alloc::{boxed::Box, collections::LinkedList, vec::Vec};
22 use core::sync::atomic::compiler_fence;
23 use log::debug;
24 use system_error::SystemError;
25
26 // 仅module内可见 全局数据区 hbr_port, disks
27 static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
28
29 const AHCI_CLASS: u8 = 0x1;
30 const AHCI_SUBCLASS: u8 = 0x6;
31
32 /* TFES - Task File Error Status */
33 #[allow(non_upper_case_globals)]
34 pub const HBA_PxIS_TFES: u32 = 1 << 30;
35
36 /// @brief 寻找所有的ahci设备
37 /// @param list 链表的写锁
38 /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err
ahci_device_search<'a>( list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError>39 fn ahci_device_search<'a>(
40 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
41 ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> {
42 let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS);
43
44 if result.is_empty() {
45 return Err(SystemError::ENODEV);
46 }
47
48 return Ok(result);
49 }
50
51 /// @brief: 初始化 ahci
ahci_init() -> Result<(), SystemError>52 pub fn ahci_init() -> Result<(), SystemError> {
53 let mut list = PCI_DEVICE_LINKEDLIST.write();
54 let ahci_device = ahci_device_search(&mut list)?;
55
56 for device in ahci_device {
57 let standard_device = device.as_standard_device_mut().unwrap();
58 standard_device.bar_ioremap();
59 // 对于每一个ahci控制器分配一块空间
60 let ahci_port_base_vaddr =
61 Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
62 let virtaddr = standard_device
63 .bar()
64 .ok_or(SystemError::EACCES)?
65 .get_bar(5)
66 .or(Err(SystemError::EACCES))?
67 .virtual_address()
68 .unwrap();
69 // 最后把这个引用列表放入到全局列表
70 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
71 //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度
72 let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() };
73 hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() });
74 let pi = volatile_read!(hba_mem.pi);
75 let hba_mem_index = hba_mem_list.len() - 1;
76 drop(hba_mem_list);
77 // 初始化所有的port
78 for j in 0..32 {
79 if (pi >> j) & 1 > 0 {
80 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
81 let hba_mem_port = &mut hba_mem.ports[j];
82 let tp = hba_mem_port.check_type();
83 match tp {
84 HbaPortType::None => {
85 debug!("<ahci_rust_init> Find a None type Disk.");
86 }
87 HbaPortType::Unknown(err) => {
88 debug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err);
89 }
90 _ => {
91 debug!("<ahci_rust_init> Find a {:?} type Disk.", tp);
92
93 // 计算地址
94 let fb = unsafe {
95 MMArch::virt_2_phys(VirtAddr::new(
96 ahci_port_base_vaddr + (32 << 10) + (j << 8),
97 ))
98 }
99 .unwrap()
100 .data();
101 let clb = unsafe {
102 MMArch::virt_2_phys(VirtAddr::new(ahci_port_base_vaddr + (j << 10)))
103 .unwrap()
104 .data()
105 };
106 let ctbas = (0..32)
107 .map(|x| unsafe {
108 MMArch::virt_2_phys(VirtAddr::new(
109 ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8),
110 ))
111 .unwrap()
112 .data() as u64
113 })
114 .collect::<Vec<_>>();
115
116 // 初始化 port
117 hba_mem_port.init(clb as u64, fb as u64, &ctbas);
118 drop(hba_mem_list);
119 compiler_fence(core::sync::atomic::Ordering::SeqCst);
120 let ahci_disk = LockedAhciDisk::new(hba_mem_index as u8, j as u8)?;
121 block_dev_manager()
122 .register(ahci_disk)
123 .expect("register ahci disk failed");
124
125 debug!("start register ahci device");
126 }
127 }
128 }
129 }
130 BlockCache::init();
131 }
132
133 compiler_fence(core::sync::atomic::Ordering::SeqCst);
134 return Ok(());
135 }
136
137 /// @brief: 通过 ctrl_num 和 port_num 获取 port
_port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort138 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
139 let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();
140 let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize];
141
142 return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() };
143 }
144