/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * 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.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_FAULTS_HH__
#define __ARCH_X86_FAULTS_HH__

#include <string>

#include "base/bitunion.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
#include "sim/tlb.hh"

namespace X86ISA
{
    // Base class for all x86 "faults" where faults is in the m5 sense
    class X86FaultBase : public FaultBase
    {
      protected:
        const char * faultName;
        const char * mnem;
        uint8_t vector;
        uint64_t errorCode;

        X86FaultBase(const char * _faultName, const char * _mnem,
                     const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
            : faultName(_faultName), mnem(_mnem),
              vector(_vector), errorCode(_errorCode)
        {
        }

        const char * name() const
        {
            return faultName;
        }

        virtual bool isBenign()
        {
            return true;
        }

        virtual const char * mnemonic() const
        {
            return mnem;
        }

        virtual bool isSoft()
        {
            return false;
        }

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);

        virtual std::string describe() const;

      public:
        /**
         * Get the vector of an interrupt.
         *
         * @return interrupt vector number.
         */
        virtual uint8_t getVector() const { return vector; }
    };

    // Base class for x86 faults which behave as if the underlying instruction
    // didn't happen.
    class X86Fault : public X86FaultBase
    {
      protected:
        X86Fault(const char * name, const char * mnem,
                 const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
            : X86FaultBase(name, mnem, vector, _errorCode)
        {}
    };

    // Base class for x86 traps which behave as if the underlying instruction
    // completed.
    class X86Trap : public X86FaultBase
    {
      protected:
        X86Trap(const char * name, const char * mnem,
                const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
            : X86FaultBase(name, mnem, vector, _errorCode)
        {}

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);
    };

    // Base class for x86 aborts which seem to be catastrophic failures.
    class X86Abort : public X86FaultBase
    {
      protected:
        X86Abort(const char * name, const char * mnem,
                const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
            : X86FaultBase(name, mnem, vector, _errorCode)
        {}

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);
    };

    // Base class for x86 interrupts.
    class X86Interrupt : public X86FaultBase
    {
      protected:
        X86Interrupt(const char * name, const char * mnem,
                const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
            : X86FaultBase(name, mnem, _vector, _errorCode)
        {}
    };

    class UnimpInstFault : public FaultBase
    {
      public:
        const char * name() const
        {
            return "unimplemented_micro";
        }

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr)
        {
            panic("Unimplemented instruction!");
        }
    };

    // Below is a summary of the interrupt/exception information in the
    // architecture manuals.

    // Class  |  Type    | vector |               Cause                 | mnem
    //------------------------------------------------------------------------
    //Contrib   Fault     0         Divide-by-Zero-Error                  #DE
    //Benign    Either    1         Debug                                 #DB
    //Benign    Interrupt 2         Non-Maskable-Interrupt                #NMI
    //Benign    Trap      3         Breakpoint                            #BP
    //Benign    Trap      4         Overflow                              #OF
    //Benign    Fault     5         Bound-Range                           #BR
    //Benign    Fault     6         Invalid-Opcode                        #UD
    //Benign    Fault     7         Device-Not-Available                  #NM
    //Benign    Abort     8         Double-Fault                          #DF
    //                    9         Coprocessor-Segment-Overrun
    //Contrib   Fault     10        Invalid-TSS                           #TS
    //Contrib   Fault     11        Segment-Not-Present                   #NP
    //Contrib   Fault     12        Stack                                 #SS
    //Contrib   Fault     13        General-Protection                    #GP
    //Either    Fault     14        Page-Fault                            #PF
    //                    15        Reserved
    //Benign    Fault     16        x87 Floating-Point Exception Pending  #MF
    //Benign    Fault     17        Alignment-Check                       #AC
    //Benign    Abort     18        Machine-Check                         #MC
    //Benign    Fault     19        SIMD Floating-Point                   #XF
    //                    20-29     Reserved
    //Contrib   ?         30        Security Exception                    #SX
    //                    31        Reserved
    //Benign    Interrupt 0-255     External Interrupts                   #INTR
    //Benign    Interrupt 0-255     Software Interrupts                   INTn

    class DivideByZero : public X86Fault
    {
      public:
        DivideByZero() :
            X86Fault("Divide-by-Zero-Error", "#DE", 0)
        {}
    };

    class DebugException : public X86FaultBase
    {
      public:
        DebugException() :
            X86FaultBase("Debug", "#DB", 1)
        {}
    };

    class NonMaskableInterrupt : public X86Interrupt
    {
      public:
        NonMaskableInterrupt(uint8_t _vector) :
            X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector)
        {}
    };

    class Breakpoint : public X86Trap
    {
      public:
        Breakpoint() :
            X86Trap("Breakpoint", "#BP", 3)
        {}
    };

    class OverflowTrap : public X86Trap
    {
      public:
        OverflowTrap() :
            X86Trap("Overflow", "#OF", 4)
        {}
    };

    class BoundRange : public X86Fault
    {
      public:
        BoundRange() :
            X86Fault("Bound-Range", "#BR", 5)
        {}
    };

    class InvalidOpcode : public X86Fault
    {
      public:
        InvalidOpcode() :
            X86Fault("Invalid-Opcode", "#UD", 6)
        {}

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);
    };

    class DeviceNotAvailable : public X86Fault
    {
      public:
        DeviceNotAvailable() :
            X86Fault("Device-Not-Available", "#NM", 7)
        {}
    };

    class DoubleFault : public X86Abort
    {
      public:
        DoubleFault() :
            X86Abort("Double-Fault", "#DF", 8, 0)
        {}
    };

    class InvalidTSS : public X86Fault
    {
      public:
        InvalidTSS(uint32_t _errorCode) :
            X86Fault("Invalid-TSS", "#TS", 10, _errorCode)
        {}
    };

    class SegmentNotPresent : public X86Fault
    {
      public:
        SegmentNotPresent(uint32_t _errorCode) :
            X86Fault("Segment-Not-Present", "#NP", 11, _errorCode)
        {}
    };

    class StackFault : public X86Fault
    {
      public:
        StackFault(uint32_t _errorCode) :
            X86Fault("Stack", "#SS", 12, _errorCode)
        {}
    };

    class GeneralProtection : public X86Fault
    {
      public:
        GeneralProtection(uint32_t _errorCode) :
            X86Fault("General-Protection", "#GP", 13, _errorCode)
        {}
    };

    class PageFault : public X86Fault
    {
      protected:
        BitUnion32(PageFaultErrorCode)
            Bitfield<0> present;
            Bitfield<1> write;
            Bitfield<2> user;
            Bitfield<3> reserved;
            Bitfield<4> fetch;
        EndBitUnion(PageFaultErrorCode)

        Addr addr;

      public:
        PageFault(Addr _addr, uint32_t _errorCode) :
            X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
        {}

        PageFault(Addr _addr, bool present, BaseTLB::Mode mode,
                bool user, bool reserved) :
            X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
        {
            PageFaultErrorCode code = 0;
            code.present = present;
            code.write = (mode == BaseTLB::Write);
            code.user = user;
            code.reserved = reserved;
            code.fetch = (mode == BaseTLB::Execute);
            errorCode = code;
        }

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);

        virtual std::string describe() const;
    };

    class X87FpExceptionPending : public X86Fault
    {
      public:
        X87FpExceptionPending() :
            X86Fault("x87 Floating-Point Exception Pending", "#MF", 16)
        {}
    };

    class AlignmentCheck : public X86Fault
    {
      public:
        AlignmentCheck() :
            X86Fault("Alignment-Check", "#AC", 17, 0)
        {}
    };

    class MachineCheck : public X86Abort
    {
      public:
        MachineCheck() :
            X86Abort("Machine-Check", "#MC", 18)
        {}
    };

    class SIMDFloatingPointFault : public X86Fault
    {
      public:
        SIMDFloatingPointFault() :
            X86Fault("SIMD Floating-Point", "#XF", 19)
        {}
    };

    class SecurityException : public X86FaultBase
    {
      public:
        SecurityException() :
            X86FaultBase("Security Exception", "#SX", 30)
        {}
    };

    class ExternalInterrupt : public X86Interrupt
    {
      public:
        ExternalInterrupt(uint8_t _vector) :
            X86Interrupt("External Interrupt", "#INTR", _vector)
        {}
    };

    class SystemManagementInterrupt : public X86Interrupt
    {
      public:
        SystemManagementInterrupt() :
            X86Interrupt("System Management Interrupt", "#SMI", 0)
        {}
    };

    class InitInterrupt : public X86Interrupt
    {
      public:
        InitInterrupt(uint8_t _vector) :
            X86Interrupt("INIT Interrupt", "#INIT", _vector)
        {}

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);
    };

    class StartupInterrupt : public X86Interrupt
    {
      public:
        StartupInterrupt(uint8_t _vector) :
            X86Interrupt("Startup Interrupt", "#SIPI", _vector)
        {}

        void invoke(ThreadContext * tc,
                StaticInstPtr inst = StaticInst::nullStaticInstPtr);
    };

    class SoftwareInterrupt : public X86Interrupt
    {
      public:
        SoftwareInterrupt(uint8_t _vector) :
            X86Interrupt("Software Interrupt", "#INTR", _vector)
        {}

        bool isSoft()
        {
            return true;
        }
    };
}

#endif // __ARCH_X86_FAULTS_HH__
