/*
 * Copyright (c) 2010, 2012-2013, 2016 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __ARCH_ARM_INTERRUPT_HH__
#define __ARCH_ARM_INTERRUPT_HH__

#include "arch/arm/faults.hh"
#include "arch/arm/regs/misc.hh"
#include "arch/arm/utility.hh"
#include "arch/generic/interrupts.hh"
#include "cpu/thread_context.hh"
#include "debug/Interrupt.hh"
#include "params/ArmInterrupts.hh"

namespace gem5
{

namespace ArmISA
{

enum InterruptTypes
{
    INT_RST,
    INT_ABT,
    INT_IRQ,
    INT_FIQ,
    INT_SEV, // Special interrupt for recieving SEV's
    INT_VIRT_IRQ,
    INT_VIRT_FIQ,
    NumInterruptTypes
};

class Interrupts : public BaseInterrupts
{
  private:
    bool interrupts[NumInterruptTypes];
    uint64_t intStatus;

  public:
    using Params = ArmInterruptsParams;

    Interrupts(const Params &p) : BaseInterrupts(p)
    {
        clearAll();
    }


    void
    post(int int_num, int index) override
    {
        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);

        if (int_num < 0 || int_num >= NumInterruptTypes)
            panic("int_num out of bounds\n");

        if (index != 0)
            panic("No support for other interrupt indexes\n");

        interrupts[int_num] = true;
        intStatus |= 1ULL << int_num;
    }

    void
    clear(int int_num, int index) override
    {
        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);

        if (int_num < 0 || int_num >= NumInterruptTypes)
            panic("int_num out of bounds\n");

        if (index != 0)
            panic("No support for other interrupt indexes\n");

        interrupts[int_num] = false;
        intStatus &= ~(1ULL << int_num);
    }

    void
    clearAll() override
    {
        DPRINTF(Interrupt, "Interrupts all cleared\n");
        intStatus = 0;
        memset(interrupts, 0, sizeof(interrupts));
    }

    enum InterruptMask
    {
        INT_MASK_M, // masked (subject to PSTATE.{A,I,F} mask bit
        INT_MASK_T, // taken regardless of mask
        INT_MASK_P  // pending
    };

    bool takeInt(InterruptTypes int_type) const;

    bool
    checkInterrupts() const override
    {
        HCR  hcr  = tc->readMiscReg(MISCREG_HCR);

        if (!(intStatus || hcr.va || hcr.vi || hcr.vf))
            return false;

        CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);

        bool no_vhe = !HaveVirtHostExt(tc);
        bool amo, fmo, imo;
        if (hcr.tge == 1){
            amo =  (no_vhe || hcr.e2h == 0);
            fmo =  (no_vhe || hcr.e2h == 0);
            imo =  (no_vhe || hcr.e2h == 0);
        } else {
            amo = hcr.amo;
            fmo = hcr.fmo;
            imo = hcr.imo;
        }

        bool isHypMode   = currEL(tc) == EL2;
        bool isSecure    = ArmISA::isSecure(tc);
        bool allowVIrq   = !cpsr.i && imo && !isSecure && !isHypMode;
        bool allowVFiq   = !cpsr.f && fmo && !isSecure && !isHypMode;
        bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode;

        if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
               (hcr.va && allowVAbort)) )
            return false;

        bool take_irq = takeInt(INT_IRQ);
        bool take_fiq = takeInt(INT_FIQ);
        bool take_ea =  takeInt(INT_ABT);

        return ((interrupts[INT_IRQ] && take_irq)                   ||
                (interrupts[INT_FIQ] && take_fiq)                   ||
                (interrupts[INT_ABT] && take_ea)                    ||
                ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) ||
                ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) ||
                (hcr.va && allowVAbort)                             ||
                (interrupts[INT_RST])                               ||
                (interrupts[INT_SEV])
               );
    }

    /**
     * This function is used to check if a wfi operation should sleep. If there
     * is an interrupt pending, even if it's masked, wfi doesn't sleep.
     * @return any interrupts pending
     */
    bool
    checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const
    {
        uint64_t maskedIntStatus;
        bool     virtWake;

        maskedIntStatus = intStatus & ~((1 << INT_VIRT_IRQ) |
                                        (1 << INT_VIRT_FIQ));
        virtWake  = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo;
        virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo;
        virtWake |=  hcr.va                              && hcr.amo;
        virtWake &= (cpsr.mode != MODE_HYP) && !isSecure(tc);
        return maskedIntStatus || virtWake;
    }

    uint32_t
    getISR(HCR hcr, CPSR cpsr, SCR scr)
    {
        bool useHcrMux;
        CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR

        useHcrMux = (cpsr.mode != MODE_HYP) && !isSecure(tc);
        isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi)
                                      :  interrupts[INT_IRQ];
        isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf)
                                      :  interrupts[INT_FIQ];
        isr.a = (useHcrMux & hcr.amo) ?  hcr.va : interrupts[INT_ABT];
        return isr;
    }

    /**
     * Check the state of a particular interrupt, ignoring CPSR masks.
     *
     * This method is primarily used when running the target CPU in a
     * hardware VM (e.g., KVM) to check if interrupts should be
     * delivered upon guest entry.
     *
     * @param interrupt Interrupt type to check the state of.
     * @return true if the interrupt is asserted, false otherwise.
     */
    bool
    checkRaw(InterruptTypes interrupt) const
    {
        if (interrupt >= NumInterruptTypes)
            panic("Interrupt number out of range.\n");

        return interrupts[interrupt];
    }

    Fault
    getInterrupt() override
    {
        assert(checkInterrupts());

        HCR  hcr  = tc->readMiscReg(MISCREG_HCR);
        CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);

        bool no_vhe = !HaveVirtHostExt(tc);
        bool amo, fmo, imo;
        if (hcr.tge == 1){
            amo =  (no_vhe || hcr.e2h == 0);
            fmo =  (no_vhe || hcr.e2h == 0);
            imo =  (no_vhe || hcr.e2h == 0);
        } else {
            amo = hcr.amo;
            fmo = hcr.fmo;
            imo = hcr.imo;
        }

        // Calculate a few temp vars so we can work out if there's a pending
        // virtual interrupt, and if its allowed to happen
        // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
        bool isHypMode   = currEL(tc) == EL2;
        bool isSecure    = ArmISA::isSecure(tc);
        bool allowVIrq   = !cpsr.i && imo && !isSecure && !isHypMode;
        bool allowVFiq   = !cpsr.f && fmo && !isSecure && !isHypMode;
        bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode;

        bool take_irq = takeInt(INT_IRQ);
        bool take_fiq = takeInt(INT_FIQ);
        bool take_ea =  takeInt(INT_ABT);

        if (interrupts[INT_IRQ] && take_irq)
            return std::make_shared<Interrupt>();
        if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
            return std::make_shared<VirtualInterrupt>();
        if (interrupts[INT_FIQ] && take_fiq)
            return std::make_shared<FastInterrupt>();
        if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
            return std::make_shared<VirtualFastInterrupt>();
        if (interrupts[INT_ABT] && take_ea)
            return std::make_shared<SystemError>();
        if (hcr.va && allowVAbort)
            return std::make_shared<VirtualDataAbort>(
                0, TlbEntry::DomainType::NoAccess, false,
                ArmFault::AsynchronousExternalAbort);
        if (interrupts[INT_RST])
            return std::make_shared<Reset>();
        if (interrupts[INT_SEV])
            return std::make_shared<ArmSev>();

        panic("intStatus and interrupts not in sync\n");
    }

    void updateIntrInfo() override {} // nothing to do

    void
    serialize(CheckpointOut &cp) const override
    {
        SERIALIZE_ARRAY(interrupts, NumInterruptTypes);
        SERIALIZE_SCALAR(intStatus);
    }

    void
    unserialize(CheckpointIn &cp) override
    {
        UNSERIALIZE_ARRAY(interrupts, NumInterruptTypes);
        UNSERIALIZE_SCALAR(intStatus);
    }
};

} // namespace ARM_ISA
} // namespace gem5

#endif // __ARCH_ARM_INTERRUPT_HH__
