xref: /DragonOS/kernel/src/driver/disk/ahci/mod.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
1004e86ffSlogin // 导出 ahci 相关的 module
2004e86ffSlogin pub mod ahci_inode;
3004e86ffSlogin pub mod ahcidisk;
4004e86ffSlogin pub mod hba;
5004e86ffSlogin 
6b087521eSChiichen use crate::driver::base::block::block_device::BlockDevice;
7b087521eSChiichen use crate::driver::base::block::disk_info::BLK_GF_AHCI;
8004e86ffSlogin // 依赖的rust工具包
98d94ea66SYJwu2023 use crate::driver::pci::pci::{
108d94ea66SYJwu2023     get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
118d94ea66SYJwu2023 };
12004e86ffSlogin use crate::filesystem::devfs::devfs_register;
13004e86ffSlogin use crate::kerror;
148d94ea66SYJwu2023 use crate::libs::rwlock::RwLockWriteGuard;
15004e86ffSlogin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
16004e86ffSlogin use crate::mm::virt_2_phys;
17004e86ffSlogin use crate::{
18004e86ffSlogin     driver::disk::ahci::{
19004e86ffSlogin         ahcidisk::LockedAhciDisk,
20004e86ffSlogin         hba::HbaMem,
21004e86ffSlogin         hba::{HbaPort, HbaPortType},
22004e86ffSlogin     },
23004e86ffSlogin     kdebug,
24004e86ffSlogin };
25004e86ffSlogin use ahci_inode::LockedAhciInode;
268d94ea66SYJwu2023 use alloc::{
278d94ea66SYJwu2023     boxed::Box,
288d94ea66SYJwu2023     collections::LinkedList,
298d94ea66SYJwu2023     format,
308d94ea66SYJwu2023     string::{String, ToString},
318d94ea66SYJwu2023     sync::Arc,
328d94ea66SYJwu2023     vec::Vec,
33004e86ffSlogin };
348d94ea66SYJwu2023 use core::sync::atomic::compiler_fence;
35*91e9d4abSLoGin use system_error::SystemError;
36004e86ffSlogin 
37004e86ffSlogin // 仅module内可见 全局数据区  hbr_port, disks
38004e86ffSlogin static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
39004e86ffSlogin static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new());
40004e86ffSlogin 
418d94ea66SYJwu2023 const AHCI_CLASS: u8 = 0x1;
428d94ea66SYJwu2023 const AHCI_SUBCLASS: u8 = 0x6;
438d94ea66SYJwu2023 
44004e86ffSlogin /* TFES - Task File Error Status */
45004e86ffSlogin #[allow(non_upper_case_globals)]
46004e86ffSlogin pub const HBA_PxIS_TFES: u32 = 1 << 30;
47004e86ffSlogin 
488d94ea66SYJwu2023 /// @brief 寻找所有的ahci设备
498d94ea66SYJwu2023 /// @param list 链表的写锁
508d94ea66SYJwu2023 /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError>   成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err
518d94ea66SYJwu2023 fn ahci_device_search<'a>(
528d94ea66SYJwu2023     list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
538d94ea66SYJwu2023 ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> {
548d94ea66SYJwu2023     let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS);
558d94ea66SYJwu2023 
568d94ea66SYJwu2023     if result.is_empty() {
578d94ea66SYJwu2023         return Err(SystemError::ENODEV);
588d94ea66SYJwu2023     }
591496ba7bSLoGin 
601496ba7bSLoGin     return Ok(result);
618d94ea66SYJwu2023 }
628d94ea66SYJwu2023 
63004e86ffSlogin /// @brief: 初始化 ahci
641496ba7bSLoGin pub fn ahci_init() -> Result<(), SystemError> {
658d94ea66SYJwu2023     let mut list = PCI_DEVICE_LINKEDLIST.write();
668d94ea66SYJwu2023     let ahci_device = ahci_device_search(&mut list)?;
67004e86ffSlogin     // 全局数据 - 列表
68004e86ffSlogin     let mut disks_list = LOCKED_DISKS_LIST.lock();
69004e86ffSlogin 
708d94ea66SYJwu2023     for device in ahci_device {
718d94ea66SYJwu2023         let standard_device = device.as_standard_device_mut().unwrap();
728d94ea66SYJwu2023         standard_device.bar_ioremap();
737ae679ddSLoGin         // 对于每一个ahci控制器分配一块空间
74004e86ffSlogin         let ahci_port_base_vaddr =
75004e86ffSlogin             Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
768d94ea66SYJwu2023         let virtaddr = standard_device
778d94ea66SYJwu2023             .bar()
788d94ea66SYJwu2023             .ok_or(SystemError::EACCES)?
798d94ea66SYJwu2023             .get_bar(5)
808d94ea66SYJwu2023             .or(Err(SystemError::EACCES))?
818d94ea66SYJwu2023             .virtual_address()
828d94ea66SYJwu2023             .unwrap();
83004e86ffSlogin         // 最后把这个引用列表放入到全局列表
84004e86ffSlogin         let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
858d94ea66SYJwu2023         //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度
862dd9f0c7SLoGin         let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() };
872dd9f0c7SLoGin         hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() });
888d94ea66SYJwu2023         let pi = volatile_read!(hba_mem.pi);
898d94ea66SYJwu2023         let hba_mem_index = hba_mem_list.len() - 1;
90004e86ffSlogin         drop(hba_mem_list);
91004e86ffSlogin         // 初始化所有的port
92004e86ffSlogin         let mut id = 0;
93004e86ffSlogin         for j in 0..32 {
94004e86ffSlogin             if (pi >> j) & 1 > 0 {
958d94ea66SYJwu2023                 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
968d94ea66SYJwu2023                 let hba_mem_port = &mut hba_mem.ports[j];
978d94ea66SYJwu2023                 let tp = hba_mem_port.check_type();
98004e86ffSlogin                 match tp {
99004e86ffSlogin                     HbaPortType::None => {
100004e86ffSlogin                         kdebug!("<ahci_rust_init> Find a None type Disk.");
101004e86ffSlogin                     }
102004e86ffSlogin                     HbaPortType::Unknown(err) => {
103004e86ffSlogin                         kdebug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err);
104004e86ffSlogin                     }
105004e86ffSlogin                     _ => {
106004e86ffSlogin                         kdebug!("<ahci_rust_init> Find a {:?} type Disk.", tp);
107004e86ffSlogin 
108004e86ffSlogin                         // 计算地址
109004e86ffSlogin                         let fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (j << 8));
110004e86ffSlogin                         let clb = virt_2_phys(ahci_port_base_vaddr + (j << 10));
111004e86ffSlogin                         let ctbas = (0..32)
112004e86ffSlogin                             .map(|x| {
113004e86ffSlogin                                 virt_2_phys(
114004e86ffSlogin                                     ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8),
115004e86ffSlogin                                 ) as u64
116004e86ffSlogin                             })
117004e86ffSlogin                             .collect::<Vec<_>>();
118004e86ffSlogin 
119004e86ffSlogin                         // 初始化 port
1208d94ea66SYJwu2023                         hba_mem_port.init(clb as u64, fb as u64, &ctbas);
121004e86ffSlogin                         drop(hba_mem_list);
122004e86ffSlogin                         compiler_fence(core::sync::atomic::Ordering::SeqCst);
123004e86ffSlogin                         // 创建 disk
124004e86ffSlogin                         disks_list.push(LockedAhciDisk::new(
125004e86ffSlogin                             format!("ahci_disk_{}", id),
126004e86ffSlogin                             BLK_GF_AHCI,
1278d94ea66SYJwu2023                             hba_mem_index as u8,
128004e86ffSlogin                             j as u8,
129004e86ffSlogin                         )?);
130004e86ffSlogin                         id += 1; // ID 从0开始
131004e86ffSlogin 
132004e86ffSlogin                         kdebug!("start register ahci device");
133004e86ffSlogin 
134004e86ffSlogin                         // 挂载到devfs上面去
135004e86ffSlogin                         let ret = devfs_register(
136004e86ffSlogin                             format!("ahci_{}", id).as_str(),
137004e86ffSlogin                             LockedAhciInode::new(disks_list.last().unwrap().clone()),
138004e86ffSlogin                         );
139004e86ffSlogin                         if let Err(err) = ret {
140004e86ffSlogin                             kerror!(
141676b8ef6SMork                                 "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}",
142004e86ffSlogin                                 id,
1438d94ea66SYJwu2023                                 hba_mem_index as u8,
144004e86ffSlogin                                 j,
145004e86ffSlogin                                 err
146004e86ffSlogin                             );
147004e86ffSlogin                         }
148004e86ffSlogin                     }
149004e86ffSlogin                 }
150004e86ffSlogin             }
151004e86ffSlogin         }
152004e86ffSlogin     }
153004e86ffSlogin 
154004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
155004e86ffSlogin     return Ok(());
156004e86ffSlogin }
157004e86ffSlogin 
158004e86ffSlogin /// @brief: 获取所有的 disk
159004e86ffSlogin #[allow(dead_code)]
160004e86ffSlogin pub fn disks() -> Vec<Arc<LockedAhciDisk>> {
161004e86ffSlogin     let disks_list = LOCKED_DISKS_LIST.lock();
162004e86ffSlogin     return disks_list.clone();
163004e86ffSlogin }
164004e86ffSlogin 
165004e86ffSlogin /// @brief: 通过 name 获取 disk
166676b8ef6SMork pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> {
167004e86ffSlogin     let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock();
1688d94ea66SYJwu2023     let result = disks_list
1698d94ea66SYJwu2023         .iter()
1708d94ea66SYJwu2023         .find(|x| x.0.lock().name == name)
1718d94ea66SYJwu2023         .ok_or(SystemError::ENXIO)?
1728d94ea66SYJwu2023         .clone();
1738d94ea66SYJwu2023     return Ok(result);
174004e86ffSlogin }
175004e86ffSlogin 
176004e86ffSlogin /// @brief: 通过 ctrl_num 和 port_num 获取 port
1778d94ea66SYJwu2023 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
178004e86ffSlogin     let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();
179004e86ffSlogin     let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize];
1808d94ea66SYJwu2023 
181004e86ffSlogin     return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() };
182004e86ffSlogin }
183004e86ffSlogin 
184004e86ffSlogin /// @brief: 测试函数
185004e86ffSlogin pub fn __test_ahci() {
1861496ba7bSLoGin     let _res = ahci_init();
187004e86ffSlogin     let disk: Arc<LockedAhciDisk> = get_disks_by_name("ahci_disk_0".to_string()).unwrap();
188004e86ffSlogin     #[deny(overflowing_literals)]
189004e86ffSlogin     let mut buf = [0u8; 3000usize];
190004e86ffSlogin 
191004e86ffSlogin     for i in 0..2000 {
192004e86ffSlogin         buf[i] = i as u8;
193004e86ffSlogin     }
194004e86ffSlogin 
195004e86ffSlogin     let _dd = disk;
196004e86ffSlogin 
197004e86ffSlogin     // 测试1, 写两个块,读4个块
198004e86ffSlogin     // _dd.write_at(123, 2, &buf).unwrap();
199004e86ffSlogin     let mut read_buf = [0u8; 3000usize];
200004e86ffSlogin     _dd.read_at(122, 4, &mut read_buf).unwrap();
201004e86ffSlogin 
202004e86ffSlogin     // 测试2, 只读写一个字节
203004e86ffSlogin     for i in 0..512 {
204004e86ffSlogin         buf[i] = 233;
205004e86ffSlogin     }
206004e86ffSlogin     // _dd.write_at(123, 2, &buf).unwrap();
207004e86ffSlogin     let mut read_buf2 = [0u8; 3000usize];
208004e86ffSlogin     _dd.read_at(122, 4, &mut read_buf2).unwrap();
209004e86ffSlogin }
210