kernel/abi/
mod.rs

1//! ABI module.
2//! 
3//! This module provides the interface for ABI (Application Binary Interface) modules
4//! in the Scarlet kernel. ABI modules are responsible for handling system calls
5//! and providing the necessary functionality for different application binary
6//! interfaces.
7//! 
8
9use crate::{arch::Trapframe, task::mytask};
10use alloc::{boxed::Box, string::{String, ToString}};
11use hashbrown::HashMap;
12use spin::Mutex;
13
14pub mod scarlet;
15
16pub const MAX_ABI_LENGTH: usize = 64;
17
18/// ABI module trait.
19/// 
20/// This trait defines the interface for ABI modules in the Scarlet kernel.
21/// ABI modules are responsible for handling system calls and providing
22/// the necessary functionality for different application binary interfaces.
23/// 
24pub trait AbiModule: 'static {
25    fn name() -> &'static str
26    where
27        Self: Sized;
28
29    fn handle_syscall(&self, trapframe: &mut Trapframe) -> Result<usize, &'static str>;
30}
31
32
33/// ABI registry.
34/// 
35/// This struct is responsible for managing the registration and instantiation
36/// of ABI modules in the Scarlet kernel.
37/// 
38pub struct AbiRegistry {
39    factories: HashMap<String, fn() -> Box<dyn AbiModule>>,
40}
41
42impl AbiRegistry {
43    fn new() -> Self {
44        Self {
45            factories: HashMap::new(),
46        }
47    }
48
49    #[allow(static_mut_refs)]
50    pub fn global() -> &'static Mutex<AbiRegistry> {
51        // Lazy initialization using spin lock
52        static mut INSTANCE: Option<Mutex<AbiRegistry>> = None;
53        static INIT: spin::Once = spin::Once::new();
54        
55        unsafe {
56            INIT.call_once(|| {
57                INSTANCE = Some(Mutex::new(AbiRegistry::new()));
58            });
59            
60            // Safe to access after INIT.call_once is called
61            INSTANCE.as_ref().unwrap()
62        }
63    }
64
65    pub fn register<T>()
66    where
67        T: AbiModule + Default + 'static,
68    {
69        crate::early_println!("Registering ABI module: {}", T::name());
70        let mut registry = Self::global().lock();
71        registry
72            .factories
73            .insert(T::name().to_string(), || Box::new(T::default()));
74    }
75
76    pub fn instantiate(name: &str) -> Option<Box<dyn AbiModule>> {
77        let registry = Self::global().lock();
78        registry.factories.get(name).map(|f| f())
79    }
80}
81
82#[macro_export]
83macro_rules! register_abi {
84    ($ty:ty) => {
85        $crate::abi::AbiRegistry::register::<$ty>();
86    };
87}
88
89pub fn syscall_dispatcher(trapframe: &mut Trapframe) -> Result<usize, &'static str> {
90    let task = mytask().unwrap();
91    let abi = task.abi.as_deref_mut().expect("ABI not set");
92    abi.handle_syscall(trapframe)
93}