xref: /DragonOS/kernel/src/driver/disk/ahci/mod.rs (revision 004e86ff19727df303c23b42c7a271b9214c6898)
1*004e86ffSlogin // 导出 ahci 相关的 module
2*004e86ffSlogin pub mod ahci_inode;
3*004e86ffSlogin pub mod ahcidisk;
4*004e86ffSlogin pub mod hba;
5*004e86ffSlogin 
6*004e86ffSlogin use crate::io::device::BlockDevice;
7*004e86ffSlogin // 依赖的rust工具包
8*004e86ffSlogin use crate::filesystem::devfs::devfs_register;
9*004e86ffSlogin use crate::io::disk_info::BLK_GF_AHCI;
10*004e86ffSlogin use crate::kerror;
11*004e86ffSlogin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
12*004e86ffSlogin use crate::mm::virt_2_phys;
13*004e86ffSlogin use crate::{
14*004e86ffSlogin     driver::disk::ahci::{
15*004e86ffSlogin         ahcidisk::LockedAhciDisk,
16*004e86ffSlogin         hba::HbaMem,
17*004e86ffSlogin         hba::{HbaPort, HbaPortType},
18*004e86ffSlogin     },
19*004e86ffSlogin     kdebug,
20*004e86ffSlogin };
21*004e86ffSlogin use ahci_inode::LockedAhciInode;
22*004e86ffSlogin use alloc::boxed::Box;
23*004e86ffSlogin use alloc::string::ToString;
24*004e86ffSlogin use alloc::{format, string::String, sync::Arc, vec::Vec};
25*004e86ffSlogin use core::sync::atomic::compiler_fence;
26*004e86ffSlogin 
27*004e86ffSlogin // 依赖的C结构体/常量
28*004e86ffSlogin use crate::include::bindings::bindings::{
29*004e86ffSlogin     ahci_cpp_init, pci_device_structure_general_device_t, pci_device_structure_header_t,
30*004e86ffSlogin     AHCI_MAPPING_BASE, MAX_AHCI_DEVICES, PAGE_2M_MASK,
31*004e86ffSlogin };
32*004e86ffSlogin 
33*004e86ffSlogin // 仅module内可见 全局数据区  hbr_port, disks
34*004e86ffSlogin static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
35*004e86ffSlogin static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new());
36*004e86ffSlogin 
37*004e86ffSlogin /* TFES - Task File Error Status */
38*004e86ffSlogin #[allow(non_upper_case_globals)]
39*004e86ffSlogin pub const HBA_PxIS_TFES: u32 = 1 << 30;
40*004e86ffSlogin 
41*004e86ffSlogin #[no_mangle]
42*004e86ffSlogin pub extern "C" fn ahci_init() -> i32 {
43*004e86ffSlogin     let r = ahci_rust_init();
44*004e86ffSlogin     if r.is_ok() {
45*004e86ffSlogin         return 0;
46*004e86ffSlogin     } else {
47*004e86ffSlogin         return r.unwrap_err();
48*004e86ffSlogin     }
49*004e86ffSlogin }
50*004e86ffSlogin /// @brief: 初始化 ahci
51*004e86ffSlogin pub fn ahci_rust_init() -> Result<(), i32> {
52*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
53*004e86ffSlogin 
54*004e86ffSlogin     let mut ahci_dev_counts: u32 = 0;
55*004e86ffSlogin     let mut ahci_devs: [*mut pci_device_structure_header_t; MAX_AHCI_DEVICES as usize] =
56*004e86ffSlogin         [0 as *mut pci_device_structure_header_t; MAX_AHCI_DEVICES as usize];
57*004e86ffSlogin     let mut gen_devs: [*mut pci_device_structure_general_device_t; MAX_AHCI_DEVICES as usize] =
58*004e86ffSlogin         [0 as *mut pci_device_structure_general_device_t; MAX_AHCI_DEVICES as usize];
59*004e86ffSlogin 
60*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
61*004e86ffSlogin     unsafe {
62*004e86ffSlogin         // 单线程 init, 所以写 ahci_devs 全局变量不会出错?
63*004e86ffSlogin         ahci_cpp_init(
64*004e86ffSlogin             (&mut ahci_dev_counts) as *mut u32,
65*004e86ffSlogin             (&mut ahci_devs) as *mut *mut pci_device_structure_header_t,
66*004e86ffSlogin             (&mut gen_devs) as *mut *mut pci_device_structure_general_device_t,
67*004e86ffSlogin         );
68*004e86ffSlogin     }
69*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
70*004e86ffSlogin 
71*004e86ffSlogin     // 全局数据 - 列表
72*004e86ffSlogin     let mut disks_list = LOCKED_DISKS_LIST.lock();
73*004e86ffSlogin 
74*004e86ffSlogin     for i in 0..(ahci_dev_counts as usize) {
75*004e86ffSlogin         // 对于每一个ahci控制器分配一块空间 (目前slab algorithm最大支持1MB)
76*004e86ffSlogin         let ahci_port_base_vaddr =
77*004e86ffSlogin             Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
78*004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
79*004e86ffSlogin         // 获取全局引用 : 计算 HBA_MEM 的虚拟地址 依赖于C的宏定义 cal_HBA_MEM_VIRT_ADDR
80*004e86ffSlogin         let virt_addr = AHCI_MAPPING_BASE as usize + unsafe { (*gen_devs[i]).BAR5 as usize }
81*004e86ffSlogin             - (unsafe { (*gen_devs[0]).BAR5 as usize } & PAGE_2M_MASK as usize);
82*004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
83*004e86ffSlogin 
84*004e86ffSlogin         // 最后把这个引用列表放入到全局列表
85*004e86ffSlogin         let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
86*004e86ffSlogin         hba_mem_list.push(unsafe { (virt_addr as *mut HbaMem).as_mut().unwrap() });
87*004e86ffSlogin         let pi = volatile_read!(hba_mem_list[i].pi);
88*004e86ffSlogin         drop(hba_mem_list);
89*004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
90*004e86ffSlogin 
91*004e86ffSlogin         // 初始化所有的port
92*004e86ffSlogin         let mut id = 0;
93*004e86ffSlogin         for j in 0..32 {
94*004e86ffSlogin             if (pi >> j) & 1 > 0 {
95*004e86ffSlogin                 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
96*004e86ffSlogin                 let tp = hba_mem_list[i].ports[j].check_type();
97*004e86ffSlogin                 match tp {
98*004e86ffSlogin                     HbaPortType::None => {
99*004e86ffSlogin                         kdebug!("<ahci_rust_init> Find a None type Disk.");
100*004e86ffSlogin                     }
101*004e86ffSlogin                     HbaPortType::Unknown(err) => {
102*004e86ffSlogin                         kdebug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err);
103*004e86ffSlogin                     }
104*004e86ffSlogin                     _ => {
105*004e86ffSlogin                         kdebug!("<ahci_rust_init> Find a {:?} type Disk.", tp);
106*004e86ffSlogin 
107*004e86ffSlogin                         // 计算地址
108*004e86ffSlogin                         let fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (j << 8));
109*004e86ffSlogin                         let clb = virt_2_phys(ahci_port_base_vaddr + (j << 10));
110*004e86ffSlogin                         compiler_fence(core::sync::atomic::Ordering::SeqCst);
111*004e86ffSlogin                         let ctbas = (0..32)
112*004e86ffSlogin                             .map(|x| {
113*004e86ffSlogin                                 virt_2_phys(
114*004e86ffSlogin                                     ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8),
115*004e86ffSlogin                                 ) as u64
116*004e86ffSlogin                             })
117*004e86ffSlogin                             .collect::<Vec<_>>();
118*004e86ffSlogin 
119*004e86ffSlogin                         // 初始化 port
120*004e86ffSlogin                         hba_mem_list[i].ports[j].init(clb as u64, fb as u64, &ctbas);
121*004e86ffSlogin 
122*004e86ffSlogin                         // 释放锁
123*004e86ffSlogin                         drop(hba_mem_list);
124*004e86ffSlogin                         compiler_fence(core::sync::atomic::Ordering::SeqCst);
125*004e86ffSlogin 
126*004e86ffSlogin                         // 创建 disk
127*004e86ffSlogin                         disks_list.push(LockedAhciDisk::new(
128*004e86ffSlogin                             format!("ahci_disk_{}", id),
129*004e86ffSlogin                             BLK_GF_AHCI,
130*004e86ffSlogin                             i as u8,
131*004e86ffSlogin                             j as u8,
132*004e86ffSlogin                         )?);
133*004e86ffSlogin                         id += 1; // ID 从0开始
134*004e86ffSlogin 
135*004e86ffSlogin                         kdebug!("start register ahci device");
136*004e86ffSlogin 
137*004e86ffSlogin                         // 挂载到devfs上面去
138*004e86ffSlogin                         let ret = devfs_register(
139*004e86ffSlogin                             format!("ahci_{}", id).as_str(),
140*004e86ffSlogin                             LockedAhciInode::new(disks_list.last().unwrap().clone()),
141*004e86ffSlogin                         );
142*004e86ffSlogin                         if let Err(err) = ret {
143*004e86ffSlogin                             kerror!(
144*004e86ffSlogin                                 "Ahci_{} ctrl = {}, port = {} failed to register, error code = {}",
145*004e86ffSlogin                                 id,
146*004e86ffSlogin                                 i,
147*004e86ffSlogin                                 j,
148*004e86ffSlogin                                 err
149*004e86ffSlogin                             );
150*004e86ffSlogin                         }
151*004e86ffSlogin                     }
152*004e86ffSlogin                 }
153*004e86ffSlogin             }
154*004e86ffSlogin         }
155*004e86ffSlogin     }
156*004e86ffSlogin 
157*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
158*004e86ffSlogin     return Ok(());
159*004e86ffSlogin }
160*004e86ffSlogin 
161*004e86ffSlogin /// @brief: 获取所有的 disk
162*004e86ffSlogin #[allow(dead_code)]
163*004e86ffSlogin pub fn disks() -> Vec<Arc<LockedAhciDisk>> {
164*004e86ffSlogin     let disks_list = LOCKED_DISKS_LIST.lock();
165*004e86ffSlogin     return disks_list.clone();
166*004e86ffSlogin }
167*004e86ffSlogin 
168*004e86ffSlogin /// @brief: 通过 name 获取 disk
169*004e86ffSlogin pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, i32> {
170*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
171*004e86ffSlogin     let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock();
172*004e86ffSlogin     for i in 0..disks_list.len() {
173*004e86ffSlogin         if disks_list[i].0.lock().name == name {
174*004e86ffSlogin             return Ok(disks_list[i].clone());
175*004e86ffSlogin         }
176*004e86ffSlogin     }
177*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
178*004e86ffSlogin     return Err(-1);
179*004e86ffSlogin }
180*004e86ffSlogin 
181*004e86ffSlogin /// @brief: 通过 ctrl_num 和 port_num 获取 port
182*004e86ffSlogin pub fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
183*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
184*004e86ffSlogin     let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();
185*004e86ffSlogin     let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize];
186*004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
187*004e86ffSlogin     return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() };
188*004e86ffSlogin }
189*004e86ffSlogin 
190*004e86ffSlogin /// @brief: 测试函数
191*004e86ffSlogin pub fn __test_ahci() {
192*004e86ffSlogin     let _res = ahci_rust_init();
193*004e86ffSlogin     let disk: Arc<LockedAhciDisk> = get_disks_by_name("ahci_disk_0".to_string()).unwrap();
194*004e86ffSlogin     #[deny(overflowing_literals)]
195*004e86ffSlogin     let mut buf = [0u8; 3000usize];
196*004e86ffSlogin 
197*004e86ffSlogin     for i in 0..2000 {
198*004e86ffSlogin         buf[i] = i as u8;
199*004e86ffSlogin     }
200*004e86ffSlogin 
201*004e86ffSlogin     let _dd = disk;
202*004e86ffSlogin 
203*004e86ffSlogin     // 测试1, 写两个块,读4个块
204*004e86ffSlogin     // _dd.write_at(123, 2, &buf).unwrap();
205*004e86ffSlogin     let mut read_buf = [0u8; 3000usize];
206*004e86ffSlogin     _dd.read_at(122, 4, &mut read_buf).unwrap();
207*004e86ffSlogin 
208*004e86ffSlogin     // 测试2, 只读写一个字节
209*004e86ffSlogin     for i in 0..512 {
210*004e86ffSlogin         buf[i] = 233;
211*004e86ffSlogin     }
212*004e86ffSlogin     // _dd.write_at(123, 2, &buf).unwrap();
213*004e86ffSlogin     let mut read_buf2 = [0u8; 3000usize];
214*004e86ffSlogin     _dd.read_at(122, 4, &mut read_buf2).unwrap();
215*004e86ffSlogin }
216