diff --git a/libconfig/src/bootgen.rs b/libconfig/src/bootgen.rs index 884f22c..004e1d9 100644 --- a/libconfig/src/bootgen.rs +++ b/libconfig/src/bootgen.rs @@ -1,5 +1,6 @@ use alloc::vec::Vec; -use core_io::{Error, Read, Seek, SeekFrom}; +use crate::sd_reader::Error +use fatfs::io::{Read, Seek, SeekFrom}; use libboard_zynq::devc; use log::debug; @@ -12,8 +13,8 @@ pub enum BootgenLoadingError { DevcError(devc::DevcError), } -impl From for BootgenLoadingError { - fn from(error: Error) -> Self { +impl From for BootgenLoadingError { + fn from(error: sd_reader::Error) -> Self { BootgenLoadingError::IoError(error) } } diff --git a/libconfig/src/lib.rs b/libconfig/src/lib.rs index 50cb34b..8aaf9dd 100644 --- a/libconfig/src/lib.rs +++ b/libconfig/src/lib.rs @@ -3,7 +3,7 @@ extern crate alloc; use core::fmt; use alloc::{string::FromUtf8Error, string::String, vec::Vec, rc::Rc}; -use core_io::{self as io, BufRead, BufReader, Read, Write, Seek, SeekFrom}; +use fatfs::io::{Read, Write, Seek, SeekFrom} use libboard_zynq::sdio; pub mod sd_reader; @@ -13,7 +13,7 @@ pub mod bootgen; #[derive(Debug)] pub enum Error<'a> { SdError(sdio::sd_card::CardInitializationError), - IoError(io::Error), + IoError(sd_reader::Error), Utf8Error(FromUtf8Error), KeyNotFoundError(&'a str), NoConfig, @@ -39,8 +39,8 @@ impl<'a> From for Error<'a> { } } -impl<'a> From for Error<'a> { - fn from(error: io::Error) -> Self { +impl<'a> From for Error<'a> { + fn from(error: sd_reader::Error) -> Self { Error::IoError(error) } } diff --git a/libconfig/src/sd_reader.rs b/libconfig/src/sd_reader.rs index 5254a07..c1da67b 100644 --- a/libconfig/src/sd_reader.rs +++ b/libconfig/src/sd_reader.rs @@ -1,8 +1,9 @@ -use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write}; use fatfs; +use fatfs::io::{Read, Seek, SeekFrom, Write} use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError}; use log::debug; use alloc::vec::Vec; +use core::fmt; const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA]; const PARTID_FAT12: u8 = 0x01; @@ -12,13 +13,46 @@ const PARTID_FAT32: u8 = 0x0B; const PARTID_FAT32_LBA: u8 = 0x0C; const PARTID_FAT16_LBA: u8 = 0x0E; -fn cmd_error_to_io_error(_: CmdTransferError) -> Error { - Error::new(ErrorKind::Other, "Command transfer error") -} - const BLOCK_SIZE: usize = 512; -/// SdReader struct implementing `Read + BufRead + Write + Seek` traits for `core_io`. +#[derive(Debug)] +pub struct Error { + message: String +} + +impl Error { + pub fn new(message: &str) -> Self { + Self { message: String::new(message) } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, self.message) + } +} + +impl IoError for Error { + fn is_interrupted(&self) -> bool { + false + } + + fn new_unexpected_eof_error() -> Self { + Error::new("Unexpected end of file error") + } + + fn new_write_zero_error() -> Self { + Error::new("Write zero error") + } +} + +impl From for Error { + fn from(_: CmdTransferError) -> Self { + Error::new("Command transfer error") + } +} + +/// SdReader struct implementing `Read + Write + Seek` traits for `core_io`. /// Used as an adaptor for fatfs crate, but could be used directly for raw data access. /// /// Implementation: all read/writes would be split into unaligned and block-aligned parts, @@ -43,6 +77,10 @@ pub struct SdReader { offset: u32, } +impl IoBase for SdReader { + type Error = Error; +} + #[derive(Copy, Clone)] #[allow(unused)] // Partition entry enum, normally we would use entry1. @@ -72,7 +110,7 @@ impl SdReader { /// Internal read function for unaligned read. /// The read must not cross block boundary. - fn read_unaligned(&mut self, buf: &mut [u8]) -> IoResult { + fn read_unaligned(&mut self, buf: &mut [u8]) -> Result { if buf.len() == 0 { return Ok(0); } @@ -86,7 +124,7 @@ impl SdReader { /// Internal write function for unaligned write. /// The write must not cross block boundary. - fn write_unaligned(&mut self, buf: &[u8]) -> IoResult { + fn write_unaligned(&mut self, buf: &[u8]) -> Result { if buf.len() == 0 { return Ok(0); } @@ -137,7 +175,7 @@ impl SdReader { } /// Set the base offset of the SD card, to transform from physical address to logical address. - fn set_base_offset(&mut self, offset: u32) -> IoResult { + fn set_base_offset(&mut self, offset: u32) -> Result { self.offset = offset; self.seek(SeekFrom::Start(0)) } @@ -145,14 +183,13 @@ impl SdReader { /// Mount fatfs from partition entry, and return the fatfs object if success. /// This takes the ownership of self, so currently there is no way to recover from an error, /// except creating a new SD card instance. - pub fn mount_fatfs(mut self, entry: PartitionEntry) -> IoResult> { + pub fn mount_fatfs(mut self, entry: PartitionEntry) -> Result> { let mut buffer: [u8; 4] = [0; 4]; self.seek(SeekFrom::Start(0x1FE))?; self.read_exact(&mut buffer[..2])?; // check MBR signature if buffer[..2] != MBR_SIGNATURE { return Err(Error::new( - ErrorKind::InvalidData, "Incorrect signature for MBR sector.", )); } @@ -165,7 +202,6 @@ impl SdReader { PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {} _ => { return Err(Error::new( - ErrorKind::InvalidData, "No FAT partition found for the specified entry.", )); } @@ -186,7 +222,7 @@ impl SdReader { } impl Read for SdReader { - fn read(&mut self, buf: &mut [u8]) -> IoResult { + fn read(&mut self, buf: &mut [u8]) -> Result { let total_length = buf.len(); let (a, b, c) = self.block_align_mut(buf); self.read_unaligned(a)?; @@ -211,30 +247,8 @@ impl Read for SdReader { } } -impl BufRead for SdReader { - fn fill_buf(&mut self) -> IoResult<&[u8]> { - if self.index == BLOCK_SIZE { - // flush the buffer if it is dirty before overwriting it with new data - if self.dirty { - self.flush()?; - } - // reload buffer - self.sd - .read_block(self.byte_addr / (BLOCK_SIZE as u32), 1, &mut self.buffer) - .map_err(cmd_error_to_io_error)?; - self.index = (self.byte_addr as usize) % BLOCK_SIZE; - } - Ok(&self.buffer[self.index..]) - } - - fn consume(&mut self, amt: usize) { - self.index += amt; - self.byte_addr += amt as u32; - } -} - impl Write for SdReader { - fn write(&mut self, buf: &[u8]) -> IoResult { + fn write(&mut self, buf: &[u8]) -> Result { let (a, b, c) = self.block_align(buf); self.write_unaligned(a)?; if b.len() > 0 { @@ -255,12 +269,11 @@ impl Write for SdReader { Ok(buf.len()) } - fn flush(&mut self) -> IoResult<()> { + fn flush(&mut self) -> Result<(), Error> { if self.dirty { let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32); self.sd - .write_block(block_addr, 1, &self.buffer) - .map_err(cmd_error_to_io_error)?; + .write_block(block_addr, 1, &self.buffer)?; self.dirty = false; } Ok(()) @@ -268,14 +281,14 @@ impl Write for SdReader { } impl Seek for SdReader { - fn seek(&mut self, pos: SeekFrom) -> IoResult { + fn seek(&mut self, pos: SeekFrom) -> Result { let raw_target = match pos { SeekFrom::Start(x) => self.offset as i64 + x as i64, SeekFrom::Current(x) => self.byte_addr as i64 + x, SeekFrom::End(_) => panic!("SD card does not support seek from end"), }; if raw_target < self.offset as i64 || raw_target > core::u32::MAX as i64 { - return Err(Error::new(ErrorKind::InvalidInput, "Invalid address")); + return Err(Error::new("Invalid address")); } let target_byte_addr = raw_target as u32; let address_same_block =