105 lines
2.5 KiB
Rust
105 lines
2.5 KiB
Rust
use core::mem::MaybeUninit;
|
|
|
|
use alloc::{boxed::Box, sync::Arc};
|
|
use async_trait::async_trait;
|
|
use device_api::device::Device;
|
|
use libk_mm::{address::PhysicalAddress, table::MapAttributes, PageProvider};
|
|
use yggdrasil_abi::error::Error;
|
|
|
|
use crate::dma::{DmaBuffer, DmaSlice, DmaSliceMut};
|
|
|
|
use super::BlockDevice;
|
|
|
|
pub mod gpt;
|
|
|
|
pub(crate) use gpt::probe_gpt;
|
|
|
|
pub struct Partition {
|
|
device: Arc<dyn BlockDevice>,
|
|
lba_start: u64,
|
|
lba_end: u64,
|
|
}
|
|
|
|
impl Partition {
|
|
pub fn new(device: Arc<dyn BlockDevice>, lba_start: u64, lba_end: u64) -> Self {
|
|
assert!(lba_start < lba_end);
|
|
Self {
|
|
device,
|
|
lba_start,
|
|
lba_end,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PageProvider for Partition {
|
|
fn get_page(&self, _offset: u64) -> Result<PhysicalAddress, Error> {
|
|
todo!()
|
|
}
|
|
|
|
fn clone_page(
|
|
&self,
|
|
_offset: u64,
|
|
_src_phys: PhysicalAddress,
|
|
_src_attrs: MapAttributes,
|
|
) -> Result<PhysicalAddress, Error> {
|
|
todo!()
|
|
}
|
|
|
|
fn release_page(&self, _offset: u64, _phys: PhysicalAddress) -> Result<(), Error> {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
impl Device for Partition {
|
|
fn display_name(&self) -> &str {
|
|
"Partition"
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl BlockDevice for Partition {
|
|
fn allocate_buffer(&self, size: usize) -> Result<DmaBuffer<[MaybeUninit<u8>]>, Error> {
|
|
self.device.allocate_buffer(size)
|
|
}
|
|
|
|
async fn read_aligned(
|
|
&self,
|
|
position: u64,
|
|
buffer: DmaSliceMut<'_, MaybeUninit<u8>>,
|
|
) -> Result<(), Error> {
|
|
// TODO check against partition bounds
|
|
let lba = self.lba_start * self.block_size() as u64 + position;
|
|
self.device.read_aligned(lba, buffer).await
|
|
}
|
|
|
|
async fn write_aligned(&self, position: u64, buffer: DmaSlice<'_, u8>) -> Result<(), Error> {
|
|
// TODO check against partition bounds
|
|
let lba = self.lba_start * self.block_size() as u64 + position;
|
|
self.device.write_aligned(lba, buffer).await
|
|
}
|
|
|
|
fn block_size(&self) -> usize {
|
|
self.device.block_size()
|
|
}
|
|
|
|
fn block_count(&self) -> u64 {
|
|
self.lba_end - self.lba_start
|
|
}
|
|
|
|
fn is_readable(&self) -> bool {
|
|
self.device.is_readable()
|
|
}
|
|
|
|
fn is_writeable(&self) -> bool {
|
|
self.device.is_writeable()
|
|
}
|
|
|
|
fn device_request(&self, option: u32, buffer: &mut [u8], len: usize) -> Result<usize, Error> {
|
|
self.device.device_request(option, buffer, len)
|
|
}
|
|
|
|
fn max_blocks_per_request(&self) -> usize {
|
|
self.device.max_blocks_per_request()
|
|
}
|
|
}
|