sparreal_kernel/globals/
mod.rs

1#![allow(unused)]
2
3use core::{
4    cell::UnsafeCell,
5    ops::Range,
6    sync::atomic::{AtomicBool, Ordering},
7};
8
9use alloc::collections::btree_map::BTreeMap;
10use log::debug;
11
12pub use crate::platform::PlatformInfoKind;
13use crate::{
14    mem::{self, PhysAddr},
15    platform::{self, CPUHardId, CPUId, cpu_list, fdt::Fdt},
16};
17
18mod once;
19mod percpu;
20
21pub(crate) use percpu::*;
22
23pub struct GlobalVal {
24    pub platform_info: PlatformInfoKind,
25    pub main_memory: Range<PhysAddr>,
26    percpu: BTreeMap<CPUId, percpu::PerCPU>,
27}
28
29struct LazyGlobal {
30    g_ok: AtomicBool,
31    g: UnsafeCell<Option<GlobalVal>>,
32}
33
34unsafe impl Sync for LazyGlobal {}
35
36static GLOBAL: LazyGlobal = LazyGlobal::new();
37
38pub fn global_val() -> &'static GlobalVal {
39    global_val_meybeuninit().expect("GlobalVal is not init!")
40}
41
42pub fn global_val_meybeuninit() -> Option<&'static GlobalVal> {
43    if !GLOBAL.g_ok.load(Ordering::SeqCst) {
44        return None;
45    }
46    Some(unsafe { (*GLOBAL.g.get()).as_ref().unwrap() })
47}
48
49impl LazyGlobal {
50    const fn new() -> Self {
51        Self {
52            g_ok: AtomicBool::new(false),
53            g: UnsafeCell::new(None),
54        }
55    }
56}
57
58/// 修改全局变量
59///
60/// # Safty
61/// 只能在其他CPU启动前调用
62pub(crate) unsafe fn edit(f: impl FnOnce(&mut GlobalVal)) {
63    unsafe {
64        let global = (*GLOBAL.g.get()).as_mut().unwrap();
65        f(global);
66    }
67}
68
69unsafe fn get_mut() -> &'static mut GlobalVal {
70    unsafe { (*GLOBAL.g.get()).as_mut().unwrap() }
71}
72
73/// # Safty
74/// 只能在其他CPU启动前调用
75pub(crate) unsafe fn setup(platform_info: PlatformInfoKind) -> Result<(), &'static str> {
76    let main = crate::mem::find_main_memory().ok_or("can not find main memory")?;
77    let start = main.range.start.align_up(platform::page_size());
78    let range = start..main.range.end;
79    let g = GlobalVal {
80        platform_info,
81        main_memory: range,
82        percpu: Default::default(),
83    };
84
85    unsafe {
86        GLOBAL.g.get().write(Some(g));
87        GLOBAL.g_ok.store(true, Ordering::SeqCst);
88    }
89    Ok(())
90}