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