use strum for abicalltable

This commit is contained in:
2025-09-26 11:15:42 -06:00
parent d00e644100
commit 07b4905a06
6 changed files with 47 additions and 22 deletions

View File

@@ -79,6 +79,7 @@ embedded-text = "0.7.2"
embedded-layout = "0.4.2"
kolibri-embedded-gui = "0.1.0"
strum = { version = "0.27.2", default-features = false }
rand = { version = "0.9.0", default-features = false }
once_cell = { version = "1.21.3", default-features = false }
static_cell = "2.1.1"

View File

@@ -1,8 +1,7 @@
use abi_sys::{DrawIterAbi, GetKeyAbi, LockDisplay, PrintAbi, RngRequest, SleepAbi};
use core::{ptr::slice_from_raw_parts, sync::atomic::Ordering};
use core::sync::atomic::Ordering;
use embassy_rp::clocks::{RoscRng, clk_sys_freq};
use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565};
use rand::Rng;
use shared::keyboard::KeyEvent;
use crate::{

View File

@@ -15,6 +15,7 @@ use goblin::{
},
elf32::{section_header::SectionHeader, sym::Sym},
};
use strum::IntoEnumIterator;
const ELF32_HDR_SIZE: usize = 52;
@@ -50,18 +51,7 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Result<EntryFn, &str> {
}
}
// MUST MATCH ABI EXACTLY
let entries: &[(CallAbiTable, usize)] = &[
(CallAbiTable::Print, abi::print as usize),
(CallAbiTable::Sleep, abi::sleep as usize),
(CallAbiTable::LockDisplay, abi::lock_display as usize),
(CallAbiTable::DrawIter, abi::draw_iter as usize),
(CallAbiTable::GetKey, abi::get_key as usize),
(CallAbiTable::GenRand, abi::gen_rand as usize),
];
assert!(entries.len() == CallAbiTable::COUNT);
patch_abi(entries, &elf_header, &mut file).unwrap();
patch_abi(&elf_header, &mut file).unwrap();
// TODO: dynamically search for abi table
@@ -77,11 +67,7 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Result<EntryFn, &str> {
}
}
fn patch_abi(
entries: &[(CallAbiTable, usize)],
elf_header: &Header,
file: &mut File,
) -> Result<(), ()> {
fn patch_abi(elf_header: &Header, file: &mut File) -> Result<(), ()> {
for i in 1..=elf_header.e_shnum {
let sh = read_section(file, &elf_header, i.into());
@@ -117,9 +103,17 @@ fn patch_abi(
if symbol_name == "CALL_ABI_TABLE" {
let table_base = sym.st_value as *mut usize;
for &(abi_idx, func_ptr) in entries {
for (idx, call) in CallAbiTable::iter().enumerate() {
let ptr = match call {
CallAbiTable::Print => abi::print as usize,
CallAbiTable::Sleep => abi::sleep as usize,
CallAbiTable::LockDisplay => abi::lock_display as usize,
CallAbiTable::DrawIter => abi::draw_iter as usize,
CallAbiTable::GetKey => abi::get_key as usize,
CallAbiTable::GenRand => abi::gen_rand as usize,
};
unsafe {
table_base.add(abi_idx as usize).write(func_ptr);
table_base.add(idx as usize).write(ptr);
}
}
return Ok(());