// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![no_std]

// Support for loading sel4 & co directly from the tarball. This is only
// used when running in simulation where there is no SPI Flash support
// (the elfloader capsule calls out to load_sel4 based on whether it
// detects fpga hardware or not).

use matcha_hal::dprintf;
use matcha_hal::mailbox_hal::MailboxHAL;

pub mod elf_loader;
pub mod tar_loader;

pub const SMC_CONTROL_BLOCK: *mut u32 = 0x54020004 as *mut u32;

pub const SMC_PAGE_SIZE: usize = 4096;         // SMC page size
pub const SMC_BEGIN: usize = 0x50000000;       // Start of SMC memory in SEC map
pub const SMC_END: usize = SMC_BEGIN + (4*1024*1024); // NB: 4MiB of SMC memory

// Returns true if the specified page address fits in SMC memory
pub fn smc_is_page(addr: usize) -> bool {
    SMC_BEGIN <= addr && (addr + SMC_PAGE_SIZE) <= SMC_END
}

pub 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(mailbox: &'static dyn MailboxHAL) {
    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 sel4_elf.is_null() {
            dprintf!("Boot failure, seL4 kernel ELF missing in FLASH.\n");
            return;
        }

        if capdl_elf.is_null() {
            dprintf!("Boot failure capdl-loader ELF missing in FLASH.\n");
            return;
        }

        // If we found all of them, boot in Shodan mode.
        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 ui_p_reg_start = 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(),
            ui_p_reg_start - elf_loader::elf_phys_min(capdl_segments),
        );

        // NB: Renode loads the cantrip-builtins cpioarchive to the SMC memory
        // carve-out so there's nothing to do here.

        dprintf!("Starting management core\n");

        smc_send_bootmsg(mailbox, [
            ui_p_reg_start,
            ui_p_reg_start
                + round_up_to_page(
                    elf_loader::elf_phys_max(capdl_segments)
                        - elf_loader::elf_phys_min(capdl_segments),
                ),
            ui_p_reg_start - elf_loader::elf_phys_min(capdl_segments),
            (*capdl_elf).e_entry,
        ]);

        SMC_CONTROL_BLOCK.write_volatile(1);
    }
}

pub fn smc_send_bootmsg(mailbox: &'static dyn MailboxHAL, message: [u32; 4]) {
    unsafe {
        let _ = mailbox.send_message_sync(16, core::mem::transmute(message.as_ref()));
    }
}

pub fn smc_ram_memcpy(src: &mut [u8], dst: u32, count: usize) {
    unsafe {
        core::ptr::copy_nonoverlapping::<u8>(
            core::mem::transmute(src.as_ptr()),
            core::mem::transmute(dst),
            count,
        );
    }
}
pub fn smc_ram_zero(dst: u32, count: usize) {
    unsafe {
        core::ptr::write_bytes::<u8>(core::mem::transmute(dst), 0, count);
    }
}
