1 use super::{_port, hba::HbaCmdTable, virt_2_phys}; 2 use crate::driver::base::block::block_device::{BlockDevice, BlockId}; 3 use crate::driver::base::block::disk_info::Partition; 4 use crate::driver::base::class::Class; 5 use crate::driver::base::device::bus::Bus; 6 7 use crate::driver::base::device::driver::Driver; 8 use crate::driver::base::device::{Device, DeviceType, IdTable}; 9 use crate::driver::base::kobject::{KObjType, KObject, KObjectState}; 10 use crate::driver::base::kset::KSet; 11 use crate::driver::disk::ahci::HBA_PxIS_TFES; 12 13 use crate::filesystem::kernfs::KernFSInode; 14 use crate::filesystem::mbr::MbrDiskPartionTable; 15 16 use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard}; 17 use crate::libs::spinlock::SpinLock; 18 use crate::mm::{phys_2_virt, verify_area, VirtAddr}; 19 use crate::{ 20 driver::disk::ahci::hba::{ 21 FisRegH2D, FisType, HbaCmdHeader, ATA_CMD_READ_DMA_EXT, ATA_CMD_WRITE_DMA_EXT, 22 ATA_DEV_BUSY, ATA_DEV_DRQ, 23 }, 24 kerror, 25 }; 26 use system_error::SystemError; 27 28 use alloc::sync::Weak; 29 use alloc::{string::String, sync::Arc, vec::Vec}; 30 31 use core::fmt::Debug; 32 use core::sync::atomic::{compiler_fence, Ordering}; 33 use core::{mem::size_of, ptr::write_bytes}; 34 35 /// @brief: 只支持MBR分区格式的磁盘结构体 36 pub struct AhciDisk { 37 pub name: String, 38 pub flags: u16, // 磁盘的状态flags 39 pub partitions: Vec<Arc<Partition>>, // 磁盘分区数组 40 // port: &'static mut HbaPort, // 控制硬盘的端口 41 pub ctrl_num: u8, 42 pub port_num: u8, 43 /// 指向LockAhciDisk的弱引用 44 self_ref: Weak<LockedAhciDisk>, 45 } 46 47 /// @brief: 带锁的AhciDisk 48 #[derive(Debug)] 49 pub struct LockedAhciDisk(pub SpinLock<AhciDisk>); 50 /// 函数实现 51 impl Debug for AhciDisk { 52 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 53 write!( 54 f, 55 "{{ name: {}, flags: {}, part_s: {:?} }}", 56 self.name, self.flags, self.partitions 57 )?; 58 return Ok(()); 59 } 60 } 61 62 impl AhciDisk { 63 fn read_at( 64 &self, 65 lba_id_start: BlockId, // 起始lba编号 66 count: usize, // 读取lba的数量 67 buf: &mut [u8], 68 ) -> Result<usize, SystemError> { 69 assert!((buf.len() & 511) == 0); 70 compiler_fence(Ordering::SeqCst); 71 let check_length = ((count - 1) >> 4) + 1; // prdt length 72 if count * 512 > buf.len() || check_length > 8_usize { 73 kerror!("ahci read: e2big"); 74 // 不可能的操作 75 return Err(SystemError::E2BIG); 76 } else if count == 0 { 77 return Ok(0); 78 } 79 80 let port = _port(self.ctrl_num, self.port_num); 81 volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits 82 83 let slot = port.find_cmdslot().unwrap_or(u32::MAX); 84 85 if slot == u32::MAX { 86 return Err(SystemError::EIO); 87 } 88 89 #[allow(unused_unsafe)] 90 let cmdheader: &mut HbaCmdHeader = unsafe { 91 (phys_2_virt( 92 volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(), 93 ) as *mut HbaCmdHeader) 94 .as_mut() 95 .unwrap() 96 }; 97 98 cmdheader.cfl = (size_of::<FisRegH2D>() / size_of::<u32>()) as u8; 99 100 volatile_set_bit!(cmdheader.cfl, 1 << 6, false); // Read/Write bit : Read from device 101 volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count 102 103 // 设置数据存放地址 104 let mut buf_ptr = buf as *mut [u8] as *mut usize as usize; 105 106 // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间 107 // TODO:在内存管理重构后,可以直接使用用户空间的内存地址 108 109 let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok(); 110 let mut kbuf = if user_buf { 111 let x: Vec<u8> = vec![0; buf.len()]; 112 Some(x) 113 } else { 114 None 115 }; 116 117 if kbuf.is_some() { 118 buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize; 119 } 120 121 #[allow(unused_unsafe)] 122 let cmdtbl = unsafe { 123 (phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable) 124 .as_mut() 125 .unwrap() // 必须使用 as_mut ,得到的才是原来的变量 126 }; 127 let mut tmp_count = count; 128 129 unsafe { 130 // 清空整个table的旧数据 131 write_bytes(cmdtbl, 0, 1); 132 } 133 // kdebug!("cmdheader.prdtl={}", volatile_read!(cmdheader.prdtl)); 134 135 // 8K bytes (16 sectors) per PRDT 136 for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) { 137 volatile_write!(cmdtbl.prdt_entry[i].dba, virt_2_phys(buf_ptr) as u64); 138 cmdtbl.prdt_entry[i].dbc = 8 * 1024 - 1; 139 volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断 prdt_entry.i 140 buf_ptr += 8 * 1024; 141 tmp_count -= 16; 142 } 143 144 // Last entry 145 let las = (volatile_read!(cmdheader.prdtl) - 1) as usize; 146 volatile_write!(cmdtbl.prdt_entry[las].dba, virt_2_phys(buf_ptr) as u64); 147 cmdtbl.prdt_entry[las].dbc = ((tmp_count << 9) - 1) as u32; // 数据长度 148 149 volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断 150 151 // 设置命令 152 let cmdfis = unsafe { 153 ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D) 154 .as_mut() 155 .unwrap() 156 }; 157 volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8); 158 volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set 159 volatile_write!(cmdfis.command, ATA_CMD_READ_DMA_EXT); 160 161 volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8); 162 volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8); 163 volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8); 164 volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8); 165 volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8); 166 volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8); 167 168 volatile_write!(cmdfis.countl, (count & 0xFF) as u8); 169 volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8); 170 171 volatile_write!(cmdfis.device, 1 << 6); // LBA Mode 172 173 // 等待之前的操作完成 174 let mut spin_count = 0; 175 const SPIN_LIMIT: u32 = 10000; 176 177 while (volatile_read!(port.tfd) as u8 & (ATA_DEV_BUSY | ATA_DEV_DRQ)) > 0 178 && spin_count < SPIN_LIMIT 179 { 180 spin_count += 1; 181 } 182 183 if spin_count == SPIN_LIMIT { 184 kerror!("Port is hung"); 185 return Err(SystemError::EIO); 186 } 187 188 volatile_set_bit!(port.ci, 1 << slot, true); // Issue command 189 // kdebug!("To wait ahci read complete."); 190 // 等待操作完成 191 loop { 192 if (volatile_read!(port.ci) & (1 << slot)) == 0 { 193 break; 194 } 195 if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 { 196 kerror!("Read disk error"); 197 return Err(SystemError::EIO); 198 } 199 } 200 201 if kbuf.is_some() { 202 buf.copy_from_slice(kbuf.as_ref().unwrap()); 203 } 204 205 compiler_fence(Ordering::SeqCst); 206 // successfully read 207 return Ok(count * 512); 208 } 209 210 fn write_at( 211 &self, 212 lba_id_start: BlockId, 213 count: usize, 214 buf: &[u8], 215 ) -> Result<usize, SystemError> { 216 assert!((buf.len() & 511) == 0); 217 compiler_fence(Ordering::SeqCst); 218 let check_length = ((count - 1) >> 4) + 1; // prdt length 219 if count * 512 > buf.len() || check_length > 8 { 220 // 不可能的操作 221 return Err(SystemError::E2BIG); 222 } else if count == 0 { 223 return Ok(0); 224 } 225 226 let port = _port(self.ctrl_num, self.port_num); 227 228 volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits 229 230 let slot = port.find_cmdslot().unwrap_or(u32::MAX); 231 232 if slot == u32::MAX { 233 return Err(SystemError::EIO); 234 } 235 236 compiler_fence(Ordering::SeqCst); 237 #[allow(unused_unsafe)] 238 let cmdheader: &mut HbaCmdHeader = unsafe { 239 (phys_2_virt( 240 volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(), 241 ) as *mut HbaCmdHeader) 242 .as_mut() 243 .unwrap() 244 }; 245 compiler_fence(Ordering::SeqCst); 246 247 volatile_write_bit!( 248 cmdheader.cfl, 249 (1 << 5) - 1_u8, 250 (size_of::<FisRegH2D>() / size_of::<u32>()) as u8 251 ); // Command FIS size 252 253 volatile_set_bit!(cmdheader.cfl, 7 << 5, true); // (p,c,w)都设置为1, Read/Write bit : Write from device 254 volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count 255 256 // 设置数据存放地址 257 compiler_fence(Ordering::SeqCst); 258 let mut buf_ptr = buf as *const [u8] as *mut usize as usize; 259 260 // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间 261 // TODO:在内存管理重构后,可以直接使用用户空间的内存地址 262 let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok(); 263 let mut kbuf = if user_buf { 264 let mut x: Vec<u8> = vec![0; buf.len()]; 265 x.resize(buf.len(), 0); 266 x.copy_from_slice(buf); 267 Some(x) 268 } else { 269 None 270 }; 271 272 if kbuf.is_some() { 273 buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize; 274 } 275 276 #[allow(unused_unsafe)] 277 let cmdtbl = unsafe { 278 (phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable) 279 .as_mut() 280 .unwrap() 281 }; 282 let mut tmp_count = count; 283 compiler_fence(Ordering::SeqCst); 284 285 unsafe { 286 // 清空整个table的旧数据 287 write_bytes(cmdtbl, 0, 1); 288 } 289 290 // 8K bytes (16 sectors) per PRDT 291 for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) { 292 volatile_write!(cmdtbl.prdt_entry[i].dba, virt_2_phys(buf_ptr) as u64); 293 volatile_write_bit!(cmdtbl.prdt_entry[i].dbc, (1 << 22) - 1, 8 * 1024 - 1); // 数据长度 294 volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断 295 buf_ptr += 8 * 1024; 296 tmp_count -= 16; 297 } 298 299 // Last entry 300 let las = (volatile_read!(cmdheader.prdtl) - 1) as usize; 301 volatile_write!(cmdtbl.prdt_entry[las].dba, virt_2_phys(buf_ptr) as u64); 302 volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断 303 volatile_write_bit!( 304 cmdtbl.prdt_entry[las].dbc, 305 (1 << 22) - 1, 306 ((tmp_count << 9) - 1) as u32 307 ); // 数据长度 308 309 // 设置命令 310 let cmdfis = unsafe { 311 ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D) 312 .as_mut() 313 .unwrap() 314 }; 315 volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8); 316 volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set 317 volatile_write!(cmdfis.command, ATA_CMD_WRITE_DMA_EXT); 318 319 volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8); 320 volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8); 321 volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8); 322 volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8); 323 volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8); 324 volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8); 325 326 volatile_write!(cmdfis.countl, (count & 0xFF) as u8); 327 volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8); 328 329 volatile_write!(cmdfis.device, 1 << 6); // LBA Mode 330 331 volatile_set_bit!(port.ci, 1 << slot, true); // Issue command 332 333 // 等待操作完成 334 loop { 335 if (volatile_read!(port.ci) & (1 << slot)) == 0 { 336 break; 337 } 338 if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 { 339 kerror!("Write disk error"); 340 return Err(SystemError::EIO); 341 } 342 } 343 344 compiler_fence(Ordering::SeqCst); 345 // successfully read 346 return Ok(count * 512); 347 } 348 349 fn sync(&self) -> Result<(), SystemError> { 350 // 由于目前没有block cache, 因此sync返回成功即可 351 return Ok(()); 352 } 353 } 354 355 impl LockedAhciDisk { 356 pub fn new( 357 name: String, 358 flags: u16, 359 ctrl_num: u8, 360 port_num: u8, 361 ) -> Result<Arc<LockedAhciDisk>, SystemError> { 362 // 构建磁盘结构体 363 let result: Arc<LockedAhciDisk> = Arc::new_cyclic(|self_ref| { 364 LockedAhciDisk(SpinLock::new(AhciDisk { 365 name, 366 flags, 367 partitions: Default::default(), 368 ctrl_num, 369 port_num, 370 self_ref: self_ref.clone(), 371 })) 372 }); 373 let table: MbrDiskPartionTable = result.read_mbr_table()?; 374 375 // 求出有多少可用分区 376 let partitions = table.partitions(Arc::downgrade(&result) as Weak<dyn BlockDevice>); 377 result.0.lock().partitions = partitions; 378 379 return Ok(result); 380 } 381 382 /// @brief: 从磁盘中读取 MBR 分区表结构体 383 pub fn read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError> { 384 let disk = self.0.lock().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>; 385 MbrDiskPartionTable::from_disk(disk) 386 } 387 } 388 389 impl KObject for LockedAhciDisk { 390 fn as_any_ref(&self) -> &dyn core::any::Any { 391 self 392 } 393 394 fn inode(&self) -> Option<Arc<KernFSInode>> { 395 todo!() 396 } 397 398 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 399 todo!() 400 } 401 402 fn kset(&self) -> Option<Arc<KSet>> { 403 todo!() 404 } 405 406 fn parent(&self) -> Option<Weak<dyn KObject>> { 407 todo!() 408 } 409 410 fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) { 411 todo!() 412 } 413 414 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 415 todo!() 416 } 417 418 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 419 todo!() 420 } 421 422 fn set_kobj_state(&self, _state: KObjectState) { 423 todo!() 424 } 425 426 fn name(&self) -> alloc::string::String { 427 todo!() 428 } 429 430 fn set_name(&self, _name: alloc::string::String) { 431 todo!() 432 } 433 434 fn set_kset(&self, _kset: Option<Arc<KSet>>) { 435 todo!() 436 } 437 438 fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) { 439 todo!() 440 } 441 442 fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) { 443 todo!() 444 } 445 } 446 447 impl Device for LockedAhciDisk { 448 fn dev_type(&self) -> DeviceType { 449 return DeviceType::Block; 450 } 451 452 fn id_table(&self) -> IdTable { 453 todo!() 454 } 455 456 fn bus(&self) -> Option<Weak<dyn Bus>> { 457 todo!("LockedAhciDisk::bus()") 458 } 459 460 fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) { 461 todo!("LockedAhciDisk::set_bus()") 462 } 463 464 fn driver(&self) -> Option<Arc<dyn Driver>> { 465 todo!("LockedAhciDisk::driver()") 466 } 467 468 fn is_dead(&self) -> bool { 469 false 470 } 471 472 fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) { 473 todo!("LockedAhciDisk::set_driver()") 474 } 475 476 fn can_match(&self) -> bool { 477 todo!() 478 } 479 480 fn set_can_match(&self, _can_match: bool) { 481 todo!() 482 } 483 484 fn state_synced(&self) -> bool { 485 todo!() 486 } 487 488 fn set_class(&self, _class: Option<Weak<dyn Class>>) { 489 todo!() 490 } 491 } 492 493 impl BlockDevice for LockedAhciDisk { 494 #[inline] 495 fn as_any_ref(&self) -> &dyn core::any::Any { 496 self 497 } 498 499 #[inline] 500 fn blk_size_log2(&self) -> u8 { 501 9 502 } 503 504 fn sync(&self) -> Result<(), SystemError> { 505 return self.0.lock().sync(); 506 } 507 508 #[inline] 509 fn device(&self) -> Arc<dyn Device> { 510 return self.0.lock().self_ref.upgrade().unwrap(); 511 } 512 513 fn block_size(&self) -> usize { 514 todo!() 515 } 516 517 fn partitions(&self) -> Vec<Arc<Partition>> { 518 return self.0.lock().partitions.clone(); 519 } 520 521 #[inline] 522 fn read_at_sync( 523 &self, 524 lba_id_start: BlockId, // 起始lba编号 525 count: usize, // 读取lba的数量 526 buf: &mut [u8], 527 ) -> Result<usize, SystemError> { 528 self.0.lock().read_at(lba_id_start, count, buf) 529 } 530 531 #[inline] 532 fn write_at_sync( 533 &self, 534 lba_id_start: BlockId, 535 count: usize, 536 buf: &[u8], 537 ) -> Result<usize, SystemError> { 538 self.0.lock().write_at(lba_id_start, count, buf) 539 } 540 } 541