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

29
Cargo.lock generated
View File

@@ -30,6 +30,7 @@ version = "0.1.0"
dependencies = [
"embedded-graphics",
"shared",
"strum",
]
[[package]]
@@ -1222,6 +1223,12 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.2"
@@ -1333,6 +1340,7 @@ dependencies = [
"spin",
"st7365p-lcd",
"static_cell",
"strum",
"talc",
"trouble-host",
]
@@ -2135,6 +2143,27 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]]
name = "syn"
version = "1.0.109"

View File

@@ -5,4 +5,5 @@ edition = "2024"
[dependencies]
embedded-graphics = "0.8.1"
strum = { version = "0.27.2", default-features = false, features = ["derive"] }
shared = { path = "../shared" }

View File

@@ -9,6 +9,7 @@ use embedded_graphics::{
pixelcolor::{Rgb565, RgbColor},
};
pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers};
use strum::EnumIter;
pub type EntryFn = fn();
@@ -17,7 +18,7 @@ pub type EntryFn = fn();
pub static mut CALL_ABI_TABLE: [usize; CallAbiTable::COUNT] = [0; CallAbiTable::COUNT];
#[repr(usize)]
#[derive(Clone, Copy)]
#[derive(Clone, Copy, EnumIter)]
pub enum CallAbiTable {
Print = 0,
Sleep = 1,

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(());