pub type RomFnTableCode = [u8; 2];
type RomTableLookupFn = unsafe extern "C" fn(code: u32, mask: u32) -> usize;
#[cfg(all(target_arch = "arm", target_os = "none"))]
const ROM_TABLE_LOOKUP_A2: *const u16 = 0x0000_0016 as _;
#[cfg(all(target_arch = "arm", target_os = "none"))]
const ROM_TABLE_LOOKUP_A1: *const u32 = 0x0000_0018 as _;
#[cfg(all(target_arch = "arm", target_os = "none"))]
const ROM_DATA_LOOKUP_A2: *const u16 = ROM_TABLE_LOOKUP_A2;
#[cfg(all(target_arch = "arm", target_os = "none"))]
const ROM_DATA_LOOKUP_A1: *const u32 = ROM_TABLE_LOOKUP_A1;
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
const ROM_TABLE_LOOKUP_A2: *const u16 = 0x0000_7DFA as _;
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
const ROM_TABLE_LOOKUP_A1: *const u32 = 0x0000_7DF8 as _;
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
const ROM_DATA_LOOKUP_A2: *const u16 = 0x0000_7DF8 as _;
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
const ROM_DATA_LOOKUP_A1: *const u32 = 0x0000_7DF4 as _;
const VERSION_NUMBER: *const u8 = 0x0000_0013 as _;
#[allow(unused)]
mod rt_flags {
pub const FUNC_RISCV: u32 = 0x0001;
pub const FUNC_RISCV_FAR: u32 = 0x0003;
pub const FUNC_ARM_SEC: u32 = 0x0004;
pub const FUNC_ARM_NONSEC: u32 = 0x0010;
pub const DATA: u32 = 0x0040;
#[cfg(all(target_arch = "arm", target_os = "none"))]
pub const FUNC_ARM_SEC_RISCV: u32 = FUNC_ARM_SEC;
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub const FUNC_ARM_SEC_RISCV: u32 = FUNC_RISCV;
}
pub fn rom_table_lookup(tag: RomFnTableCode, mask: u32) -> usize {
let tag = u16::from_le_bytes(tag) as u32;
unsafe {
let lookup_func = if rom_version_number() == 1 {
ROM_TABLE_LOOKUP_A1.read() as usize
} else {
ROM_TABLE_LOOKUP_A2.read() as usize
};
let lookup_func: RomTableLookupFn = core::mem::transmute(lookup_func);
lookup_func(tag, mask)
}
}
pub fn rom_data_lookup(tag: RomFnTableCode, mask: u32) -> usize {
let tag = u16::from_le_bytes(tag) as u32;
unsafe {
let lookup_func = if rom_version_number() == 1 {
ROM_DATA_LOOKUP_A1.read() as usize
} else {
ROM_DATA_LOOKUP_A2.read() as usize
};
let lookup_func: RomTableLookupFn = core::mem::transmute(lookup_func);
lookup_func(tag, mask)
}
}
#[repr(i32)]
#[derive(Debug)]
pub enum BootRomApiErrorCode {
NotPermitted = -4,
InvalidArg = -5,
InvalidAddress = -10,
BadAlignment = -11,
InvalidState = -12,
BufferTooSmall = -13,
PreconditionNotMet = -14,
ModifiedData = -15,
InvalidData = -16,
NotFound = -17,
UnsupportedModification = -18,
LockRequired = -19,
Unknown = -1,
}
impl From<i32> for BootRomApiErrorCode {
fn from(value: i32) -> Self {
match value {
-4 => Self::NotPermitted,
-5 => Self::InvalidArg,
-10 => Self::InvalidAddress,
-11 => Self::BadAlignment,
-12 => Self::InvalidState,
-13 => Self::BufferTooSmall,
-14 => Self::PreconditionNotMet,
-15 => Self::ModifiedData,
-16 => Self::InvalidData,
-17 => Self::NotFound,
-18 => Self::UnsupportedModification,
-19 => Self::LockRequired,
_ => Self::Unknown,
}
}
}
#[allow(unused)]
pub mod sys_info_api {
use super::BootRomApiErrorCode;
#[repr(u32)]
pub enum GetSysInfoFlag {
ChipInfo = 0x0001,
Critical = 0x0002,
CpuInfo = 0x0004,
FlashDevInfo = 0x0008,
BootRandom = 0x0010,
BootInfo = 0x0040,
}
impl GetSysInfoFlag {
const fn buffer_length(&self) -> usize {
match self {
GetSysInfoFlag::ChipInfo => 4,
GetSysInfoFlag::Critical
| GetSysInfoFlag::CpuInfo
| GetSysInfoFlag::FlashDevInfo => 2,
GetSysInfoFlag::BootRandom | GetSysInfoFlag::BootInfo => 5,
}
}
}
pub struct ChipInfo {
pub package_sel: u32,
pub device_id: u32,
pub wafer_id: u32,
}
impl From<[u32; 3]> for ChipInfo {
fn from(value: [u32; 3]) -> Self {
ChipInfo {
package_sel: value[0],
device_id: value[1],
wafer_id: value[2],
}
}
}
pub struct OtpCriticalReg(u32);
impl OtpCriticalReg {
pub fn secure_boot_enabled(&self) -> bool {
(self.0 & 0x1) == 1
}
pub fn secure_debug_disabled(&self) -> bool {
(self.0 & 0x2) >> 1 == 1
}
pub fn debug_disabled(&self) -> bool {
(self.0 & 0x4) >> 2 == 1
}
pub fn default_arch_sel(&self) -> bool {
(self.0 & 0x8) >> 3 == 1
}
pub fn glitch_detector_enabled(&self) -> bool {
(self.0 & 0x10) >> 4 == 1
}
pub fn glitch_detector_sens(&self) -> u8 {
((self.0 & 0x60) >> 5) as _
}
pub fn arm_disabled(&self) -> bool {
(self.0 & 0x10000) >> 16 == 1
}
pub fn risc_disabled(&self) -> bool {
(self.0 & 0x20000) >> 17 == 1
}
}
impl From<[u32; 1]> for OtpCriticalReg {
fn from(value: [u32; 1]) -> OtpCriticalReg {
OtpCriticalReg(value[0])
}
}
#[repr(u32)]
pub enum CpuInfo {
Arm,
Risc,
}
impl From<[u32; 1]> for CpuInfo {
fn from(value: [u32; 1]) -> CpuInfo {
if value[0] == 0 {
CpuInfo::Arm
} else {
CpuInfo::Risc
}
}
}
pub struct FlashDevInfo(u32);
#[repr(u32)]
pub enum FlashDevInfoSize {
None,
K8,
K16,
K32,
K64,
K128,
K256,
K512,
M1,
M2,
M4,
M8,
M16,
Unknown,
}
impl From<u32> for FlashDevInfoSize {
fn from(value: u32) -> Self {
if value > 0xc {
return Self::Unknown;
}
unsafe { core::mem::transmute::<u32, FlashDevInfoSize>(value) }
}
}
impl FlashDevInfo {
pub fn cs1_gpio(&self) -> u8 {
(self.0 & 0x1f) as _
}
pub fn d8h_erase_supported(&self) -> bool {
(self.0 & 0x80) != 0
}
pub fn cs0_size(&self) -> FlashDevInfoSize {
FlashDevInfoSize::from((self.0 & 0xf00) >> 8)
}
pub fn cs1_size(&self) -> FlashDevInfoSize {
FlashDevInfoSize::from((self.0 & 0xf000) >> 12)
}
}
impl From<[u32; 1]> for FlashDevInfo {
fn from(value: [u32; 1]) -> FlashDevInfo {
FlashDevInfo(value[0])
}
}
pub struct BootRandom(pub u128);
impl From<[u32; 4]> for BootRandom {
fn from(value: [u32; 4]) -> BootRandom {
let mut result = 0;
for word in value {
result = (result << 32) | u128::from(word);
}
BootRandom(result)
}
}
pub struct BootInfo {
pub diagnostic_partition: PartitionIndex,
pub boot_type: BootType,
pub chained: bool,
pub partition: i8,
pub tbyb_update_info: u8,
pub boot_diagnostic: u32,
pub boot_params: [u32; 2],
}
pub enum PartitionIndex {
Partition(u8),
None,
Slot0,
Slot1,
Image,
Unknown,
}
impl From<i8> for PartitionIndex {
fn from(value: i8) -> Self {
if !(-4..=15).contains(&value) {
return Self::Unknown;
}
match value {
-1 => Self::None,
-2 => Self::Slot0,
-3 => Self::Slot1,
-4 => Self::Image,
_ => Self::Partition(value as u8),
}
}
}
pub enum BootType {
Normal,
BootSel,
RamImage,
FlashUpdate,
PcSp,
Unknown,
}
impl From<u8> for BootType {
fn from(value: u8) -> Self {
match value {
0 => Self::Normal,
2 => Self::BootSel,
3 => Self::RamImage,
4 => Self::FlashUpdate,
8..=15 => Self::PcSp,
_ => Self::Unknown,
}
}
}
#[repr(u16)]
pub enum BootDiagnosticFlags {
RegionSearched = 0x0001,
InvalidBlockLoop = 0x0002,
ValidBlockLoop = 0x0004,
ValidImageDef = 0x0008,
HasPartitionTable = 0x0010,
Considered = 0x0020,
Chosen = 0x0040,
PartitionTableMatchingKeyForVerify = 0x0080,
PartitionTableHashForVerify = 0x0100,
PartitionTableVerifiedOk = 0x0200,
ImageDefMatchingKeyForVerify = 0x0400,
ImageDefHashForVerify = 0x0800,
ImageDefVerifiedOk = 0x1000,
LoadMapEntriesLoaded = 0x2000,
ImageLaunched = 0x4000,
ImageConditionFailure = 0x8000,
}
impl From<[u32; 4]> for BootInfo {
fn from(value: [u32; 4]) -> Self {
let word0 = value[0];
BootInfo {
diagnostic_partition: PartitionIndex::from((word0 & 0xFF) as i8),
boot_type: BootType::from((word0 >> 8) as u8),
chained: (word0 >> 8) & 0x80 > 0,
partition: (word0 >> 16) as _,
tbyb_update_info: (word0 >> 24) as _,
boot_diagnostic: value[1],
boot_params: [value[2], value[3]],
}
}
}
impl BootInfo {
fn check_flag(diagnostics: u16, flag: BootDiagnosticFlags) -> bool {
(diagnostics & flag as u16) != 0
}
pub fn check_section_a_flag(&self, flag: BootDiagnosticFlags) -> bool {
Self::check_flag(self.boot_diagnostic as u16, flag)
}
pub fn check_section_b_flag(&self, flag: BootDiagnosticFlags) -> bool {
Self::check_flag((self.boot_diagnostic >> 8) as u16, flag)
}
}
#[macro_export]
macro_rules! declare_get_sys_info_function {
($(#[$meta:meta])* $function_name:ident, $ok_ret_type:ty, $flag:expr) => {
$(#[$meta])*
pub fn $function_name() -> Result<Option<$ok_ret_type>, BootRomApiErrorCode> {
const FLAG: GetSysInfoFlag = $flag;
const BUFFER_LEN: usize = FLAG.buffer_length();
let mut buffer = [0u32; FLAG.buffer_length()];
let result =
unsafe { super::get_sys_info(buffer.as_mut_ptr(), buffer.len(), FLAG as u32) };
if result < 0 {
return Err(BootRomApiErrorCode::from(result));
} else if buffer[0] == 0 {
return Ok(None);
}
Ok(Some(<$ok_ret_type>::from(
TryInto::<[u32; BUFFER_LEN - 1]>::try_into(&buffer[1..]).unwrap(),
)))
}
};
}
#[macro_export]
#[cfg(all(target_arch = "arm", target_os = "none"))]
macro_rules! declare_get_sys_info_ns_function {
($(#[$meta:meta])* $function_name:ident, $ok_ret_type:ty, $flag:expr) => {
$(#[$meta])*
pub fn $function_name() -> Result<Option<$ok_ret_type>, BootRomApiErrorCode> {
const FLAG: GetSysInfoFlag = $flag;
const BUFFER_LEN: usize = FLAG.buffer_length();
let mut buffer = [0u32; FLAG.buffer_length()];
let result =
unsafe { super::get_sys_info_ns(buffer.as_mut_ptr(), buffer.len(), FLAG as u32) };
if result < 0 {
return Err(BootRomApiErrorCode::from(result));
} else if buffer[0] == 0 {
return Ok(None);
}
Ok(Some(<$ok_ret_type>::from(
TryInto::<[u32; BUFFER_LEN - 1]>::try_into(&buffer[1..]).unwrap(),
)))
}
};
}
declare_get_sys_info_function!(
chip_info, ChipInfo, GetSysInfoFlag::ChipInfo
);
declare_get_sys_info_function!(
otp_critical_register,
OtpCriticalReg,
GetSysInfoFlag::Critical
);
declare_get_sys_info_function!(
cpu_info, CpuInfo, GetSysInfoFlag::CpuInfo
);
declare_get_sys_info_function!(
flash_dev_info, FlashDevInfo, GetSysInfoFlag::FlashDevInfo
);
declare_get_sys_info_function!(
boot_random, BootRandom, GetSysInfoFlag::BootRandom
);
declare_get_sys_info_function!(
boot_info, BootInfo, GetSysInfoFlag::BootInfo
);
#[cfg(all(target_arch = "arm", target_os = "none"))]
declare_get_sys_info_ns_function!(
chip_info_ns, ChipInfo, GetSysInfoFlag::ChipInfo
);
#[cfg(all(target_arch = "arm", target_os = "none"))]
declare_get_sys_info_ns_function!(
otp_critical_register_ns,
OtpCriticalReg,
GetSysInfoFlag::Critical
);
#[cfg(all(target_arch = "arm", target_os = "none"))]
declare_get_sys_info_ns_function!(
cpu_info_ns, CpuInfo, GetSysInfoFlag::CpuInfo
);
#[cfg(all(target_arch = "arm", target_os = "none"))]
declare_get_sys_info_ns_function!(
flash_dev_info_ns, FlashDevInfo, GetSysInfoFlag::FlashDevInfo
);
#[cfg(all(target_arch = "arm", target_os = "none"))]
declare_get_sys_info_ns_function!(
boot_random_ns, BootRandom, GetSysInfoFlag::BootRandom
);
#[cfg(all(target_arch = "arm", target_os = "none"))]
declare_get_sys_info_ns_function!(
boot_info_ns, BootInfo, GetSysInfoFlag::BootInfo
);
}
macro_rules! declare_rom_function {
(
$(#[$outer:meta])*
fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty
$lookup:block
) => {
#[doc = r"Additional access for the `"]
#[doc = stringify!($name)]
#[doc = r"` ROM function."]
pub mod $name {
#[cfg(not(feature = "rom-func-cache"))]
pub fn ptr() -> extern "C" fn( $($argname: $ty),* ) -> $ret {
let p: usize = $lookup;
unsafe {
let func : extern "C" fn( $($argname: $ty),* ) -> $ret = core::mem::transmute(p);
func
}
}
#[cfg(feature = "rom-func-cache")]
pub fn ptr() -> extern "C" fn( $($argname: $ty),* ) -> $ret {
use core::sync::atomic::{AtomicU16, Ordering};
static CACHED_PTR: AtomicU16 = AtomicU16::new(0);
let p: usize = match CACHED_PTR.load(Ordering::Relaxed) {
0 => {
let raw: usize = $lookup;
CACHED_PTR.store(raw as u16, Ordering::Relaxed);
raw
},
val => val as usize,
};
unsafe {
let func : extern "C" fn( $($argname: $ty),* ) -> $ret = core::mem::transmute(p);
func
}
}
}
$(#[$outer])*
pub extern "C" fn $name( $($argname: $ty),* ) -> $ret {
$name::ptr()($($argname),*)
}
};
(
$(#[$outer:meta])*
unsafe fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty
$lookup:block
) => {
#[doc = r"Additional access for the `"]
#[doc = stringify!($name)]
#[doc = r"` ROM function."]
pub mod $name {
#[cfg(not(feature = "rom-func-cache"))]
pub fn ptr() -> unsafe extern "C" fn( $($argname: $ty),* ) -> $ret {
let p: usize = $lookup;
unsafe {
let func : unsafe extern "C" fn( $($argname: $ty),* ) -> $ret = core::mem::transmute(p);
func
}
}
#[cfg(feature = "rom-func-cache")]
pub fn ptr() -> unsafe extern "C" fn( $($argname: $ty),* ) -> $ret {
use core::sync::atomic::{AtomicU16, Ordering};
static CACHED_PTR: AtomicU16 = AtomicU16::new(0);
let p: usize = match CACHED_PTR.load(Ordering::Relaxed) {
0 => {
let raw: usize = $lookup;
CACHED_PTR.store(raw as u16, Ordering::Relaxed);
raw
},
val => val as usize,
};
unsafe {
let func : unsafe extern "C" fn( $($argname: $ty),* ) -> $ret = core::mem::transmute(p);
func
}
}
}
$(#[$outer])*
pub unsafe extern "C" fn $name( $($argname: $ty),* ) -> $ret {
$name::ptr()($($argname),*)
}
};
}
declare_rom_function! {
unsafe fn connect_internal_flash() -> () {
crate::rom_data::rom_table_lookup(*b"IF", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_exit_xip() -> () {
crate::rom_data::rom_table_lookup(*b"EX", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_range_erase(addr: u32, count: usize, block_size: u32, block_cmd: u8) -> () {
crate::rom_data::rom_table_lookup(*b"RE", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_range_program(addr: u32, data: *const u8, count: usize) -> () {
crate::rom_data::rom_table_lookup(*b"RP", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_flush_cache() -> () {
crate::rom_data::rom_table_lookup(*b"FC", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_enter_cmd_xip() -> () {
crate::rom_data::rom_table_lookup(*b"CX", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_select_xip_read_mode(bootrom_xip_mode: u8, clkdiv: u8) -> () {
crate::rom_data::rom_table_lookup(*b"XM", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_reset_address_trans() -> () {
crate::rom_data::rom_table_lookup(*b"RA", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn flash_runtime_to_storage_addr(addr: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"FA", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
unsafe fn flash_runtime_to_storage_addr_ns(addr: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"FA", crate::rom_data::rt_flags::FUNC_ARM_NONSEC)
}
}
declare_rom_function! {
unsafe fn flash_op(flags: u32, addr: u32, size_bytes: u32, buffer: *mut u8) -> i32 {
crate::rom_data::rom_table_lookup(*b"FO", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
unsafe fn flash_op_ns(flags: u32, addr: u32, size_bytes: u32, buffer: *mut u8) -> i32 {
crate::rom_data::rom_table_lookup(*b"FO", crate::rom_data::rt_flags::FUNC_ARM_NONSEC)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
unsafe fn set_ns_api_permission(ns_api_num: u32, allowed: u8) -> i32 {
crate::rom_data::rom_table_lookup(*b"SP", crate::rom_data::rt_flags::FUNC_ARM_SEC)
}
}
declare_rom_function! {
unsafe fn validate_ns_buffer() -> () {
crate::rom_data::rom_table_lookup(*b"VB", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
fn reboot(flags: u32, delay_ms: u32, p0: u32, p1: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"RB", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
fn reboot_ns(flags: u32, delay_ms: u32, p0: u32, p1: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"RB", crate::rom_data::rt_flags::FUNC_ARM_NONSEC)
}
}
declare_rom_function! {
unsafe fn bootrom_state_reset(flags: u32) -> () {
crate::rom_data::rom_table_lookup(*b"SR", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn set_rom_callback(callback_number: i32, callback_fn: *const ()) -> i32 {
crate::rom_data::rom_table_lookup(*b"RC", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn get_sys_info(out_buffer: *mut u32, out_buffer_word_size: usize, flags: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"GS", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
unsafe fn get_sys_info_ns(out_buffer: *mut u32, out_buffer_word_size: usize, flags: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"GS", crate::rom_data::rt_flags::FUNC_ARM_NONSEC)
}
}
declare_rom_function! {
unsafe fn get_partition_table_info(out_buffer: *mut u32, out_buffer_word_size: usize, flags_and_partition: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"GP", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
unsafe fn get_partition_table_info_ns(out_buffer: *mut u32, out_buffer_word_size: usize, flags_and_partition: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"GP", crate::rom_data::rt_flags::FUNC_ARM_NONSEC)
}
}
declare_rom_function! {
unsafe fn load_partition_table(workarea_base: *mut u8, workarea_size: usize, force_reload: bool) -> i32 {
crate::rom_data::rom_table_lookup(*b"LP", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn otp_access(buf: *mut u8, buf_len: usize, row_and_flags: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"OA", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(all(target_arch = "arm", target_os = "none"))]
unsafe fn otp_access_ns(buf: *mut u8, buf_len: usize, row_and_flags: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"OA", crate::rom_data::rt_flags::FUNC_ARM_NONSEC)
}
}
declare_rom_function! {
unsafe fn pick_ab_parition(workarea_base: *mut u8, workarea_size: usize, partition_a_num: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"AB", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn chain_image(workarea_base: *mut u8, workarea_size: usize, region_base: i32, region_size: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"CI", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn explicit_buy(buffer: *mut u8, buffer_size: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"EB", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn get_uf2_target_partition(workarea_base: *mut u8, workarea_size: usize, family_id: u32, partition_out: *mut u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"GU", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
unsafe fn get_b_partition(partition_a: u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"GB", crate::rom_data::rt_flags::FUNC_ARM_SEC_RISCV)
}
}
declare_rom_function! {
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
unsafe fn set_bootrom_stack(base_size: *mut u32) -> i32 {
crate::rom_data::rom_table_lookup(*b"SS", crate::rom_data::rt_flags::FUNC_RISCV)
}
}
pub fn rom_version_number() -> u8 {
unsafe { *VERSION_NUMBER }
}
pub fn git_revision() -> u32 {
let ptr = rom_data_lookup(*b"GR", rt_flags::DATA) as *const u32;
unsafe { ptr.read() }
}
pub fn partition_table_pointer() -> *const u32 {
let ptr = rom_data_lookup(*b"PT", rt_flags::DATA) as *const *const u32;
unsafe { ptr.read() }
}
#[cfg(all(target_arch = "arm", target_os = "none"))]
pub fn is_secure_mode() -> bool {
#[allow(clippy::zero_ptr)]
let rom_base: *mut u32 = 0x0000_0000 as *mut u32;
let tt = cortex_m::asm::tt(rom_base);
(tt & (1 << 22)) != 0
}
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub fn is_secure_mode() -> bool {
false
}