//! Board file for Shodan's "Matcha" RISC-V development platform.

#![no_std]
#![no_main]
#![feature(llvm_asm)]
#![feature(const_fn)]
#![feature(naked_functions)]

use capsules::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
use core::fmt::Write;
use core::panic::PanicInfo;
use kernel::capabilities;
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
use kernel::component::Component;
use kernel::hil;
use kernel::hil::flash::HasClient;
use kernel::hil::time::Alarm;
use kernel::Chip;
use kernel::Platform;
use kernel::{create_capability, debug, static_init};
use kernel::debug::IoWrite;
use matcha_capsules::dprintf_capsule::DprintfCapsule;
use matcha_capsules::elfloader_capsule::ElfLoaderCapsule;
use matcha_capsules::mailbox_capsule::MailboxCapsule;
use matcha_capsules::storage_capsule::StorageCapsule;
use matcha_config::*;
use matcha_hal::spi_host_hal;
use matcha_hal::timer_hal;
use matcha_hal::uart_hal;
use matcha_hal::smc_ctrl_hal;
use matcha_hal::rv_core_ibex_hal;
use rv32i::csr;

pub mod chip;

// Writer struct for panic handler.
struct Writer {}
static mut WRITER: Writer = Writer {};
impl Write for Writer {
    fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
        self.write(s.as_bytes());
        Ok(())
    }
}
impl IoWrite for Writer {
    fn write(&mut self, buf: &[u8]) {
        unsafe {
            uart_hal::UART0.transmit_sync(buf);
        }
    }
}

// Stubbed LED for panic handler.
pub struct MatchaLed {
}
impl MatchaLed {
    pub fn new() -> Self {
        Self {}
    }
}
impl kernel::hil::led::Led for MatchaLed {
    fn init(&mut self) { }
    fn on(&mut self) { }
    fn off(&mut self) { }
    fn toggle(&mut self) { }
    fn read(&self) -> bool { true }
}

/// Panic handler.
#[cfg(not(test))]
#[no_mangle]
#[panic_handler]
pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
    let first_led = &mut MatchaLed::new();
    let writer = &mut WRITER;
    debug::panic(
        &mut [first_led],
        writer,
        pi,
        &rv32i::support::nop,
        &PROCESSES,
        &CHIP,
    )
}

/// These symbols are defined in the linker script.
extern "C" {
    /// Beginning of the ROM region containing app images.
    static _sapps: u8;
    /// End of the ROM region containing app images.
    static _eapps: u8;
    /// Beginning of the RAM region for app memory.
    static mut _sappmem: u8;
    /// End of the RAM region for app memory.
    static _eappmem: u8;
}

// Actual memory for holding the active process structures. Need an empty list
// at least.
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; 4] =
    [None, None, None, None];

static mut CHIP: Option<
    &'static crate::chip::Matcha<VirtualMuxAlarm<'static, timer_hal::RvTimer>>,
> = None;

/// Dummy buffer that causes the linker to reserve enough space for the stack.
/// Must be at least 16k in debug builds (@aappleby - not sure why, what's so large?)
#[no_mangle]
#[link_section = ".stack_buffer"]
pub static mut STACK_MEMORY: [u8; 0x4000] = [0; 0x4000];

/// A structure representing this platform that holds references to all
/// capsules for this platform. We've included an alarm and console.
struct MatchaPlatform {
    console_capsule: &'static capsules::console::Console<'static>,
    alarm_capsule: &'static capsules::alarm::AlarmDriver<
        'static,
        VirtualMuxAlarm<'static, timer_hal::RvTimer<'static>>,
    >,
    dprintf_capsule: &'static DprintfCapsule,
    storage_capsule: &'static StorageCapsule<
        'static,
        matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >,
    >,
    elfloader_capsule: &'static ElfLoaderCapsule<
        'static,
        matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >,
    >,
    mailbox_capsule: &'static MailboxCapsule,
    lldb_capsule: &'static capsules::low_level_debug::LowLevelDebug<
        'static,
        capsules::virtual_uart::UartDevice<'static>,
    >,
}

/// Mapping of integer syscalls to objects that implement syscalls.
impl Platform for MatchaPlatform {
    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
    where
        F: FnOnce(Option<&dyn kernel::Driver>) -> R,
    {
        match driver_num {
            CAPSULE_CONSOLE => f(Some(self.console_capsule)),
            CAPSULE_ALARM => f(Some(self.alarm_capsule)),
            CAPSULE_DPRINTF => f(Some(self.dprintf_capsule)),
            CAPSULE_STORAGE => f(Some(self.storage_capsule)),
            CAPSULE_ELFLOADER => f(Some(self.elfloader_capsule)),
            CAPSULE_MAILBOX => f(Some(self.mailbox_capsule)),
            CAPSULE_LLDB => f(Some(self.lldb_capsule)),
            _ => f(None),
        }
    }
}

/// Reset Handler.
///
/// This function is called from the arch crate after some very basic RISC-V
/// setup.
#[no_mangle]
pub unsafe fn reset_handler() {
    // Basic setup of the platform.
    rv32i::init_memory();
    // Ibex-specific handler
    crate::chip::configure_trap_handler();

    // initialize capabilities
    let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
    let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability);

    let main_loop_cap = create_capability!(capabilities::MainLoopCapability);

    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES));

    let dynamic_deferred_call_clients =
        static_init!([DynamicDeferredCallClientState; 1], Default::default());
    let dynamic_deferred_caller = static_init!(
        DynamicDeferredCall,
        DynamicDeferredCall::new(dynamic_deferred_call_clients)
    );
    DynamicDeferredCall::set_global_instance(dynamic_deferred_caller);

    // Create a shared UART channel for the console and for kernel debug.
    let uart_mux = components::console::UartMuxComponent::new(
        &uart_hal::UART0,
        matcha_config::UART0_BAUDRATE,
        dynamic_deferred_caller,
    )
    .finalize(());

    let alarm = &timer_hal::TIMER;
    alarm.setup();

    // Create a shared virtualization mux layer on top of a single hardware
    // alarm.
    let mux_alarm = static_init!(MuxAlarm<'static, timer_hal::RvTimer>, MuxAlarm::new(alarm));
    hil::time::Alarm::set_alarm_client(&timer_hal::TIMER, mux_alarm);

    // Alarm
    let virtual_alarm_user = static_init!(
        VirtualMuxAlarm<'static, timer_hal::RvTimer>,
        VirtualMuxAlarm::new(mux_alarm)
    );
    let scheduler_timer_virtual_alarm = static_init!(
        VirtualMuxAlarm<'static, timer_hal::RvTimer>,
        VirtualMuxAlarm::new(mux_alarm)
    );
    let alarm_capsule = static_init!(
        capsules::alarm::AlarmDriver<'static, VirtualMuxAlarm<'static, timer_hal::RvTimer>>,
        capsules::alarm::AlarmDriver::new(
            virtual_alarm_user,
            board_kernel.create_grant(&memory_allocation_cap)
        )
    );
    hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm_capsule);

    let chip = static_init!(
        crate::chip::Matcha<VirtualMuxAlarm<'static, timer_hal::RvTimer>>,
        crate::chip::Matcha::new(scheduler_timer_virtual_alarm)
    );
    scheduler_timer_virtual_alarm.set_alarm_client(chip.scheduler_timer());
    CHIP = Some(chip);

    // Need to enable all interrupts for Tock Kernel
    chip.enable_plic_interrupts();
    // enable interrupts globally
    csr::CSR
        .mie
        .modify(csr::mie::mie::msoft::SET + csr::mie::mie::mtimer::SET + csr::mie::mie::mext::SET);
    csr::CSR.mstatus.modify(csr::mstatus::mstatus::mie::SET);

    // Setup the console.
    let console_capsule =
        components::console::ConsoleComponent::new(board_kernel, uart_mux).finalize(());
    // Create the debugger object that handles calls to `debug!()`.
    components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());

    let lldb_capsule =
        components::lldb::LowLevelDebugComponent::new(board_kernel, uart_mux).finalize(());

    let dprintf_capsule = static_init!(
        DprintfCapsule,
        DprintfCapsule {
            app_data_grant: board_kernel.create_grant(&memory_allocation_cap)
        }
    );

    let storage_capsule = static_init!(
        matcha_capsules::storage_capsule::StorageCapsule<
            'static,
        matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >>,
        matcha_capsules::storage_capsule::StorageCapsule::new(
             board_kernel.create_grant(&memory_allocation_cap)
        )
    );

    // Construct a mailbox that points to the platform-specific base address and
    // PLIC lines
    let mailbox_hal: &'static mut matcha_hal::mailbox_hal::MailboxImpl = static_init!(
        matcha_hal::mailbox_hal::MailboxImpl,
        matcha_hal::mailbox_hal::MailboxImpl::new(
            MAILBOX_BASE,
            MAILBOX_WTIRQ,
            MAILBOX_RTIRQ,
            MAILBOX_EIRQ,
        )
    );

    let fpga_version = rv_core_ibex_hal::RV_CORE_IBEX_SEC.fpga_version();
    let elfloader_capsule = static_init!(
             matcha_capsules::elfloader_capsule::ElfLoaderCapsule<
                 'static,
             matcha_capsules::nexus_spiflash::NexusSpiflash<
                 'static,
                 capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
             >>,
             matcha_capsules::elfloader_capsule::ElfLoaderCapsule::new(fpga_version != 0)
    );

    let mailbox_capsule = static_init!(
        matcha_capsules::mailbox_capsule::MailboxCapsule,
        matcha_capsules::mailbox_capsule::MailboxCapsule::new(
            board_kernel.create_grant(&memory_allocation_cap),
        )
    );

    // Mailbox interrupts are delegated to the capsule, except for the
    // bottom-level bit twiddling.
    mailbox_hal.set_client_isr(mailbox_capsule);

    // Our other capsules and our "chip" hold references to the mailbox.
    mailbox_capsule.set_mailbox(mailbox_hal);
    elfloader_capsule.set_mailbox(mailbox_hal);
    chip.set_mailbox_isr(mailbox_hal);

    let mux_spi = components::spi::SpiMuxComponent::new(
        &spi_host_hal::SPI_HOST0
    ).finalize(components::spi_mux_component_helper!(spi_host_hal::SpiHw));
    let nexus_spiflash_spi = static_init!(
        capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        capsules::virtual_spi::VirtualSpiMasterDevice::new(mux_spi, 0)
    );
    let nexus_spiflash_virtual_alarm = static_init!(
        VirtualMuxAlarm<'static, timer_hal::RvTimer>,
        VirtualMuxAlarm::new(mux_alarm)
    );
    let nexus_spiflash = static_init!(
        matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >,
        matcha_capsules::nexus_spiflash::NexusSpiflash::new(
            nexus_spiflash_spi,
            &mut matcha_capsules::nexus_spiflash::TXBUFFER,
            &mut matcha_capsules::nexus_spiflash::RXBUFFER,
        )
    );
    nexus_spiflash_spi.set_client(nexus_spiflash);
    nexus_spiflash_virtual_alarm.set_alarm_client(nexus_spiflash);


    let mux_flash = static_init!(
        capsules::virtual_flash::MuxFlash<'static, matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >>,
        capsules::virtual_flash::MuxFlash::new(nexus_spiflash)
    );
    hil::flash::HasClient::set_client(nexus_spiflash, mux_flash);

    // Storage access reads (only) from flash.
    let storage_virtual_flash = static_init!(
        capsules::virtual_flash::FlashUser<'static, matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >>,
        capsules::virtual_flash::FlashUser::new(mux_flash)
    );
    let storage_read_page: &'static mut matcha_capsules::nexus_spiflash::NexusSpiflashPage = static_init!(
        matcha_capsules::nexus_spiflash::NexusSpiflashPage,
        matcha_capsules::nexus_spiflash::NexusSpiflashPage::default()
    );
    storage_capsule.set_flash(storage_virtual_flash, storage_read_page);
    storage_virtual_flash.set_client(storage_capsule);

    // Elfloader reads artifacts from flash & boots the SMC.
    elfloader_capsule.set_smc_ctrl(&smc_ctrl_hal::SMC_CTRL);
    let elfloader_virtual_flash = static_init!(
        capsules::virtual_flash::FlashUser<'static, matcha_capsules::nexus_spiflash::NexusSpiflash<
            'static,
            capsules::virtual_spi::VirtualSpiMasterDevice<'static, spi_host_hal::SpiHw>,
        >>,
        capsules::virtual_flash::FlashUser::new(mux_flash)
    );
    let elfloader_read_page: &'static mut matcha_capsules::nexus_spiflash::NexusSpiflashPage = static_init!(
        matcha_capsules::nexus_spiflash::NexusSpiflashPage,
        matcha_capsules::nexus_spiflash::NexusSpiflashPage::default()
    );
    elfloader_capsule.set_flash(elfloader_virtual_flash, elfloader_read_page);
    elfloader_virtual_flash.set_client(elfloader_capsule);
    // NB: main app triggers the Elfloader bootstrap of seL4

    let platform = MatchaPlatform {
        console_capsule: console_capsule,
        alarm_capsule: alarm_capsule,
        dprintf_capsule: dprintf_capsule,
        storage_capsule: storage_capsule,
        elfloader_capsule: elfloader_capsule,
        mailbox_capsule: mailbox_capsule,
        lldb_capsule: lldb_capsule,
    };

    kernel::procs::load_processes(
        board_kernel,
        chip,
        core::slice::from_raw_parts(
            &_sapps as *const u8,
            &_eapps as *const u8 as usize - &_sapps as *const u8 as usize,
        ),
        core::slice::from_raw_parts_mut(
            &mut _sappmem as *mut u8,
            &_eappmem as *const u8 as usize - &_sappmem as *const u8 as usize,
        ),
        &mut PROCESSES,
        kernel::procs::FaultResponse::Panic,
        &process_mgmt_cap,
    )
    .unwrap_or_else(|err| {
        debug!("Error loading processes!");
        debug!("{:?}", err);
    });
    debug!("MatchaPlatform initialisation complete. Entering main loop");

    let scheduler = components::sched::priority::PriorityComponent::new(board_kernel).finalize(());
    board_kernel.kernel_loop(&platform, chip, None, scheduler, &main_loop_cap);
}
