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