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