//! Matcha hardware mailbox.

// We want constants & registers to stay together even if they're not currently
// used in this file.
#![allow(dead_code)]

use core::cell::Cell;
use core::mem::transmute;
use core::slice;
use kernel::common::registers::{register_structs, ReadOnly, ReadWrite, WriteOnly};
use kernel::common::StaticRef;
use kernel::{AppSlice, Shared};

use crate::*;

//------------------------------------------------------------------------------

// The high bit of the message header is used to distinguish between "inline"
// messages that fit in the mailbox and "long" messages that contain the
// physical address of a memory page containing the message.
const HEADER_FLAG_LONG_MESSAGE: u32 = 0x80000000;

const MAILBOX_SIZE_DWORDS: u32 = 8;

const INTR_STATE_BIT_WTIRQ: u32 = 0b001;
const INTR_STATE_BIT_RTIRQ: u32 = 0b010;
const INTR_STATE_BIT_EIRQ: u32 = 0b100;
const INTR_STATE_MASK: u32 = 0b111;

const INTR_ENABLE_BIT_WTIRQ: u32 = 0b001;
const INTR_ENABLE_BIT_RTIRQ: u32 = 0b010;
const INTR_ENABLE_BIT_EIRQ: u32 = 0b100;

const STATUS_BIT_EMPTY: u32 = 0b0001;
const STATUS_BIT_FULL: u32 = 0b0010;
const STATUS_BIT_WFIFOL: u32 = 0b0100;
const STATUS_BIT_RFIFOL: u32 = 0b1000;

//------------------------------------------------------------------------------

register_structs! {
    pub MailboxRegisters {
        (0x000 => reg_intr_state:  ReadWrite<u32>),
        (0x004 => reg_intr_enable: ReadWrite<u32>),
        (0x008 => reg_intr_test:   ReadWrite<u32>),
        (0x00C => reg_mboxw:       WriteOnly<u32>),
        (0x010 => reg_mboxr:       ReadOnly<u32>),
        (0x014 => reg_status:      ReadOnly<u32>),
        (0x018 => reg_error:       ReadOnly<u32>),
        (0x01C => reg_wirqt:       ReadWrite<u32>),
        (0x020 => reg_rirqt:       ReadWrite<u32>),
        (0x024 => reg_ctrl:        WriteOnly<u32>),
        (0x028 => reg_fifor:       ReadOnly<u32>),
        (0x02C => reg_fifow:       ReadOnly<u32>),
        (0x030 => @END),
    }
}

//------------------------------------------------------------------------------

pub trait MailboxISR {
    fn on_wtirq(&self);
    fn on_rtirq(&self);
    fn on_eirq(&self);
}

//------------------------------------------------------------------------------

pub trait MailboxHAL {
    fn get_message_sync(&self, buf: &mut [u8]) -> Result<usize, usize>;
    fn send_message_sync(&self, message_size: usize, buf: &[u8]) -> Result<usize, usize>;
    fn get_message_slice_sync(&self, slice: &AppSlice<Shared, u8>) -> Result<usize, usize>;
    fn send_message_slice_sync(
        &self,
        message_len: usize,
        slice: &AppSlice<Shared, u8>,
    ) -> Result<usize, usize>;
}

//------------------------------------------------------------------------------

pub struct MailboxImpl {
    regs: StaticRef<MailboxRegisters>,
    
    // PLIC line for write interrupt
    wtirq: u32, 
    
    // PLIC line for read interrupt
    rtirq: u32,

    // PLIC line for error interrupt
    eirq: u32,

    // Client interrupt callback
    client_isr: Cell<Option<&'static dyn MailboxISR>>,

    // Physical address of the memory page used to send the last message, if it
    // was a long message.
    message_page: Cell<u32>,
}

//------------------------------------------------------------------------------

impl MailboxImpl {
    pub fn new(mailbox_base_addr: u32, wtirq: u32, rtirq: u32, eirq: u32) -> Self {
        let inst = Self {
            regs: unsafe { StaticRef::new(mailbox_base_addr as *mut MailboxRegisters) },
            wtirq: wtirq,
            rtirq: rtirq,
            eirq: eirq,
            client_isr: Cell::new(None),
            message_page: Cell::new(0),
        };

        // Clear any old interrupts and enable receive and error interrupts.
        inst.regs.reg_wirqt.set(0);
        inst.regs.reg_rirqt.set(0);
        inst.regs.reg_intr_state.set(INTR_STATE_MASK); // W1C
        inst.regs
            .reg_intr_enable
            .set(INTR_ENABLE_BIT_RTIRQ | INTR_ENABLE_BIT_EIRQ);
        unsafe {
            MailboxImpl::set_bit(plic_hal::PLIC_EN0, inst.rtirq as isize);
            MailboxImpl::set_bit(plic_hal::PLIC_EN0, inst.eirq as isize);
        }

        return inst;
    }

    pub fn set_client_isr(&self, client: &'static dyn MailboxISR) {
        self.client_isr.set(Some(client));
    }

    //--------------------------------------------------------------------------
    // 32-bit-word bitfield helpers for the PLIC's irq enable lines.

    unsafe fn set_bit(base: u32, bit_index: isize) {
        let buf: *mut u32 = transmute(base);
        let mut bits = buf.offset(bit_index >> 5).read_volatile();
        bits |= 1 << (bit_index & 31);
        buf.offset(bit_index >> 5).write_volatile(bits);
    }

    unsafe fn clear_bit(base: u32, bit_index: isize) {
        let buf: *mut u32 = transmute(base);
        let mut bits = buf.offset(bit_index >> 5).read_volatile();
        bits &= !(1 << (bit_index & 31));
        buf.offset(bit_index >> 5).write_volatile(bits);
    }

    fn enqueue_u32(&self, x: u32) {
        while (self.regs.reg_status.get() & STATUS_BIT_FULL) == STATUS_BIT_FULL {}
        self.regs.reg_mboxw.set(x);
    }

    fn dequeue_u32(&self) -> u32 {
        while (self.regs.reg_status.get() & STATUS_BIT_EMPTY) == STATUS_BIT_EMPTY {}
        return self.regs.reg_mboxr.get();
    }

    pub fn drain_read_fifo(&self) {
        while (self.regs.reg_status.get() & STATUS_BIT_EMPTY) == 0 {
            let _ = self.regs.reg_mboxr.get();
        }
    }

    pub fn dump(&self) {
        dprintf!("reg_intr_state  {:x}\n", self.regs.reg_intr_state.get());
        dprintf!("reg_intr_enable {:x}\n", self.regs.reg_intr_enable.get());
        dprintf!("reg_intr_test   {:x}\n", self.regs.reg_intr_test.get());
        dprintf!("reg_status      {:x}\n", self.regs.reg_status.get());
        dprintf!("reg_error       {:x}\n", self.regs.reg_error.get());
        dprintf!("reg_wirqt       {:x}\n", self.regs.reg_wirqt.get());
        dprintf!("reg_rirqt       {:x}\n", self.regs.reg_rirqt.get());
        dprintf!("reg_fifor       {:x}\n", self.regs.reg_fifor.get());
        dprintf!("reg_fifow       {:x}\n", self.regs.reg_fifow.get());
    }
}

//------------------------------------------------------------------------------

impl MailboxHAL for MailboxImpl {
    fn get_message_sync(&self, buf: &mut [u8]) -> Result<usize, usize> {
        let header = self.dequeue_u32();
        let message_size = header & !HEADER_FLAG_LONG_MESSAGE;

        if (header & HEADER_FLAG_LONG_MESSAGE) != 0 {
            // Long message, copy from message page to result buffer.
            let message_page = self.dequeue_u32();
            self.message_page.set(message_page);
            unsafe {
                let src: *const u8 = transmute(message_page);
                let dst: *mut u8 = transmute(buf.as_ptr());
                core::ptr::copy_nonoverlapping(src, dst, message_size as usize);
            }
        } else {
            // Short message, copy from mailbox to result buffer.
            unsafe {
                let dst: *mut u32 = transmute(buf.as_ptr());
                let message_dwords = message_size / 4;
                for i in 0..message_dwords {
                    dst.offset(i as isize).write(self.dequeue_u32());
                }
            }
        }
        return Ok(message_size as usize);
    }

    fn send_message_sync(&self, message_size: usize, buf: &[u8]) -> Result<usize, usize> {
        unsafe {
            let message_page = self.message_page.get();
            if message_page != 0 {
                // Long message, reply using the same physical page as the request.
                let src: *const u8 = transmute(buf.as_ptr());
                let dst: *mut u8 = transmute(message_page);
                core::ptr::copy_nonoverlapping(src, dst, message_size);

                self.enqueue_u32(0x80000000 | message_size as u32);
                self.enqueue_u32(message_page);

                // Response sent, clear cached page address
                self.message_page.set(0);
            } else {
                // Short message, respond via the mailbox.
                let src: *const u32 = transmute(buf.as_ptr());
                let message_dwords = message_size / 4;
                self.enqueue_u32(message_size as u32);
                for i in 0..message_dwords {
                    self.enqueue_u32(src.offset(i as isize).read());
                }
            }
        }

        return Ok(message_size);
    }

    fn get_message_slice_sync(&self, slice: &AppSlice<Shared, u8>) -> Result<usize, usize> {
        unsafe {
            let buf: &mut [u8] = slice::from_raw_parts_mut(slice.ptr() as *mut u8, slice.len());
            return self.get_message_sync(buf);
        }
    }

    fn send_message_slice_sync(
        &self,
        message_len: usize,
        slice: &AppSlice<Shared, u8>,
    ) -> Result<usize, usize> {
        unsafe {
            let buf: &[u8] = slice::from_raw_parts(slice.ptr() as *const u8, slice.len());
            return self.send_message_sync(message_len, buf);
        }
    }
}

//------------------------------------------------------------------------------
// The interrupt handler in platform/src/chip.rs will call these handlers, which
// in turn call the capsule-level handlers and then clear the interrupt.

impl MailboxISR for MailboxImpl {
    fn on_wtirq(&self) {
        self.client_isr.get().map(|c| c.on_wtirq());
        self.regs.reg_intr_state.set(INTR_STATE_BIT_WTIRQ);
    }

    fn on_rtirq(&self) {
        self.client_isr.get().map(|c| c.on_rtirq());
        if (self.regs.reg_status.get() & STATUS_BIT_EMPTY) == 0 {
            self.drain_read_fifo();
        }
        self.regs.reg_intr_state.set(INTR_STATE_BIT_RTIRQ);
    }

    fn on_eirq(&self) {
        dprintf!("MailboxImpl::on_eirq fired - this is probably bad\n");
        self.client_isr.get().map(|c| c.on_eirq());
        self.regs.reg_intr_state.set(INTR_STATE_BIT_EIRQ);
    }
}

//------------------------------------------------------------------------------
