//! Matcha hardware mailbox.
//! TODO(aappleby): Rework this to match the RTL implementation.

use core::mem::transmute;
use kernel::common::registers::{register_structs, ReadWrite};
use kernel::common::StaticRef;

use crate::dprintf;
use crate::*;

pub const MAILBOX0_BASE: u32 = 0x400F0000;
pub const MAILBOX1_BASE: u32 = 0x400F1000;
pub const MAILBOX_SIZE_DWORDS: usize = 8;

register_structs! {
  pub MailboxRegisters {
      (0x000 => message: [ReadWrite<u32>; 8]),
      (0x020 => irq_send: ReadWrite<u32>),
      (0x024 => irq_recv: ReadWrite<u32>),
      (0x028 => @END),
  }
}

pub struct Mailbox {
    regs: StaticRef<MailboxRegisters>,
    plic_irq_send: isize,
    plic_irq_recv: isize,
}

pub const MAILBOX0: Mailbox = Mailbox {
    regs: unsafe { StaticRef::new(MAILBOX0_BASE as *mut MailboxRegisters) },
    plic_irq_send: 100,
    plic_irq_recv: 101,
};

pub const MAILBOX1: Mailbox = Mailbox {
    regs: unsafe { StaticRef::new(MAILBOX1_BASE as *mut MailboxRegisters) },
    plic_irq_send: 102,
    plic_irq_recv: 103,
};

// 32-bit-word bitfield helper for the PLIC's irq enable lines.
pub 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);
}

impl Mailbox {
    pub unsafe fn get_message(&self, message: &mut [u32]) {
        if message.len() > MAILBOX_SIZE_DWORDS {
            dprintf!("get_message() - Bad message size {}\n", message.len());
            return;
        }

        // Empty the mailbox - must be done with dword-sized writes
        for i in 0..message.len() {
            message[i] = self.regs.message[i].get();
            self.regs.message[i].set(0);
        }
    }

    pub unsafe fn set_message(&self, message: &[u32]) {
        if message.len() > MAILBOX_SIZE_DWORDS {
            dprintf!("set_message() - Bad message size {}\n", message.len());
            return;
        }

        // Fill the mailbox - must be done with dword-sized writes
        for i in 0..message.len() {
            self.regs.message[i].set(message[i]);
        }
    }

    // This requires a small bit of explanation - if an interrupt were to happen
    // between the 'if (*flag == 0)' and 'asm("wfi")' statements, we could end up
    // waiting forever for an interrupt that had already arrived. To prevent that,
    // we have to globally disable interrupts around those statements. Once
    // an interrupt has been triggered, 'wfi' will continue and the isr will
    // execute immediately after global interrupts are re-enabled.

    unsafe fn wait_until_full(&self) {
        while self.regs.irq_send.get() == 0 {
            clear_mstatus_bits(MIE_BIT | SIE_BIT);
            if self.regs.irq_send.get() == 0 {
                asm!("wfi");
            }
            set_mstatus_bits(MIE_BIT | SIE_BIT);
        }
    }

    unsafe fn wait_until_empty(&self) {
        while self.regs.irq_send.get() != 0 {
            clear_mstatus_bits(MIE_BIT | SIE_BIT);
            if self.regs.irq_send.get() != 0 {
                asm!("wfi");
            }
            set_mstatus_bits(MIE_BIT | SIE_BIT);
        }
    }

    unsafe fn wait_until_recv(&self) {
        while self.regs.irq_recv.get() == 0 {
            clear_mstatus_bits(MIE_BIT | SIE_BIT);
            if self.regs.irq_recv.get() == 0 {
                asm!("wfi");
            }
            set_mstatus_bits(MIE_BIT | SIE_BIT);
        }
    }

    pub unsafe fn send_message(&self, message: &[u32], wait_for_ack: bool) {
        self.wait_until_empty();
        self.set_message(message);
        self.regs.irq_send.set(1);

        if wait_for_ack {
            // Enable the RECV irq line, then wait for RECV. The ISR will disable the
            // irq line once it fires.
            set_bit(plic::PLIC_EN0, self.plic_irq_recv);
            self.wait_until_recv();
            self.regs.irq_recv.set(0);
        }
    }

    // TODO(aappleby): Refactor
    pub unsafe fn recv_message(&self, message: &mut [u32], send_ack: bool) {
        // Enable the SEND irq line and wait for new mail. The ISR will disable the
        // irq line once it fires.
        // set_bit(plic::PLIC_EN1, self.plic_irq_send);
        self.wait_until_full();
        self.regs.irq_send.set(0);

        // Message has arrived.
        self.get_message(message);

        if send_ack {
            // Trigger RECV
            self.regs.irq_recv.set(1);
        }
    }
}
