xref: /DragonOS/kernel/src/driver/disk/ahci/ahcidisk.rs (revision c566df451ce6dbf2af684333e68b39fdfff86498)
1004e86ffSlogin use super::{_port, hba::HbaCmdTable, virt_2_phys};
2b087521eSChiichen use crate::driver::base::block::block_device::{BlockDevice, BlockId};
3b087521eSChiichen use crate::driver::base::block::disk_info::Partition;
4b087521eSChiichen use crate::driver::base::block::SeekFrom;
508a2ee40SLoGin use crate::driver::base::class::Class;
606d5e247SLoGin use crate::driver::base::device::bus::Bus;
7ad1d649eSGnoCiYeH 
8a03c4f9dSLoGin use crate::driver::base::device::driver::Driver;
906d5e247SLoGin use crate::driver::base::device::{Device, DeviceType, IdTable};
1006d5e247SLoGin use crate::driver::base::kobject::{KObjType, KObject, KObjectState};
1106d5e247SLoGin use crate::driver::base::kset::KSet;
12004e86ffSlogin use crate::driver::disk::ahci::HBA_PxIS_TFES;
13a03c4f9dSLoGin 
1406d5e247SLoGin use crate::filesystem::kernfs::KernFSInode;
15004e86ffSlogin use crate::filesystem::mbr::MbrDiskPartionTable;
16004e86ffSlogin 
17b087521eSChiichen use crate::kdebug;
1806d5e247SLoGin use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard};
19004e86ffSlogin use crate::libs::{spinlock::SpinLock, vec_cursor::VecCursor};
204fda81ceSLoGin use crate::mm::{phys_2_virt, verify_area, VirtAddr};
21004e86ffSlogin use crate::{
22004e86ffSlogin     driver::disk::ahci::hba::{
23004e86ffSlogin         FisRegH2D, FisType, HbaCmdHeader, ATA_CMD_READ_DMA_EXT, ATA_CMD_WRITE_DMA_EXT,
24004e86ffSlogin         ATA_DEV_BUSY, ATA_DEV_DRQ,
25004e86ffSlogin     },
26004e86ffSlogin     kerror,
27004e86ffSlogin };
2891e9d4abSLoGin use system_error::SystemError;
29004e86ffSlogin 
30004e86ffSlogin use alloc::sync::Weak;
31004e86ffSlogin use alloc::{string::String, sync::Arc, vec::Vec};
32004e86ffSlogin 
33004e86ffSlogin use core::fmt::Debug;
347ae679ddSLoGin use core::sync::atomic::{compiler_fence, Ordering};
35004e86ffSlogin use core::{mem::size_of, ptr::write_bytes};
36004e86ffSlogin 
37004e86ffSlogin /// @brief: 只支持MBR分区格式的磁盘结构体
38004e86ffSlogin pub struct AhciDisk {
39004e86ffSlogin     pub name: String,
40004e86ffSlogin     pub flags: u16,                      // 磁盘的状态flags
41004e86ffSlogin     pub partitions: Vec<Arc<Partition>>, // 磁盘分区数组
42004e86ffSlogin     // port: &'static mut HbaPort,      // 控制硬盘的端口
43004e86ffSlogin     pub ctrl_num: u8,
44004e86ffSlogin     pub port_num: u8,
45004e86ffSlogin     /// 指向LockAhciDisk的弱引用
46004e86ffSlogin     self_ref: Weak<LockedAhciDisk>,
47004e86ffSlogin }
48004e86ffSlogin 
49004e86ffSlogin /// @brief: 带锁的AhciDisk
50004e86ffSlogin #[derive(Debug)]
51004e86ffSlogin pub struct LockedAhciDisk(pub SpinLock<AhciDisk>);
52004e86ffSlogin /// 函数实现
53004e86ffSlogin impl Debug for AhciDisk {
54004e86ffSlogin     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55004e86ffSlogin         write!(
56004e86ffSlogin             f,
57004e86ffSlogin             "{{ name: {}, flags: {}, part_s: {:?} }}",
58004e86ffSlogin             self.name, self.flags, self.partitions
59004e86ffSlogin         )?;
60004e86ffSlogin         return Ok(());
61004e86ffSlogin     }
62004e86ffSlogin }
63004e86ffSlogin 
64004e86ffSlogin impl AhciDisk {
65004e86ffSlogin     fn read_at(
66004e86ffSlogin         &self,
67b087521eSChiichen         lba_id_start: BlockId, // 起始lba编号
68004e86ffSlogin         count: usize,          // 读取lba的数量
69004e86ffSlogin         buf: &mut [u8],
70676b8ef6SMork     ) -> Result<usize, SystemError> {
717ae679ddSLoGin         assert!((buf.len() & 511) == 0);
72004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
73004e86ffSlogin         let check_length = ((count - 1) >> 4) + 1; // prdt length
747ae679ddSLoGin         if count * 512 > buf.len() || check_length > 8 as usize {
75004e86ffSlogin             kerror!("ahci read: e2big");
76004e86ffSlogin             // 不可能的操作
77676b8ef6SMork             return Err(SystemError::E2BIG);
78004e86ffSlogin         } else if count == 0 {
79004e86ffSlogin             return Ok(0);
80004e86ffSlogin         }
81004e86ffSlogin 
82004e86ffSlogin         let port = _port(self.ctrl_num, self.port_num);
83004e86ffSlogin         volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits
84004e86ffSlogin 
85004e86ffSlogin         let slot = port.find_cmdslot().unwrap_or(u32::MAX);
86004e86ffSlogin 
87004e86ffSlogin         if slot == u32::MAX {
88676b8ef6SMork             return Err(SystemError::EIO);
89004e86ffSlogin         }
90004e86ffSlogin 
91004e86ffSlogin         #[allow(unused_unsafe)]
92004e86ffSlogin         let cmdheader: &mut HbaCmdHeader = unsafe {
93004e86ffSlogin             (phys_2_virt(
94004e86ffSlogin                 volatile_read!(port.clb) as usize
95004e86ffSlogin                     + slot as usize * size_of::<HbaCmdHeader>() as usize,
96004e86ffSlogin             ) as *mut HbaCmdHeader)
97004e86ffSlogin                 .as_mut()
98004e86ffSlogin                 .unwrap()
99004e86ffSlogin         };
100004e86ffSlogin 
1017ae679ddSLoGin         cmdheader.cfl = (size_of::<FisRegH2D>() / size_of::<u32>()) as u8;
102004e86ffSlogin 
103004e86ffSlogin         volatile_set_bit!(cmdheader.cfl, 1 << 6, false); //  Read/Write bit : Read from device
104004e86ffSlogin         volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count
105004e86ffSlogin 
106004e86ffSlogin         // 设置数据存放地址
107004e86ffSlogin         let mut buf_ptr = buf as *mut [u8] as *mut usize as usize;
108660a04ceSlogin 
109660a04ceSlogin         // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
110660a04ceSlogin         // TODO:在内存管理重构后,可以直接使用用户空间的内存地址
1114fda81ceSLoGin 
1124fda81ceSLoGin         let user_buf = verify_area(VirtAddr::new(buf_ptr as usize), buf.len()).is_ok();
113660a04ceSlogin         let mut kbuf = if user_buf {
1147ae679ddSLoGin             let mut x: Vec<u8> = Vec::new();
1157ae679ddSLoGin             x.resize(buf.len(), 0);
116660a04ceSlogin             Some(x)
117660a04ceSlogin         } else {
118660a04ceSlogin             None
119660a04ceSlogin         };
120660a04ceSlogin 
121660a04ceSlogin         if kbuf.is_some() {
122660a04ceSlogin             buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
123660a04ceSlogin         }
124660a04ceSlogin 
125004e86ffSlogin         #[allow(unused_unsafe)]
126004e86ffSlogin         let cmdtbl = unsafe {
127004e86ffSlogin             (phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable)
128004e86ffSlogin                 .as_mut()
129004e86ffSlogin                 .unwrap() // 必须使用 as_mut ,得到的才是原来的变量
130004e86ffSlogin         };
131004e86ffSlogin         let mut tmp_count = count;
132004e86ffSlogin 
133004e86ffSlogin         unsafe {
134004e86ffSlogin             // 清空整个table的旧数据
135004e86ffSlogin             write_bytes(cmdtbl, 0, 1);
136004e86ffSlogin         }
1377ae679ddSLoGin         // kdebug!("cmdheader.prdtl={}", volatile_read!(cmdheader.prdtl));
138004e86ffSlogin 
139004e86ffSlogin         // 8K bytes (16 sectors) per PRDT
140004e86ffSlogin         for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) {
141004e86ffSlogin             volatile_write!(cmdtbl.prdt_entry[i].dba, virt_2_phys(buf_ptr) as u64);
1427ae679ddSLoGin             cmdtbl.prdt_entry[i].dbc = 8 * 1024 - 1;
143004e86ffSlogin             volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断 prdt_entry.i
144004e86ffSlogin             buf_ptr += 8 * 1024;
145004e86ffSlogin             tmp_count -= 16;
146004e86ffSlogin         }
147004e86ffSlogin 
148004e86ffSlogin         // Last entry
149004e86ffSlogin         let las = (volatile_read!(cmdheader.prdtl) - 1) as usize;
150004e86ffSlogin         volatile_write!(cmdtbl.prdt_entry[las].dba, virt_2_phys(buf_ptr) as u64);
1517ae679ddSLoGin         cmdtbl.prdt_entry[las].dbc = ((tmp_count << 9) - 1) as u32; // 数据长度
1527ae679ddSLoGin 
153004e86ffSlogin         volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断
154004e86ffSlogin 
155004e86ffSlogin         // 设置命令
156004e86ffSlogin         let cmdfis = unsafe {
157004e86ffSlogin             ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D)
158004e86ffSlogin                 .as_mut()
159004e86ffSlogin                 .unwrap()
160004e86ffSlogin         };
161004e86ffSlogin         volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8);
162004e86ffSlogin         volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set
163004e86ffSlogin         volatile_write!(cmdfis.command, ATA_CMD_READ_DMA_EXT);
164004e86ffSlogin 
165004e86ffSlogin         volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8);
166004e86ffSlogin         volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8);
167004e86ffSlogin         volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8);
168004e86ffSlogin         volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8);
169004e86ffSlogin         volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8);
170004e86ffSlogin         volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8);
171004e86ffSlogin 
172004e86ffSlogin         volatile_write!(cmdfis.countl, (count & 0xFF) as u8);
173004e86ffSlogin         volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8);
174004e86ffSlogin 
175004e86ffSlogin         volatile_write!(cmdfis.device, 1 << 6); // LBA Mode
176004e86ffSlogin 
177004e86ffSlogin         // 等待之前的操作完成
178004e86ffSlogin         let mut spin_count = 0;
179004e86ffSlogin         const SPIN_LIMIT: u32 = 10000;
180004e86ffSlogin 
181004e86ffSlogin         while (volatile_read!(port.tfd) as u8 & (ATA_DEV_BUSY | ATA_DEV_DRQ)) > 0
182004e86ffSlogin             && spin_count < SPIN_LIMIT
183004e86ffSlogin         {
184004e86ffSlogin             spin_count += 1;
185004e86ffSlogin         }
186004e86ffSlogin 
187004e86ffSlogin         if spin_count == SPIN_LIMIT {
188004e86ffSlogin             kerror!("Port is hung");
189676b8ef6SMork             return Err(SystemError::EIO);
190004e86ffSlogin         }
191004e86ffSlogin 
192004e86ffSlogin         volatile_set_bit!(port.ci, 1 << slot, true); // Issue command
193004e86ffSlogin                                                      // kdebug!("To wait ahci read complete.");
194004e86ffSlogin                                                      // 等待操作完成
195004e86ffSlogin         loop {
196004e86ffSlogin             if (volatile_read!(port.ci) & (1 << slot)) == 0 {
197004e86ffSlogin                 break;
198004e86ffSlogin             }
199004e86ffSlogin             if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 {
200004e86ffSlogin                 kerror!("Read disk error");
201676b8ef6SMork                 return Err(SystemError::EIO);
202004e86ffSlogin             }
203004e86ffSlogin         }
204004e86ffSlogin 
205660a04ceSlogin         if kbuf.is_some() {
206660a04ceSlogin             buf.copy_from_slice(kbuf.as_ref().unwrap());
207660a04ceSlogin         }
208660a04ceSlogin 
209004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
210004e86ffSlogin         // successfully read
211004e86ffSlogin         return Ok(count * 512);
212004e86ffSlogin     }
213004e86ffSlogin 
214004e86ffSlogin     fn write_at(
215004e86ffSlogin         &self,
216b087521eSChiichen         lba_id_start: BlockId,
217004e86ffSlogin         count: usize,
218004e86ffSlogin         buf: &[u8],
219676b8ef6SMork     ) -> Result<usize, SystemError> {
2207ae679ddSLoGin         assert!((buf.len() & 511) == 0);
221004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
222004e86ffSlogin         let check_length = ((count - 1) >> 4) + 1; // prdt length
2237ae679ddSLoGin         if count * 512 > buf.len() || check_length > 8 as usize {
224004e86ffSlogin             // 不可能的操作
225676b8ef6SMork             return Err(SystemError::E2BIG);
226004e86ffSlogin         } else if count == 0 {
227004e86ffSlogin             return Ok(0);
228004e86ffSlogin         }
229004e86ffSlogin 
230004e86ffSlogin         let port = _port(self.ctrl_num, self.port_num);
231004e86ffSlogin 
232004e86ffSlogin         volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits
233004e86ffSlogin 
234004e86ffSlogin         let slot = port.find_cmdslot().unwrap_or(u32::MAX);
235004e86ffSlogin 
236004e86ffSlogin         if slot == u32::MAX {
237676b8ef6SMork             return Err(SystemError::EIO);
238004e86ffSlogin         }
239004e86ffSlogin 
240004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
241004e86ffSlogin         #[allow(unused_unsafe)]
242004e86ffSlogin         let cmdheader: &mut HbaCmdHeader = unsafe {
243004e86ffSlogin             (phys_2_virt(
244004e86ffSlogin                 volatile_read!(port.clb) as usize
245004e86ffSlogin                     + slot as usize * size_of::<HbaCmdHeader>() as usize,
246004e86ffSlogin             ) as *mut HbaCmdHeader)
247004e86ffSlogin                 .as_mut()
248004e86ffSlogin                 .unwrap()
249004e86ffSlogin         };
250004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
251004e86ffSlogin 
252004e86ffSlogin         volatile_write_bit!(
253004e86ffSlogin             cmdheader.cfl,
254004e86ffSlogin             (1 << 5) - 1 as u8,
255004e86ffSlogin             (size_of::<FisRegH2D>() / size_of::<u32>()) as u8
256004e86ffSlogin         ); // Command FIS size
257004e86ffSlogin 
258004e86ffSlogin         volatile_set_bit!(cmdheader.cfl, 7 << 5, true); // (p,c,w)都设置为1, Read/Write bit :  Write from device
259004e86ffSlogin         volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count
260004e86ffSlogin 
261004e86ffSlogin         // 设置数据存放地址
262004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
263004e86ffSlogin         let mut buf_ptr = buf as *const [u8] as *mut usize as usize;
264660a04ceSlogin 
265660a04ceSlogin         // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
266660a04ceSlogin         // TODO:在内存管理重构后,可以直接使用用户空间的内存地址
2674fda81ceSLoGin         let user_buf = verify_area(VirtAddr::new(buf_ptr as usize), buf.len()).is_ok();
268660a04ceSlogin         let mut kbuf = if user_buf {
269660a04ceSlogin             let mut x: Vec<u8> = Vec::with_capacity(buf.len());
270660a04ceSlogin             x.resize(buf.len(), 0);
271660a04ceSlogin             x.copy_from_slice(buf);
272660a04ceSlogin             Some(x)
273660a04ceSlogin         } else {
274660a04ceSlogin             None
275660a04ceSlogin         };
276660a04ceSlogin 
277660a04ceSlogin         if kbuf.is_some() {
278660a04ceSlogin             buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
279660a04ceSlogin         }
280660a04ceSlogin 
281004e86ffSlogin         #[allow(unused_unsafe)]
282004e86ffSlogin         let cmdtbl = unsafe {
283004e86ffSlogin             (phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable)
284004e86ffSlogin                 .as_mut()
285004e86ffSlogin                 .unwrap()
286004e86ffSlogin         };
287004e86ffSlogin         let mut tmp_count = count;
288004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
289004e86ffSlogin 
290004e86ffSlogin         unsafe {
291004e86ffSlogin             // 清空整个table的旧数据
292004e86ffSlogin             write_bytes(cmdtbl, 0, 1);
293004e86ffSlogin         }
294004e86ffSlogin 
295004e86ffSlogin         // 8K bytes (16 sectors) per PRDT
296004e86ffSlogin         for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) {
297004e86ffSlogin             volatile_write!(cmdtbl.prdt_entry[i].dba, virt_2_phys(buf_ptr) as u64);
298004e86ffSlogin             volatile_write_bit!(cmdtbl.prdt_entry[i].dbc, (1 << 22) - 1, 8 * 1024 - 1); // 数据长度
299004e86ffSlogin             volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断
300004e86ffSlogin             buf_ptr += 8 * 1024;
301004e86ffSlogin             tmp_count -= 16;
302004e86ffSlogin         }
303004e86ffSlogin 
304004e86ffSlogin         // Last entry
305004e86ffSlogin         let las = (volatile_read!(cmdheader.prdtl) - 1) as usize;
306004e86ffSlogin         volatile_write!(cmdtbl.prdt_entry[las].dba, virt_2_phys(buf_ptr) as u64);
307004e86ffSlogin         volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断
308004e86ffSlogin         volatile_write_bit!(
309004e86ffSlogin             cmdtbl.prdt_entry[las].dbc,
310004e86ffSlogin             (1 << 22) - 1,
311004e86ffSlogin             ((tmp_count << 9) - 1) as u32
312004e86ffSlogin         ); // 数据长度
313004e86ffSlogin 
314004e86ffSlogin         // 设置命令
315004e86ffSlogin         let cmdfis = unsafe {
316004e86ffSlogin             ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D)
317004e86ffSlogin                 .as_mut()
318004e86ffSlogin                 .unwrap()
319004e86ffSlogin         };
320004e86ffSlogin         volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8);
321004e86ffSlogin         volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set
322004e86ffSlogin         volatile_write!(cmdfis.command, ATA_CMD_WRITE_DMA_EXT);
323004e86ffSlogin 
324004e86ffSlogin         volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8);
325004e86ffSlogin         volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8);
326004e86ffSlogin         volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8);
327004e86ffSlogin         volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8);
328004e86ffSlogin         volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8);
329004e86ffSlogin         volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8);
330004e86ffSlogin 
331004e86ffSlogin         volatile_write!(cmdfis.countl, (count & 0xFF) as u8);
332004e86ffSlogin         volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8);
333004e86ffSlogin 
334004e86ffSlogin         volatile_write!(cmdfis.device, 1 << 6); // LBA Mode
335004e86ffSlogin 
336004e86ffSlogin         volatile_set_bit!(port.ci, 1 << slot, true); // Issue command
337004e86ffSlogin 
338004e86ffSlogin         // 等待操作完成
339004e86ffSlogin         loop {
340004e86ffSlogin             if (volatile_read!(port.ci) & (1 << slot)) == 0 {
341004e86ffSlogin                 break;
342004e86ffSlogin             }
343004e86ffSlogin             if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 {
344004e86ffSlogin                 kerror!("Write disk error");
345676b8ef6SMork                 return Err(SystemError::EIO);
346004e86ffSlogin             }
347004e86ffSlogin         }
348004e86ffSlogin 
349004e86ffSlogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
350004e86ffSlogin         // successfully read
351004e86ffSlogin         return Ok(count * 512);
352004e86ffSlogin     }
353004e86ffSlogin 
354676b8ef6SMork     fn sync(&self) -> Result<(), SystemError> {
355004e86ffSlogin         // 由于目前没有block cache, 因此sync返回成功即可
356004e86ffSlogin         return Ok(());
357004e86ffSlogin     }
358004e86ffSlogin }
359004e86ffSlogin 
360004e86ffSlogin impl LockedAhciDisk {
361004e86ffSlogin     pub fn new(
362004e86ffSlogin         name: String,
363004e86ffSlogin         flags: u16,
364004e86ffSlogin         ctrl_num: u8,
365004e86ffSlogin         port_num: u8,
366676b8ef6SMork     ) -> Result<Arc<LockedAhciDisk>, SystemError> {
367004e86ffSlogin         // 构建磁盘结构体
368004e86ffSlogin         let result: Arc<LockedAhciDisk> = Arc::new(LockedAhciDisk(SpinLock::new(AhciDisk {
369004e86ffSlogin             name,
370004e86ffSlogin             flags,
371004e86ffSlogin             partitions: Default::default(),
372004e86ffSlogin             ctrl_num,
373004e86ffSlogin             port_num,
374004e86ffSlogin             self_ref: Weak::default(),
375004e86ffSlogin         })));
376004e86ffSlogin 
377004e86ffSlogin         let table: MbrDiskPartionTable = result.read_mbr_table()?;
378004e86ffSlogin 
379004e86ffSlogin         // 求出有多少可用分区
380004e86ffSlogin         for i in 0..4 {
3817ae679ddSLoGin             compiler_fence(Ordering::SeqCst);
382004e86ffSlogin             if table.dpte[i].part_type != 0 {
3837ae679ddSLoGin                 let w = Arc::downgrade(&result);
3847ae679ddSLoGin                 result.0.lock().partitions.push(Partition::new(
385004e86ffSlogin                     table.dpte[i].starting_sector() as u64,
386004e86ffSlogin                     table.dpte[i].starting_lba as u64,
387004e86ffSlogin                     table.dpte[i].total_sectors as u64,
3887ae679ddSLoGin                     w,
389004e86ffSlogin                     i as u16,
390004e86ffSlogin                 ));
391004e86ffSlogin             }
392004e86ffSlogin         }
3937ae679ddSLoGin 
3947ae679ddSLoGin         result.0.lock().self_ref = Arc::downgrade(&result);
3957ae679ddSLoGin 
396004e86ffSlogin         return Ok(result);
397004e86ffSlogin     }
398004e86ffSlogin 
399004e86ffSlogin     /// @brief: 从磁盘中读取 MBR 分区表结构体 TODO: Cursor
400676b8ef6SMork     pub fn read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError> {
401004e86ffSlogin         let mut table: MbrDiskPartionTable = Default::default();
402004e86ffSlogin 
403004e86ffSlogin         // 数据缓冲区
404004e86ffSlogin         let mut buf: Vec<u8> = Vec::new();
405004e86ffSlogin         buf.resize(size_of::<MbrDiskPartionTable>(), 0);
406004e86ffSlogin 
4077ae679ddSLoGin         self.read_at(0, 1, &mut buf)?;
408004e86ffSlogin         // 创建 Cursor 用于按字节读取
409004e86ffSlogin         let mut cursor = VecCursor::new(buf);
410004e86ffSlogin         cursor.seek(SeekFrom::SeekCurrent(446))?;
411004e86ffSlogin 
412004e86ffSlogin         for i in 0..4 {
413b087521eSChiichen             kdebug!("infomation of partition {}:\n", i);
414004e86ffSlogin 
415004e86ffSlogin             table.dpte[i].flags = cursor.read_u8()?;
416004e86ffSlogin             table.dpte[i].starting_head = cursor.read_u8()?;
417004e86ffSlogin             table.dpte[i].starting_sector_cylinder = cursor.read_u16()?;
418004e86ffSlogin             table.dpte[i].part_type = cursor.read_u8()?;
419004e86ffSlogin             table.dpte[i].ending_head = cursor.read_u8()?;
420004e86ffSlogin             table.dpte[i].ending_sector_cylingder = cursor.read_u16()?;
421004e86ffSlogin             table.dpte[i].starting_lba = cursor.read_u32()?;
422004e86ffSlogin             table.dpte[i].total_sectors = cursor.read_u32()?;
423004e86ffSlogin 
424b087521eSChiichen             kdebug!("dpte[i] = {:?}", table.dpte[i]);
425004e86ffSlogin         }
426004e86ffSlogin         table.bs_trailsig = cursor.read_u16()?;
427004e86ffSlogin         // kdebug!("bs_trailsig = {}", unsafe {
428004e86ffSlogin         //     read_unaligned(addr_of!(table.bs_trailsig))
429004e86ffSlogin         // });
430004e86ffSlogin 
431004e86ffSlogin         return Ok(table);
432004e86ffSlogin     }
433004e86ffSlogin }
434004e86ffSlogin 
43506d5e247SLoGin impl KObject for LockedAhciDisk {
43606d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any {
43706d5e247SLoGin         self
43806d5e247SLoGin     }
43906d5e247SLoGin 
44006d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>> {
44106d5e247SLoGin         todo!()
44206d5e247SLoGin     }
44306d5e247SLoGin 
44406d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
44506d5e247SLoGin         todo!()
44606d5e247SLoGin     }
44706d5e247SLoGin 
44806d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>> {
44906d5e247SLoGin         todo!()
45006d5e247SLoGin     }
45106d5e247SLoGin 
45206d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>> {
45306d5e247SLoGin         todo!()
45406d5e247SLoGin     }
45506d5e247SLoGin 
45606d5e247SLoGin     fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) {
45706d5e247SLoGin         todo!()
45806d5e247SLoGin     }
45906d5e247SLoGin 
46006d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
46106d5e247SLoGin         todo!()
46206d5e247SLoGin     }
46306d5e247SLoGin 
46406d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
46506d5e247SLoGin         todo!()
46606d5e247SLoGin     }
46706d5e247SLoGin 
46806d5e247SLoGin     fn set_kobj_state(&self, _state: KObjectState) {
46906d5e247SLoGin         todo!()
47006d5e247SLoGin     }
47106d5e247SLoGin 
47206d5e247SLoGin     fn name(&self) -> alloc::string::String {
47306d5e247SLoGin         todo!()
47406d5e247SLoGin     }
47506d5e247SLoGin 
47606d5e247SLoGin     fn set_name(&self, _name: alloc::string::String) {
47706d5e247SLoGin         todo!()
47806d5e247SLoGin     }
47906d5e247SLoGin 
48006d5e247SLoGin     fn set_kset(&self, _kset: Option<Arc<KSet>>) {
48106d5e247SLoGin         todo!()
48206d5e247SLoGin     }
48306d5e247SLoGin 
48406d5e247SLoGin     fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) {
48506d5e247SLoGin         todo!()
48606d5e247SLoGin     }
487a03c4f9dSLoGin 
488a03c4f9dSLoGin     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
489a03c4f9dSLoGin         todo!()
490a03c4f9dSLoGin     }
49106d5e247SLoGin }
492b087521eSChiichen 
493b087521eSChiichen impl Device for LockedAhciDisk {
494b087521eSChiichen     fn dev_type(&self) -> DeviceType {
495b087521eSChiichen         return DeviceType::Block;
496b087521eSChiichen     }
497b087521eSChiichen 
49806d5e247SLoGin     fn id_table(&self) -> IdTable {
499b087521eSChiichen         todo!()
500b087521eSChiichen     }
501b087521eSChiichen 
502*c566df45SLoGin     fn bus(&self) -> Option<Weak<dyn Bus>> {
50306d5e247SLoGin         todo!("LockedAhciDisk::bus()")
504b087521eSChiichen     }
505b087521eSChiichen 
506*c566df45SLoGin     fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
507a03c4f9dSLoGin         todo!("LockedAhciDisk::set_bus()")
508a03c4f9dSLoGin     }
509a03c4f9dSLoGin 
51006d5e247SLoGin     fn driver(&self) -> Option<Arc<dyn Driver>> {
51106d5e247SLoGin         todo!("LockedAhciDisk::driver()")
51206d5e247SLoGin     }
51306d5e247SLoGin 
51406d5e247SLoGin     fn is_dead(&self) -> bool {
51506d5e247SLoGin         false
51606d5e247SLoGin     }
51706d5e247SLoGin 
518a03c4f9dSLoGin     fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
51906d5e247SLoGin         todo!("LockedAhciDisk::set_driver()")
520b087521eSChiichen     }
521a03c4f9dSLoGin 
522a03c4f9dSLoGin     fn can_match(&self) -> bool {
523a03c4f9dSLoGin         todo!()
524a03c4f9dSLoGin     }
525a03c4f9dSLoGin 
526a03c4f9dSLoGin     fn set_can_match(&self, _can_match: bool) {
527a03c4f9dSLoGin         todo!()
528a03c4f9dSLoGin     }
529a03c4f9dSLoGin 
530a03c4f9dSLoGin     fn state_synced(&self) -> bool {
531a03c4f9dSLoGin         todo!()
532a03c4f9dSLoGin     }
53308a2ee40SLoGin 
53408a2ee40SLoGin     fn set_class(&self, _class: Option<Arc<dyn Class>>) {
53508a2ee40SLoGin         todo!()
53608a2ee40SLoGin     }
537b087521eSChiichen }
538b087521eSChiichen 
539004e86ffSlogin impl BlockDevice for LockedAhciDisk {
540004e86ffSlogin     #[inline]
541004e86ffSlogin     fn as_any_ref(&self) -> &dyn core::any::Any {
542004e86ffSlogin         self
543004e86ffSlogin     }
544004e86ffSlogin 
545004e86ffSlogin     #[inline]
546004e86ffSlogin     fn blk_size_log2(&self) -> u8 {
547004e86ffSlogin         9
548004e86ffSlogin     }
549004e86ffSlogin 
550676b8ef6SMork     fn sync(&self) -> Result<(), SystemError> {
551004e86ffSlogin         return self.0.lock().sync();
552004e86ffSlogin     }
553004e86ffSlogin 
554004e86ffSlogin     #[inline]
555b087521eSChiichen     fn device(&self) -> Arc<dyn Device> {
556004e86ffSlogin         return self.0.lock().self_ref.upgrade().unwrap();
557004e86ffSlogin     }
558004e86ffSlogin 
559004e86ffSlogin     fn block_size(&self) -> usize {
560004e86ffSlogin         todo!()
561004e86ffSlogin     }
562004e86ffSlogin 
563004e86ffSlogin     fn partitions(&self) -> Vec<Arc<Partition>> {
564004e86ffSlogin         return self.0.lock().partitions.clone();
565004e86ffSlogin     }
566b087521eSChiichen 
567b087521eSChiichen     #[inline]
568b087521eSChiichen     fn read_at(
569b087521eSChiichen         &self,
570b087521eSChiichen         lba_id_start: BlockId, // 起始lba编号
571b087521eSChiichen         count: usize,          // 读取lba的数量
572b087521eSChiichen         buf: &mut [u8],
573b087521eSChiichen     ) -> Result<usize, SystemError> {
574b087521eSChiichen         self.0.lock().read_at(lba_id_start, count, buf)
575b087521eSChiichen     }
576b087521eSChiichen 
577b087521eSChiichen     #[inline]
578b087521eSChiichen     fn write_at(
579b087521eSChiichen         &self,
580b087521eSChiichen         lba_id_start: BlockId,
581b087521eSChiichen         count: usize,
582b087521eSChiichen         buf: &[u8],
583b087521eSChiichen     ) -> Result<usize, SystemError> {
584b087521eSChiichen         self.0.lock().write_at(lba_id_start, count, buf)
585b087521eSChiichen     }
586004e86ffSlogin }
587