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