Skip to content

Commit

Permalink
The disk operations now works with any size buffer
Browse files Browse the repository at this point in the history
Also fixed a bunch of typos thanks to a new vscode extension
  • Loading branch information
alloncm committed Sep 30, 2023
1 parent 41aeb6a commit d570013
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 89 deletions.
12 changes: 6 additions & 6 deletions rpi/src/bin/baremetal/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use magenboy_rpi::{drivers::*, peripherals::{PERIPHERALS, GpioPull, ResetMode, P

#[panic_handler]
fn panic(info:&PanicInfo)->!{
log::error!("An error has occoured!: \r\n{}", info);
log::error!("An error has occurred!: \r\n{}", info);

unsafe{boot::hang_led()};
}
Expand All @@ -21,7 +21,7 @@ const MAX_ROM_SIZE:usize = 0x80_0000; // 8 MiB, Max size of MBC5 rom
const MAX_RAM_SIZE:usize = 0x2_0000; // 128 KiB

// Allocating as static buffer (on the .bss) because it is a very large buffer and
// I dont want to cause problems in stack making it overflow and shit (I can increase it when needed but I afraid Id forget)
// I don't want to cause problems in stack making it overflow and shit (I can increase it when needed but I afraid Id forget)
static mut ROM_BUFFER:[u8; MAX_ROM_SIZE] = [0;MAX_ROM_SIZE];
static mut RAM_BUFFER:[u8; MAX_RAM_SIZE] = [0;MAX_RAM_SIZE];

Expand All @@ -42,7 +42,7 @@ pub extern "C" fn main()->!{
let mut pause_menu_gfx = gfx.clone();
let mut joypad_provider = GpioJoypadProvider::new(button_to_bcm_pin);
let mut pause_menu_joypad_provider = joypad_provider.clone();
log::info!("Initialize all drivers succesfully");
log::info!("Initialize all drivers successfully");

let menu_renderer = joypad_gfx_menu::GfxDeviceMenuRenderer::new(&mut gfx);

Expand Down Expand Up @@ -71,7 +71,7 @@ pub extern "C" fn main()->!{
match pause_menu.get_menu_selection(&mut pause_menu_joypad_provider){
EmulatorMenuOption::Resume => {},
EmulatorMenuOption::Restart => {
log::info!("Reseting system");
log::info!("Resetting system");
reset_system(mbc, fs, power_manager, ResetMode::Partition0, selected_rom);
}
EmulatorMenuOption::Shutdown => {
Expand All @@ -88,7 +88,7 @@ fn reset_system<'a>(mbc: &'a dyn Mbc, mut fs: Fat32Fs, mut power_manager: Power,
let filename = get_save_filename(selected_rom);
fs.write_file(filename.as_str(), mbc.get_ram());

// delaying the reset operation so other low level tasks will have enough time to finish (like uart transmision)
// delaying the reset operation so other low level tasks will have enough time to finish (like uart transmission)
delay::wait_ms(100);
power_manager.reset(mode);
}
Expand Down Expand Up @@ -120,7 +120,7 @@ fn read_menu_options(fs: &mut Fat32Fs, menu_options: &mut [MenuOption<FileEntry,
log::debug!("Detected ROM: {}", entry.get_name());
}
}
// The fact that its not completely full indicatets that there are no more unread entries left
// The fact that its not completely full indicates that there are no more unread entries left
if dir_entries.remaining_capacity() != 0{
break;
}
Expand Down
67 changes: 43 additions & 24 deletions rpi/src/drivers/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::as_mut_buffer;
#[repr(C, packed)]
struct PartitionEntry{
status:u8,
frist_sector_chs_address:[u8;3],
first_sector_chs_address:[u8;3],
partition_type:u8,
last_sector_chs_address:[u8;3],
first_sector_index:u32,
Expand All @@ -13,7 +13,7 @@ struct PartitionEntry{

impl Default for PartitionEntry{
fn default() -> Self {
Self { status: Default::default(), frist_sector_chs_address: Default::default(), partition_type: Default::default(), last_sector_chs_address: Default::default(), first_sector_index: Default::default(), sectors_count: Default::default() }
Self { status: Default::default(), first_sector_chs_address: Default::default(), partition_type: Default::default(), last_sector_chs_address: Default::default(), first_sector_index: Default::default(), sectors_count: Default::default() }
}
}

Expand All @@ -37,6 +37,8 @@ pub struct Disk{
}

impl Disk{
const BLOCK_SIZE:u32 = Emmc::get_block_size();

pub fn new()->Self{
let mut emmc = unsafe{PERIPHERALS.take_emmc()};
emmc.init();
Expand All @@ -54,41 +56,58 @@ impl Disk{
Self { emmc, mbr }
}

/// Returns the number of blocks the read operation fetched
/// The user knows how much of the buffer is filled
pub fn read(&mut self, block_index:u32, buffer:&mut [u8]) -> u32 {
let block_size = Self::get_block_size();
if buffer.len() % block_size as usize != 0{
// handle if the buffer is not alligened for block size
pub fn read(&mut self, block_index:u32, buffer:&mut [u8]){
let buffer_len_reminder = buffer.len() % Self::BLOCK_SIZE as usize;
let max_aligned_buffer_len = buffer.len() - buffer_len_reminder;
let aligned_buffer = &mut buffer[..max_aligned_buffer_len];

self.emmc.seek((block_index * Self::BLOCK_SIZE) as u64);
// Verify the buffer is larger than a single block
if aligned_buffer.len() != 0{
self.emmc_read(aligned_buffer);
// early return if the buffer is aligned
if buffer_len_reminder == 0 {return};
}
self.emmc.seek((block_index * block_size) as u64);
// let end_index = core::cmp::min(buffer.len(), )
// handle the case buffer length is not aligned for block size
let mut temp_buffer:[u8;Self::BLOCK_SIZE as usize] = [0;Self::BLOCK_SIZE as usize];
self.emmc.seek(((block_index + (max_aligned_buffer_len as u32 / Self::BLOCK_SIZE)) * Self::BLOCK_SIZE) as u64);
self.emmc_read(&mut temp_buffer);
buffer[max_aligned_buffer_len..].copy_from_slice(&mut temp_buffer[..buffer_len_reminder]);
}

fn emmc_read(&mut self, buffer: &mut [u8]) {
if !self.emmc.read(buffer){
core::panic!("Error while reading object of size: {}", buffer.len());
}
return buffer.len() as u32 / Self::get_block_size();
}

/// Returns the number of blocks the write operation modified
pub fn write(&mut self, block_index:u32, buffer:&[u8])->u32{
self.prepare_for_disk_operation(block_index, buffer);
pub fn write(&mut self, block_index:u32, buffer:&[u8]){
let buffer_len_reminder = buffer.len() % Self::BLOCK_SIZE as usize;
let max_aligned_buffer_len = buffer.len() - buffer_len_reminder;
let aligned_buffer = &buffer[..max_aligned_buffer_len];

self.emmc.seek((block_index * Self::BLOCK_SIZE) as u64);
if aligned_buffer.len() != 0{
self.emmc_write(aligned_buffer);
// early return since the buffer is aligned
if buffer_len_reminder == 0 {return};
}
// handle the case buffer length is not aligned for block size
let mut temp_buffer:[u8;Self::BLOCK_SIZE as usize] = [0;Self::BLOCK_SIZE as usize];
temp_buffer[max_aligned_buffer_len..].copy_from_slice(&buffer[..buffer_len_reminder]);
self.emmc.seek(((block_index + (max_aligned_buffer_len as u32 / Self::BLOCK_SIZE)) * Self::BLOCK_SIZE) as u64);
self.emmc_write(&temp_buffer);
}

fn emmc_write(&mut self, buffer: &[u8]) {
if !self.emmc.write(buffer){
core::panic!("Error while writing object of size: {}", buffer.len());
}
return buffer.len() as u32 / Self::get_block_size();
}

pub fn get_partition_first_sector_index(&self, partition_index:u8)->u32{
self.mbr.partitions[partition_index as usize].first_sector_index
}

pub const fn get_block_size()->u32{Emmc::get_block_size()}

fn prepare_for_disk_operation(&mut self, block_index:u32, buffer:&[u8]){
let block_size = Self::get_block_size();
if buffer.len() % block_size as usize != 0{
core::panic!("buffer size must be a division of block size: {}, actual buffer_size: {}", block_size, buffer.len());
}
self.emmc.seek((block_index * block_size) as u64);
}
pub const fn get_block_size()->u32{Self::BLOCK_SIZE}
}
Loading

0 comments on commit d570013

Please sign in to comment.