cpu.rs 1.0 KB

1234567891011121314151617181920212223242526272829303132
  1. use core::{pin::Pin, ptr::NonNull};
  2. use arch::CPUStatus;
  3. use super::mem::{paging::Page, phys::PhysPtr as _};
  4. #[arch::define_percpu]
  5. static CPU_STATUS: Option<CPUStatus> = None;
  6. /// # Safety
  7. /// This function is unsafe because it needs preemption to be disabled.
  8. pub unsafe fn current_cpu() -> Pin<&'static mut CPUStatus> {
  9. // SAFETY: `CPU_STATUS` is global static and initialized only once.
  10. unsafe { Pin::new_unchecked(CPU_STATUS.as_mut().as_mut().unwrap()) }
  11. }
  12. pub unsafe fn init_thiscpu() {
  13. let status = arch::CPUStatus::new_thiscpu(|layout| {
  14. // TODO: Use page size defined in `arch`.
  15. let page_count = (layout.size() + 0x1000 - 1) / 0x1000;
  16. let page = Page::early_alloc_ceil(page_count);
  17. let pointer = page.as_cached().as_ptr();
  18. core::mem::forget(page);
  19. NonNull::new(pointer).expect("Allocated page pfn should be non-null")
  20. });
  21. CPU_STATUS.set(Some(status));
  22. // SAFETY: `CPU_STATUS` is global static and initialized only once.
  23. current_cpu().init();
  24. }