// 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.

//! 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_capsules::pinmux_capsule::PinmuxCapsule;
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::pinmux_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>,
    >,
    pinmux_capsule: &'static PinmuxCapsule,
}

/// 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)),
            CAPSULE_PINMUX => f(Some(self.pinmux_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 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()
    );

    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 pinmux_capsule = static_init!(
        matcha_capsules::pinmux_capsule::PinmuxCapsule,
        matcha_capsules::pinmux_capsule::PinmuxCapsule::new(
            board_kernel.create_grant(&memory_allocation_cap),
        )
    );
    pinmux_capsule.set_pinmux(&pinmux_hal::PINMUX);

    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,
        pinmux_capsule: pinmux_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);
}
