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

//! Platform Level Interrupt Control peripheral driver.

use crate::plic_constants::*;
use kernel::common::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
use kernel::common::StaticRef;

pub const PLIC_ADDR: u32 = 0x4800_0000;

pub const PLIC_EN0: u32 = PLIC_ADDR + RV_PLIC_IE0_0_REG_OFFSET as u32;
pub const PLIC_CCCR0: u32 = PLIC_ADDR + RV_PLIC_CC0_REG_OFFSET as u32;

register_structs! {
    pub PlicRegisters {
        /// Interrupt Priority Registers
        (RV_PLIC_PRIO0_REG_OFFSET => priority: [ReadWrite<u32, priority::Register>; RV_PLIC_PARAM_NUM_SRC as usize]),
        (RV_PLIC_PRIO0_REG_OFFSET + 4*(RV_PLIC_PARAM_NUM_SRC as usize) => _reserved0),
        /// Interrupt Pending Register
        (RV_PLIC_IP_0_REG_OFFSET => pending: [ReadOnly<u32>; RV_PLIC_IP_MULTIREG_COUNT as usize]),
        (RV_PLIC_IP_0_REG_OFFSET + 4*(RV_PLIC_IP_MULTIREG_COUNT as usize) => _reserved1),
        /// Interrupt Enable Register
        (RV_PLIC_IE0_0_REG_OFFSET => enable: [ReadWrite<u32>; RV_PLIC_IE0_MULTIREG_COUNT as usize]),
        (RV_PLIC_IE0_0_REG_OFFSET + 4*(RV_PLIC_IE0_MULTIREG_COUNT as usize) => _reserved2),
        /// Priority Threshold Register
        (RV_PLIC_THRESHOLD0_REG_OFFSET => threshold: ReadWrite<u32, priority::Register>),
        /// Claim/Complete Register
        (RV_PLIC_CC0_REG_OFFSET => claim: ReadWrite<u32>),
        (RV_PLIC_CC0_REG_OFFSET + 4 => @END),
    }
}

register_bitfields![u32,
    priority [
        Priority OFFSET(0) NUMBITS(3) []
    ]
];

const PLIC_BASE: StaticRef<PlicRegisters> =
    unsafe { StaticRef::new(PLIC_ADDR as *const PlicRegisters) };

/// Clear all pending interrupts.
pub unsafe fn clear_all_pending() {
    let _plic: &PlicRegisters = &*PLIC_BASE;
}

/// Enable all interrupts.
pub unsafe fn enable_all() {
    let plic: &PlicRegisters = &*PLIC_BASE;

    let en_iter = plic.enable.iter();
    for en in en_iter {
        en.set(0xFFFF_FFFF);
    }

    // Set the max priority for each interrupt. This is not really used
    // at this point.
    let mut iter = plic.priority.iter();
    iter.next(); // Interrupt source 0 can't be enabled.
    for priority in iter {
        priority.write(priority::Priority.val(3));
    }

    // Accept all interrupts.
    plic.threshold.write(priority::Priority.val(1));
}

/// Disable all interrupts.
pub unsafe fn disable_all() {
    let plic: &PlicRegisters = &*PLIC_BASE;
    for enable in plic.enable.iter() {
        enable.set(0);
    }
}

/// Get the index (0-256) of the lowest number pending interrupt, or `None` if
/// none is pending. RISC-V PLIC has a "claim" register which makes it easy
/// to grab the highest priority pending interrupt.
pub unsafe fn next_pending() -> Option<u32> {
    let plic: &PlicRegisters = &*PLIC_BASE;

    let claim = plic.claim.get();
    if claim == 0 {
        None
    } else {
        Some(claim)
    }
}

/// Signal that an interrupt is finished being handled. In Tock, this should be
/// called from the normal main loop (not the interrupt handler).
pub unsafe fn complete(index: u32) {
    let plic: &PlicRegisters = &*PLIC_BASE;
    plic.claim.set(index);
}

/// Return `true` if there are any pending interrupts in the PLIC, `false`
/// otherwise.
pub unsafe fn has_pending() -> bool {
    let plic: &PlicRegisters = &*PLIC_BASE;

    plic.pending.iter().fold(0, |i, pending| pending.get() | i) != 0
}
