context.rs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. use core::{cell::UnsafeCell, mem::transmute};
  2. use eonix_hal::context::TaskContext;
  3. use eonix_hal::traits::context::RawTaskContext;
  4. #[derive(Debug)]
  5. pub struct ExecutionContext(UnsafeCell<TaskContext>);
  6. unsafe impl Sync for ExecutionContext {}
  7. impl ExecutionContext {
  8. pub const fn new() -> Self {
  9. Self(UnsafeCell::new(TaskContext::new()))
  10. }
  11. pub fn set_ip(&mut self, ip: usize) {
  12. let Self(context) = self;
  13. context.get_mut().set_program_counter(ip);
  14. }
  15. pub fn set_sp(&mut self, sp: usize) {
  16. let Self(context) = self;
  17. context.get_mut().set_stack_pointer(sp);
  18. }
  19. pub fn set_interrupt(&mut self, is_enabled: bool) {
  20. let Self(context) = self;
  21. context.get_mut().set_interrupt_enabled(is_enabled);
  22. }
  23. pub fn call1<T>(&mut self, func: unsafe extern "C" fn(T) -> !, arg: usize) {
  24. let Self(context) = self;
  25. context
  26. .get_mut()
  27. .call(unsafe { transmute(func as *mut ()) }, arg);
  28. }
  29. pub fn switch_to(&self, to: &Self) {
  30. let Self(from_ctx) = self;
  31. let Self(to_ctx) = to;
  32. unsafe {
  33. TaskContext::switch(&mut *from_ctx.get(), &mut *to_ctx.get());
  34. }
  35. }
  36. pub fn switch_noreturn(&self) -> ! {
  37. let Self(to_ctx) = self;
  38. unsafe {
  39. TaskContext::switch_to_noreturn(&mut *to_ctx.get());
  40. }
  41. }
  42. }