use std::fmt::Display;
use super::formatters::BinaryBytesOne;
pub mod ext_mem_prop_tags {
pub const START_ADDRESS: u32 = 0x00000001;
pub const SIZE_IN_KBYTES: u32 = 0x00000002;
pub const PAGE_SIZE: u32 = 0x00000004;
pub const SECTOR_SIZE: u32 = 0x00000008;
pub const BLOCK_SIZE: u32 = 0x00000010;
}
pub mod mem_id {
pub const INTERNAL_MEMORY: u32 = 0;
pub const QUAD_SPI0: u32 = 1;
pub const IFR: u32 = 4;
pub const FUSE: u32 = 4;
pub const SEMC_NOR: u32 = 8;
pub const FLEX_SPI_NOR: u32 = 9;
pub const SPIFI_NOR: u32 = 10;
pub const FLASH_EXEC_ONLY: u32 = 16;
pub const SEMC_NAND: u32 = 256;
pub const SPI_NAND: u32 = 257;
pub const SPI_NOR_EEPROM: u32 = 272;
pub const I2C_NOR_EEPROM: u32 = 273;
pub const SD_CARD: u32 = 288;
pub const MMC_CARD: u32 = 289;
}
#[derive(Clone, Debug)]
pub struct ReservedRegions {
regions: Box<[(u32, u32)]>,
}
impl Display for ReservedRegions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for (index, (start, end)) in self.regions.iter().enumerate() {
writeln!(
f,
" Region {index}: {start:#010X} - {end:#010X}; Total Size: {}",
BinaryBytesOne(end - start + 1)
)?;
}
Ok(())
}
}
impl ReservedRegions {
#[must_use]
pub fn parse(data: &[u32]) -> Self {
assert!(data.len() % 2 == 0, "reserved regions value is not odd");
let regions = data.chunks(2).map(|region| (region[0], region[1])).collect();
ReservedRegions { regions }
}
}
#[derive(Clone, Copy, Debug)]
pub struct ExternalMemoryAttributes {
start_address: Option<u32>,
total_size: Option<u32>,
page_size: Option<u32>,
sector_size: Option<u32>,
block_size: Option<u32>,
}
impl ExternalMemoryAttributes {
#[must_use]
pub fn parse(data: &[u32]) -> Self {
let value = data[0];
let start_address = if value & ext_mem_prop_tags::START_ADDRESS != 0 {
Some(data[1])
} else {
None
};
let total_size = if value & ext_mem_prop_tags::SIZE_IN_KBYTES != 0 {
Some(data[2])
} else {
None
};
let page_size = if value & ext_mem_prop_tags::PAGE_SIZE != 0 {
Some(data[3])
} else {
None
};
let sector_size = if value & ext_mem_prop_tags::SECTOR_SIZE != 0 {
Some(data[4])
} else {
None
};
let block_size = if value & ext_mem_prop_tags::BLOCK_SIZE != 0 {
Some(data[5])
} else {
None
};
ExternalMemoryAttributes {
start_address,
total_size,
page_size,
sector_size,
block_size,
}
}
}
impl Display for ExternalMemoryAttributes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(start_address) = self.start_address {
write!(f, "Start Address: {start_address:#010X}")?;
}
if let Some(total_size) = self.total_size {
write!(f, "Total Size: {}", BinaryBytesOne(u64::from(total_size) * 1024))?;
}
if let Some(page_size) = self.page_size {
write!(f, "Page Size: {}", BinaryBytesOne(page_size))?;
}
if let Some(sector_size) = self.sector_size {
write!(f, "Sector Size: {}", BinaryBytesOne(sector_size))?;
}
if let Some(block_size) = self.block_size {
write!(f, "Block Size: {}", BinaryBytesOne(block_size))?;
}
Ok(())
}
}