blob: 5677c8152ff6aa45c6ea2d5f857a1e1436c922e2 [file] [log] [blame]
#![no_std]
use core::mem::transmute;
use matcha_hal::dprintf;
pub mod elf_loader;
pub mod tar_loader;
pub const SMC_CONTROL_BLOCK: *mut u32 = 0x49000000 as *mut u32;
fn round_up_to_page(addr: u32) -> u32 {
return (addr + 4095) & !4095;
}
// TODO(aappleby): Break this down into smaller pieces and move into app/main
pub fn load_sel4() {
unsafe {
// Look in our tar file for the ELFs we need to boot Shodan.
let sel4_elf = elf_loader::find_elf("kernel");
let capdl_elf = elf_loader::find_elf("capdl-loader");
// If we found all of them, boot in Shodan mode.
if !sel4_elf.is_null() && !capdl_elf.is_null() {
dprintf!("Loading seL4 kernel elf\n");
elf_loader::load_elf_segments(sel4_elf.as_ref().unwrap(), 0);
let sel4_segments = elf_loader::elf_get_segments(sel4_elf);
let capdl_segments = elf_loader::elf_get_segments(capdl_elf);
let sel4_pend = round_up_to_page(elf_loader::elf_phys_max(sel4_segments));
dprintf!("Loading capdl-loader to the page after seL4\n");
elf_loader::load_elf_segments(
capdl_elf.as_ref().unwrap(),
sel4_pend - elf_loader::elf_phys_min(capdl_segments),
);
dprintf!("Starting management core\n");
let entry_point: u32 = (*sel4_elf).e_entry
- (elf_loader::elf_virt_min(sel4_segments)
- elf_loader::elf_phys_min(sel4_segments));
let message = [
transmute(sel4_pend),
transmute(
sel4_pend
+ round_up_to_page(
elf_loader::elf_phys_max(capdl_segments)
- elf_loader::elf_phys_min(capdl_segments),
),
),
transmute(sel4_pend - elf_loader::elf_phys_min(capdl_segments)),
transmute((*capdl_elf).e_entry),
];
matcha_hal::mailbox::MAILBOX1.set_message(&message);
SMC_CONTROL_BLOCK.write_volatile(entry_point);
} else {
dprintf!("Missing sel4_elf or capdl_elf\n");
}
}
}