//! 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::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::dprintf;
use matcha_hal::timer_hal;
use matcha_hal::uart_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,
    elfloader_capsule: &'static ElfLoaderCapsule,
    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();

    dprintf!("sw/matcha/platform/src/main.rs::reset_handler()\n");

    // 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,
        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 elfloader_capsule = static_init!(
        matcha_capsules::elfloader_capsule::ElfLoaderCapsule,
        matcha_capsules::elfloader_capsule::ElfLoaderCapsule::new()
    );

    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 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);
}
