#![cfg_attr(target_os = "none", no_std)]
#![cfg(target_os = "none")]
#[cfg(target_arch = "aarch64")]
#[path = "arch/aarch64/mod.rs"]
mod arch;
mod fdt;
mod loader;
mod staticcell;
use heapless::Vec;
pub use kdef_pgtable::{KIMAGE_VADDR, KIMAGE_VSIZE, KLINER_OFFSET};
use pie_boot_if::EarlyBootArgs;
pub use pie_boot_if::{BootInfo, MemoryRegion, MemoryRegionKind, MemoryRegions};
#[allow(unused)]
use pie_boot_macros::start_code;
pub use pie_boot_macros::{entry, secondary_entry};
use staticcell::StaticCell;
#[allow(unused)]
static mut BOOT_ARGS: EarlyBootArgs = EarlyBootArgs::new();
#[unsafe(link_section = ".data")]
static BOOT_INFO: StaticCell<BootInfo> = StaticCell::new(BootInfo::new());
#[unsafe(link_section = ".data")]
static MEMORY_REGIONS: StaticCell<Vec<MemoryRegion, 128>> = StaticCell::new(Vec::new());
#[unsafe(link_section = ".data")]
static mut BOOT_PT: usize = 0;
unsafe extern "Rust" {
fn __pie_boot_main(args: &BootInfo);
}
fn virt_entry(args: &BootInfo) {
unsafe {
MEMORY_REGIONS.as_mut().clear();
let _ = MEMORY_REGIONS
.as_mut()
.extend_from_slice(&args.memory_regions);
*BOOT_INFO.as_mut() = args.clone();
if let Some(ptr) = BOOT_INFO.fdt {
fdt::setup(ptr);
}
mainmem_start_rsv(args);
let regions = core::slice::from_raw_parts_mut(
MEMORY_REGIONS.as_mut().as_mut_ptr(),
MEMORY_REGIONS.len(),
);
BOOT_INFO.as_mut().memory_regions = regions.into();
BOOT_PT = BOOT_INFO.pg_start as usize;
__pie_boot_main(&BOOT_INFO);
}
}
pub fn boot_info() -> &'static BootInfo {
&BOOT_INFO
}
pub fn secondary_entry_addr() -> usize {
let ptr = arch::_start_secondary as usize;
ptr - boot_info().kcode_offset()
}
fn mainmem_start_rsv(args: &BootInfo) {
let lma = args.kimage_start_lma as usize;
let mainmem = MEMORY_REGIONS.iter().find(|r| {
let is_ram = matches!(r.kind, MemoryRegionKind::Ram);
let in_range = r.start <= lma && r.end > lma;
is_ram && in_range
});
let Some(mainmem) = mainmem else {
return;
};
let mut start = mainmem.start;
unsafe extern "C" {
fn _text();
}
let mut end = _text as usize - args.kcode_offset();
let mut indices_to_remove: heapless::Vec<usize, 16> = heapless::Vec::new();
for (i, r) in MEMORY_REGIONS.iter().enumerate() {
if !matches!(r.kind, MemoryRegionKind::Reserved) {
continue;
}
if !(end <= r.start || start >= r.end) {
if r.start <= start && r.end >= end {
return;
}
if r.start >= start && r.end <= end {
let _ = indices_to_remove.push(i);
continue;
}
if r.start <= start && r.end > start && r.end < end {
start = r.end;
}
if r.start > start && r.start < end && r.end >= end {
end = r.start;
}
}
}
for &i in indices_to_remove.iter().rev() {
MEMORY_REGIONS.as_mut().swap_remove(i);
}
if start >= end {
return;
}
let _ = MEMORY_REGIONS.as_mut().push(MemoryRegion {
kind: MemoryRegionKind::Reserved,
start,
end,
});
}
#[unsafe(no_mangle)]
unsafe extern "C" fn __pie_boot_default_secondary(_cpu_id: usize) {}