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