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