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

//! 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_page(&self) -> Option<u32>;
    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 any page associated with the last message.
    message_page: Cell<Option<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(None),
        };

        // 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_page(&self) -> Option<u32> {
        self.message_page.get()
    }

    fn get_message_sync(&self, buf: &mut [u8]) -> Result<usize, usize> {
        let header = self.dequeue_u32();
        if (header & HEADER_FLAG_LONG_MESSAGE) != 0 {
            let page = self.dequeue_u32();
            self.message_page.set(Some(page));
        }
        // Copy from the FIFO to the result buffer.
        let message_size = header & !HEADER_FLAG_LONG_MESSAGE;
        unsafe {
            let dst: *mut u32 = transmute(buf.as_ptr());
            let message_dwords = message_size / 4;
            for i in 0..message_dwords {
                dst.add(i as usize).write(self.dequeue_u32());
            }
        }
        return Ok(message_size as usize);
    }

    fn send_message_sync(&self, message_size: usize, buf: &[u8]) -> Result<usize, usize> {
        self.message_page.set(None);
        unsafe {
            self.enqueue_u32(message_size as u32);

            // Copy the reply to the FIFO.
            let src: *const u32 = transmute(buf.as_ptr());
            let message_dwords = message_size / 4;
            for i in 0..message_dwords {
                self.enqueue_u32(src.add(i).read());
            }
            let remainder = message_size - (4 * message_dwords);
            if remainder > 0 {
                // XXX check native byte order
                let mut word: u32 = buf[message_size - 1] as u32;
                if remainder > 1 {
                    word = (word << 8) | (buf[message_size - 2] as u32);
                }
                if remainder > 2 {
                    word = (word << 8) | (buf[message_size - 3] as u32);
                }
                self.enqueue_u32(word);
            }
        }
        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);
    }
}

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