| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- use crate::{context::RawTaskContext, fault::Fault};
- use core::marker::PhantomData;
- use eonix_mm::address::VAddr;
- /// A raw trap context.
- ///
- /// This should be implemented by the architecture-specific trap context
- /// and will be used in the HAL crates.
- #[doc(notable_trait)]
- pub trait RawTrapContext: Copy {
- type FIrq: FnOnce(fn(irqno: usize));
- type FTimer: FnOnce(fn());
- fn new() -> Self;
- fn trap_type(&self) -> TrapType<Self::FIrq, Self::FTimer>;
- fn get_program_counter(&self) -> usize;
- fn get_stack_pointer(&self) -> usize;
- fn set_program_counter(&mut self, pc: usize);
- fn set_stack_pointer(&mut self, sp: usize);
- fn is_interrupt_enabled(&self) -> bool;
- fn set_interrupt_enabled(&mut self, enabled: bool);
- fn is_user_mode(&self) -> bool;
- fn set_user_mode(&mut self, user: bool);
- fn set_user_return_value(&mut self, retval: usize);
- fn set_user_call_frame<E>(
- &mut self,
- pc: usize,
- sp: Option<usize>,
- ra: Option<usize>,
- args: &[usize],
- write_memory: impl Fn(VAddr, &[u8]) -> Result<(), E>,
- ) -> Result<(), E>;
- }
- #[doc(notable_trait)]
- pub trait TrapReturn {
- type TaskContext: RawTaskContext;
- /// Return to the context before the trap occurred.
- ///
- /// # Safety
- /// This function is unsafe because the caller MUST ensure that the
- /// context before the trap is valid, that is, that the stack pointer
- /// points to a valid stack frame and the program counter points to some
- /// valid instruction.
- unsafe fn trap_return(&mut self);
- }
- pub trait IrqState {
- /// Restore the IRQ state.
- fn restore(self);
- }
- /// The reason that caused the trap.
- pub enum TrapType<FIrq, FTimer>
- where
- FIrq: FnOnce(fn(irqno: usize)),
- FTimer: FnOnce(fn()),
- {
- Syscall { no: usize, args: [usize; 6] },
- Fault(Fault),
- Irq { callback: FIrq },
- Timer { callback: FTimer },
- }
- /// A marker type that indicates that the type is a raw trap context.
- ///
- /// # Usage
- ///
- /// Check whether a type implements `RawTrapContext` using a `PhantomData` field.
- ///
- /// The following code should fail to compile:
- ///
- /// ```compile_fail
- /// # use eonix_hal_traits::trap::IsRawTrapContext;
- /// struct NonRawTrapContext; // Does not implement `RawTrapContext`!
- ///
- /// // Compile-time error: `NonRawTrapContext` does not implement `RawTrapContext`.
- /// struct UserStruct(NonRawTrapContext, IsRawTrapContext<NonRawTrapContext>);
- /// ```
- ///
- /// While the following code should compile:
- ///
- /// ```no_run
- /// # use eonix_hal_traits::trap::IsRawTrapContext;
- /// struct RawTrapContextType;
- ///
- /// impl RawTrapContext for RawTrapContextType {
- /// // ...
- /// # fn new() -> Self { todo!() }
- /// # fn trap_type() -> TrapType { todo!() }
- /// # fn get_program_counter(&self) -> usize { todo!() }
- /// # fn get_stack_pointer(&self) -> usize { todo!() }
- /// # fn set_program_counter(&mut self, _: usize) { todo!() }
- /// # fn set_stack_pointer(&mut self, _: usize) { todo!() }
- /// # fn is_interrupt_enabled(&self) -> bool { todo!() }
- /// # fn set_interrupt_enabled(&mut self, _: bool) { todo!() }
- /// # fn is_user_mode(&self) -> bool { todo!() }
- /// # fn set_user_mode(&mut self, _: bool) { todo!() }
- /// # fn set_user_return_value(&mut self, _: usize) { todo!() }
- /// }
- ///
- /// struct UserStruct(RawTrapContextType, IsRawTrapContext<RawTrapContextType>);
- /// ```
- pub struct IsRawTrapContext<T>(PhantomData<T>)
- where
- T: RawTrapContext;
|