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