1#![cfg_attr(target_os = "none", no_std)]
2#![cfg(target_os = "none")]
3
4#[cfg(target_arch = "aarch64")]
5#[path = "arch/aarch64/mod.rs"]
6mod arch;
7
8mod fdt;
9mod loader;
10mod staticcell;
11
12use heapless::Vec;
13pub use kdef_pgtable::{KIMAGE_VADDR, KIMAGE_VSIZE, KLINER_OFFSET};
14use pie_boot_if::EarlyBootArgs;
15pub use pie_boot_if::{BootInfo, MemoryRegion, MemoryRegionKind, MemoryRegions};
16#[allow(unused)]
17use pie_boot_macros::start_code;
18pub use pie_boot_macros::{entry, secondary_entry};
19use staticcell::StaticCell;
20
21#[allow(unused)]
22static mut BOOT_ARGS: EarlyBootArgs = EarlyBootArgs::new();
23
24#[unsafe(link_section = ".data")]
25static BOOT_INFO: StaticCell<BootInfo> = StaticCell::new(BootInfo::new());
26#[unsafe(link_section = ".data")]
27static MEMORY_REGIONS: StaticCell<Vec<MemoryRegion, 128>> = StaticCell::new(Vec::new());
28#[unsafe(link_section = ".data")]
29static mut BOOT_PT: usize = 0;
30
31unsafe extern "Rust" {
32 fn __pie_boot_main(args: &BootInfo);
33}
34
35fn virt_entry(args: &BootInfo) {
36 unsafe {
37 MEMORY_REGIONS.as_mut().clear();
38 let _ = MEMORY_REGIONS
39 .as_mut()
40 .extend_from_slice(&args.memory_regions);
41
42 *BOOT_INFO.as_mut() = args.clone();
43
44 if let Some(ptr) = BOOT_INFO.fdt {
45 fdt::setup(ptr);
46 }
47
48 mainmem_start_rsv(args);
49 let regions = core::slice::from_raw_parts_mut(
50 MEMORY_REGIONS.as_mut().as_mut_ptr(),
51 MEMORY_REGIONS.len(),
52 );
53 BOOT_INFO.as_mut().memory_regions = regions.into();
54 BOOT_PT = BOOT_INFO.pg_start as usize;
55
56 __pie_boot_main(&BOOT_INFO);
57 }
58}
59
60pub fn boot_info() -> &'static BootInfo {
61 &BOOT_INFO
62}
63
64pub fn secondary_entry_addr() -> usize {
67 let ptr = arch::_start_secondary as usize;
68 ptr - boot_info().kcode_offset()
69}
70
71fn mainmem_start_rsv(args: &BootInfo) {
72 let lma = args.kimage_start_lma as usize;
73
74 let mainmem = MEMORY_REGIONS.iter().find(|r| {
75 let is_ram = matches!(r.kind, MemoryRegionKind::Ram);
76 let in_range = r.start <= lma && r.end > lma;
77 is_ram && in_range
78 });
79
80 let Some(mainmem) = mainmem else {
81 return;
82 };
83
84 let mut start = mainmem.start;
85 unsafe extern "C" {
86 fn _text();
87 }
88 let mut end = _text as usize - args.kcode_offset();
89
90 let mut indices_to_remove: heapless::Vec<usize, 16> = heapless::Vec::new();
92
93 for (i, r) in MEMORY_REGIONS.iter().enumerate() {
95 if !matches!(r.kind, MemoryRegionKind::Reserved) {
96 continue;
97 }
98
99 if !(end <= r.start || start >= r.end) {
101 if r.start <= start && r.end >= end {
103 return;
104 }
105
106 if r.start >= start && r.end <= end {
108 let _ = indices_to_remove.push(i);
109 continue;
110 }
111
112 if r.start <= start && r.end > start && r.end < end {
114 start = r.end;
115 }
116
117 if r.start > start && r.start < end && r.end >= end {
119 end = r.start;
120 }
121 }
122 }
123
124 for &i in indices_to_remove.iter().rev() {
126 MEMORY_REGIONS.as_mut().swap_remove(i);
127 }
128
129 if start >= end {
131 return;
132 }
133
134 let _ = MEMORY_REGIONS.as_mut().push(MemoryRegion {
136 kind: MemoryRegionKind::Reserved,
137 start,
138 end,
139 });
140}
141
142#[unsafe(no_mangle)]
143unsafe extern "C" fn __pie_boot_default_secondary(_cpu_id: usize) {}