faults.hh revision 5881:73c0aaaaf186
112953Sgabeblack@google.com/*
212953Sgabeblack@google.com * Copyright (c) 2007 The Hewlett-Packard Development Company
312953Sgabeblack@google.com * All rights reserved.
412953Sgabeblack@google.com *
512953Sgabeblack@google.com * Redistribution and use of this software in source and binary forms,
612953Sgabeblack@google.com * with or without modification, are permitted provided that the
712953Sgabeblack@google.com * following conditions are met:
812953Sgabeblack@google.com *
912953Sgabeblack@google.com * The software must be used only for Non-Commercial Use which means any
1012953Sgabeblack@google.com * use which is NOT directed to receiving any direct monetary
1112953Sgabeblack@google.com * compensation for, or commercial advantage from such use.  Illustrative
1212953Sgabeblack@google.com * examples of non-commercial use are academic research, personal study,
1312953Sgabeblack@google.com * teaching, education and corporate research & development.
1412953Sgabeblack@google.com * Illustrative examples of commercial use are distributing products for
1512953Sgabeblack@google.com * commercial advantage and providing services using the software for
1612953Sgabeblack@google.com * commercial advantage.
1712953Sgabeblack@google.com *
1812953Sgabeblack@google.com * If you wish to use this software or functionality therein that may be
1912953Sgabeblack@google.com * covered by patents for commercial use, please contact:
2012953Sgabeblack@google.com *     Director of Intellectual Property Licensing
2112953Sgabeblack@google.com *     Office of Strategy and Technology
2212953Sgabeblack@google.com *     Hewlett-Packard Company
2312953Sgabeblack@google.com *     1501 Page Mill Road
2412953Sgabeblack@google.com *     Palo Alto, California  94304
2512953Sgabeblack@google.com *
2612953Sgabeblack@google.com * Redistributions of source code must retain the above copyright notice,
2712953Sgabeblack@google.com * this list of conditions and the following disclaimer.  Redistributions
2812953Sgabeblack@google.com * in binary form must reproduce the above copyright notice, this list of
2912953Sgabeblack@google.com * conditions and the following disclaimer in the documentation and/or
3012953Sgabeblack@google.com * other materials provided with the distribution.  Neither the name of
3112953Sgabeblack@google.com * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
3212953Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
3312957Sgabeblack@google.com * this software without specific prior written permission.  No right of
3412957Sgabeblack@google.com * sublicense is granted herewith.  Derivatives of the software and
3512961Sgabeblack@google.com * output created using the software may be prepared, but only for
3612954Sgabeblack@google.com * Non-Commercial Uses.  Derivatives of the software may be shared with
3712954Sgabeblack@google.com * others provided: (i) the others agree to abide by the list of
3812953Sgabeblack@google.com * conditions herein which includes the Non-Commercial Use restrictions;
3912953Sgabeblack@google.com * and (ii) such Derivatives of the software include the above copyright
4012953Sgabeblack@google.com * notice to acknowledge the contribution from this software where
4112961Sgabeblack@google.com * applicable, this list of conditions and the disclaimer below.
4212961Sgabeblack@google.com *
4312953Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4412953Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
4512953Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
4612953Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
4712954Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4812954Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4912954Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5012954Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5112954Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5212954Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
5312954Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5412954Sgabeblack@google.com *
5512954Sgabeblack@google.com * Authors: Gabe Black
5612954Sgabeblack@google.com */
5712954Sgabeblack@google.com
5812954Sgabeblack@google.com#ifndef __ARCH_X86_FAULTS_HH__
5912954Sgabeblack@google.com#define __ARCH_X86_FAULTS_HH__
6012954Sgabeblack@google.com
6112954Sgabeblack@google.com#include "base/bitunion.hh"
6212954Sgabeblack@google.com#include "base/misc.hh"
6312954Sgabeblack@google.com#include "sim/faults.hh"
6412954Sgabeblack@google.com
6512954Sgabeblack@google.comnamespace X86ISA
6612957Sgabeblack@google.com{
6712954Sgabeblack@google.com    // Base class for all x86 "faults" where faults is in the m5 sense
6812954Sgabeblack@google.com    class X86FaultBase : public FaultBase
6912954Sgabeblack@google.com    {
7012954Sgabeblack@google.com      protected:
7112954Sgabeblack@google.com        const char * faultName;
7212954Sgabeblack@google.com        const char * mnem;
7312954Sgabeblack@google.com        uint8_t vector;
7412954Sgabeblack@google.com        uint64_t errorCode;
7512954Sgabeblack@google.com
7612954Sgabeblack@google.com        X86FaultBase(const char * _faultName, const char * _mnem,
7712954Sgabeblack@google.com                const uint8_t _vector, uint64_t _errorCode = -1) :
7812954Sgabeblack@google.com            faultName(_faultName), mnem(_mnem),
7912954Sgabeblack@google.com            vector(_vector), errorCode(_errorCode)
8012954Sgabeblack@google.com        {
8112954Sgabeblack@google.com        }
8212954Sgabeblack@google.com
8312954Sgabeblack@google.com        const char * name() const
8412954Sgabeblack@google.com        {
8512954Sgabeblack@google.com            return faultName;
8612954Sgabeblack@google.com        }
8712954Sgabeblack@google.com
8812954Sgabeblack@google.com        virtual bool isBenign()
8912954Sgabeblack@google.com        {
9012954Sgabeblack@google.com            return true;
9112954Sgabeblack@google.com        }
9212954Sgabeblack@google.com
9312954Sgabeblack@google.com        virtual const char * mnemonic() const
9412954Sgabeblack@google.com        {
9512954Sgabeblack@google.com            return mnem;
9612954Sgabeblack@google.com        }
9712954Sgabeblack@google.com
9812954Sgabeblack@google.com        virtual bool isSoft()
9912954Sgabeblack@google.com        {
10012954Sgabeblack@google.com            return false;
10112954Sgabeblack@google.com        }
10212954Sgabeblack@google.com
10312954Sgabeblack@google.com#if FULL_SYSTEM
10412954Sgabeblack@google.com        void invoke(ThreadContext * tc);
10512954Sgabeblack@google.com#endif
10612954Sgabeblack@google.com    };
10712954Sgabeblack@google.com
10812954Sgabeblack@google.com    // Base class for x86 faults which behave as if the underlying instruction
10912954Sgabeblack@google.com    // didn't happen.
11012954Sgabeblack@google.com    class X86Fault : public X86FaultBase
11112961Sgabeblack@google.com    {
11212961Sgabeblack@google.com      protected:
11312961Sgabeblack@google.com        X86Fault(const char * name, const char * mnem,
11412961Sgabeblack@google.com                const uint8_t vector, uint64_t _errorCode = -1) :
11512961Sgabeblack@google.com            X86FaultBase(name, mnem, vector, _errorCode)
11612961Sgabeblack@google.com        {}
11712961Sgabeblack@google.com    };
11812961Sgabeblack@google.com
11912961Sgabeblack@google.com    // Base class for x86 traps which behave as if the underlying instruction
12012961Sgabeblack@google.com    // completed.
12112961Sgabeblack@google.com    class X86Trap : public X86FaultBase
12212961Sgabeblack@google.com    {
12312961Sgabeblack@google.com      protected:
12412961Sgabeblack@google.com        X86Trap(const char * name, const char * mnem,
12512961Sgabeblack@google.com                const uint8_t vector, uint64_t _errorCode = -1) :
12612961Sgabeblack@google.com            X86FaultBase(name, mnem, vector, _errorCode)
12712961Sgabeblack@google.com        {}
12812961Sgabeblack@google.com
12912961Sgabeblack@google.com#if FULL_SYSTEM
13012961Sgabeblack@google.com        void invoke(ThreadContext * tc);
13112961Sgabeblack@google.com#endif
13212961Sgabeblack@google.com    };
13312961Sgabeblack@google.com
13412961Sgabeblack@google.com    // Base class for x86 aborts which seem to be catastrophic failures.
13512961Sgabeblack@google.com    class X86Abort : public X86FaultBase
13612961Sgabeblack@google.com    {
13712954Sgabeblack@google.com      protected:
13812953Sgabeblack@google.com        X86Abort(const char * name, const char * mnem,
13912953Sgabeblack@google.com                const uint8_t vector, uint64_t _errorCode = -1) :
14012953Sgabeblack@google.com            X86FaultBase(name, mnem, vector, _errorCode)
14112953Sgabeblack@google.com        {}
14212953Sgabeblack@google.com
14312953Sgabeblack@google.com#if FULL_SYSTEM
14412954Sgabeblack@google.com        void invoke(ThreadContext * tc);
14512954Sgabeblack@google.com#endif
14612953Sgabeblack@google.com    };
14712953Sgabeblack@google.com
14812953Sgabeblack@google.com    // Base class for x86 interrupts.
14912957Sgabeblack@google.com    class X86Interrupt : public X86FaultBase
15012957Sgabeblack@google.com    {
15112953Sgabeblack@google.com      protected:
15212957Sgabeblack@google.com        X86Interrupt(const char * name, const char * mnem,
15312957Sgabeblack@google.com                const uint8_t _vector, uint64_t _errorCode = -1) :
15412957Sgabeblack@google.com            X86FaultBase(name, mnem, _vector, _errorCode)
15512957Sgabeblack@google.com        {}
15612957Sgabeblack@google.com    };
15712953Sgabeblack@google.com
15812953Sgabeblack@google.com    class UnimpInstFault : public FaultBase
15912953Sgabeblack@google.com    {
16012953Sgabeblack@google.com      public:
16112953Sgabeblack@google.com        const char * name() const
16212954Sgabeblack@google.com        {
16312954Sgabeblack@google.com            return "unimplemented_micro";
16412954Sgabeblack@google.com        }
16512954Sgabeblack@google.com
16612953Sgabeblack@google.com        void invoke(ThreadContext * tc)
16712953Sgabeblack@google.com        {
16812953Sgabeblack@google.com            panic("Unimplemented instruction!");
16912953Sgabeblack@google.com        }
17012953Sgabeblack@google.com    };
17112953Sgabeblack@google.com
17212953Sgabeblack@google.com    static inline Fault genMachineCheckFault()
17312953Sgabeblack@google.com    {
17412953Sgabeblack@google.com        panic("Machine check fault not implemented in x86!\n");
17512953Sgabeblack@google.com    }
17612953Sgabeblack@google.com
17712953Sgabeblack@google.com    // Below is a summary of the interrupt/exception information in the
17812953Sgabeblack@google.com    // architecture manuals.
17912954Sgabeblack@google.com
18012954Sgabeblack@google.com    // Class  |  Type    | vector |               Cause                 | mnem
18112954Sgabeblack@google.com    //------------------------------------------------------------------------
18212962Sgabeblack@google.com    //Contrib   Fault     0         Divide-by-Zero-Error                  #DE
18312962Sgabeblack@google.com    //Benign    Either    1         Debug                                 #DB
18412962Sgabeblack@google.com    //Benign    Interrupt 2         Non-Maskable-Interrupt                #NMI
18512962Sgabeblack@google.com    //Benign    Trap      3         Breakpoint                            #BP
18612962Sgabeblack@google.com    //Benign    Trap      4         Overflow                              #OF
18712962Sgabeblack@google.com    //Benign    Fault     5         Bound-Range                           #BR
18812962Sgabeblack@google.com    //Benign    Fault     6         Invalid-Opcode                        #UD
18912962Sgabeblack@google.com    //Benign    Fault     7         Device-Not-Available                  #NM
19012962Sgabeblack@google.com    //Benign    Abort     8         Double-Fault                          #DF
19112962Sgabeblack@google.com    //                    9         Coprocessor-Segment-Overrun
19212962Sgabeblack@google.com    //Contrib   Fault     10        Invalid-TSS                           #TS
19312962Sgabeblack@google.com    //Contrib   Fault     11        Segment-Not-Present                   #NP
19412962Sgabeblack@google.com    //Contrib   Fault     12        Stack                                 #SS
19512962Sgabeblack@google.com    //Contrib   Fault     13        General-Protection                    #GP
19612962Sgabeblack@google.com    //Either    Fault     14        Page-Fault                            #PF
19712962Sgabeblack@google.com    //                    15        Reserved
19812962Sgabeblack@google.com    //Benign    Fault     16        x87 Floating-Point Exception Pending  #MF
19912962Sgabeblack@google.com    //Benign    Fault     17        Alignment-Check                       #AC
20012962Sgabeblack@google.com    //Benign    Abort     18        Machine-Check                         #MC
20112962Sgabeblack@google.com    //Benign    Fault     19        SIMD Floating-Point                   #XF
20212962Sgabeblack@google.com    //                    20-29     Reserved
20312962Sgabeblack@google.com    //Contrib   ?         30        Security Exception                    #SX
20412962Sgabeblack@google.com    //                    31        Reserved
20512962Sgabeblack@google.com    //Benign    Interrupt 0-255     External Interrupts                   #INTR
20612962Sgabeblack@google.com    //Benign    Interrupt 0-255     Software Interrupts                   INTn
20712962Sgabeblack@google.com
20812962Sgabeblack@google.com    class DivideByZero : public X86Fault
20912962Sgabeblack@google.com    {
21012962Sgabeblack@google.com      public:
21112962Sgabeblack@google.com        DivideByZero() :
21212962Sgabeblack@google.com            X86Fault("Divide-by-Zero-Error", "#DE", 0)
21312962Sgabeblack@google.com        {}
21412962Sgabeblack@google.com    };
21512962Sgabeblack@google.com
21612962Sgabeblack@google.com    class DebugException : public X86FaultBase
21712962Sgabeblack@google.com    {
21812962Sgabeblack@google.com      public:
21912962Sgabeblack@google.com        DebugException() :
22012962Sgabeblack@google.com            X86FaultBase("Debug", "#DB", 1)
22112962Sgabeblack@google.com        {}
22212962Sgabeblack@google.com    };
22312962Sgabeblack@google.com
22412962Sgabeblack@google.com    class NonMaskableInterrupt : public X86Interrupt
22512962Sgabeblack@google.com    {
22612962Sgabeblack@google.com      public:
22712962Sgabeblack@google.com        NonMaskableInterrupt(uint8_t _vector) :
22812962Sgabeblack@google.com            X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector)
22912962Sgabeblack@google.com        {}
23012962Sgabeblack@google.com    };
23112962Sgabeblack@google.com
23212962Sgabeblack@google.com    class Breakpoint : public X86Trap
23312962Sgabeblack@google.com    {
23412962Sgabeblack@google.com      public:
23512962Sgabeblack@google.com        Breakpoint() :
23612962Sgabeblack@google.com            X86Trap("Breakpoint", "#BP", 3)
23712962Sgabeblack@google.com        {}
23812962Sgabeblack@google.com    };
23912962Sgabeblack@google.com
24012962Sgabeblack@google.com    class OverflowTrap : public X86Trap
24112962Sgabeblack@google.com    {
24212962Sgabeblack@google.com      public:
24312962Sgabeblack@google.com        OverflowTrap() :
24412962Sgabeblack@google.com            X86Trap("Overflow", "#OF", 4)
24512962Sgabeblack@google.com        {}
24612962Sgabeblack@google.com    };
24712962Sgabeblack@google.com
24812962Sgabeblack@google.com    class BoundRange : public X86Fault
24912962Sgabeblack@google.com    {
25012962Sgabeblack@google.com      public:
25112954Sgabeblack@google.com        BoundRange() :
25212954Sgabeblack@google.com            X86Fault("Bound-Range", "#BR", 5)
25312954Sgabeblack@google.com        {}
25412954Sgabeblack@google.com    };
25512961Sgabeblack@google.com
25612961Sgabeblack@google.com    class InvalidOpcode : public X86Fault
25712961Sgabeblack@google.com    {
25812961Sgabeblack@google.com      public:
25912961Sgabeblack@google.com        InvalidOpcode() :
26012961Sgabeblack@google.com            X86Fault("Invalid-Opcode", "#UD", 6)
26112961Sgabeblack@google.com        {}
26212961Sgabeblack@google.com    };
26312961Sgabeblack@google.com
26412961Sgabeblack@google.com    class DeviceNotAvailable : public X86Fault
26512953Sgabeblack@google.com    {
26612961Sgabeblack@google.com      public:
26712961Sgabeblack@google.com        DeviceNotAvailable() :
26812961Sgabeblack@google.com            X86Fault("Device-Not-Available", "#NM", 7)
26912961Sgabeblack@google.com        {}
27012961Sgabeblack@google.com    };
27112961Sgabeblack@google.com
27212961Sgabeblack@google.com    class DoubleFault : public X86Abort
27312961Sgabeblack@google.com    {
27412954Sgabeblack@google.com      public:
27512962Sgabeblack@google.com        DoubleFault() :
27612954Sgabeblack@google.com            X86Abort("Double-Fault", "#DF", 8, 0)
27712954Sgabeblack@google.com        {}
27812954Sgabeblack@google.com    };
27912954Sgabeblack@google.com
28012954Sgabeblack@google.com    class InvalidTSS : public X86Fault
28112961Sgabeblack@google.com    {
28212961Sgabeblack@google.com      public:
28312961Sgabeblack@google.com        InvalidTSS(uint32_t _errorCode) :
28412961Sgabeblack@google.com            X86Fault("Invalid-TSS", "#TS", 10, _errorCode)
28512961Sgabeblack@google.com        {}
28612961Sgabeblack@google.com    };
28712961Sgabeblack@google.com
28812961Sgabeblack@google.com    class SegmentNotPresent : public X86Fault
28912961Sgabeblack@google.com    {
29012961Sgabeblack@google.com      public:
29112961Sgabeblack@google.com        SegmentNotPresent(uint32_t _errorCode) :
29212961Sgabeblack@google.com            X86Fault("Segment-Not-Present", "#NP", 11, _errorCode)
29312961Sgabeblack@google.com        {}
29412953Sgabeblack@google.com    };
29512953Sgabeblack@google.com
29612953Sgabeblack@google.com    class StackFault : public X86Fault
29712953Sgabeblack@google.com    {
29812957Sgabeblack@google.com      public:
29912957Sgabeblack@google.com        StackFault(uint32_t _errorCode) :
30012953Sgabeblack@google.com            X86Fault("Stack", "#SS", 12, _errorCode)
30112957Sgabeblack@google.com        {}
30212953Sgabeblack@google.com    };
30312953Sgabeblack@google.com
30412954Sgabeblack@google.com    class GeneralProtection : public X86Fault
30512953Sgabeblack@google.com    {
30612953Sgabeblack@google.com      public:
30712953Sgabeblack@google.com        GeneralProtection(uint32_t _errorCode) :
30812953Sgabeblack@google.com            X86Fault("General-Protection", "#GP", 13, _errorCode)
30912953Sgabeblack@google.com        {}
31012953Sgabeblack@google.com    };
31112953Sgabeblack@google.com
312    class PageFault : public X86Fault
313    {
314      protected:
315        BitUnion32(PageFaultErrorCode)
316            Bitfield<0> present;
317            Bitfield<1> write;
318            Bitfield<2> user;
319            Bitfield<3> reserved;
320            Bitfield<4> fetch;
321        EndBitUnion(PageFaultErrorCode)
322
323        Addr addr;
324
325      public:
326        PageFault(Addr _addr, uint32_t _errorCode) :
327            X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
328        {}
329
330        PageFault(Addr _addr, bool present, bool write,
331                bool user, bool reserved, bool fetch) :
332            X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
333        {
334            PageFaultErrorCode code = 0;
335            code.present = present;
336            code.write = write;
337            code.user = user;
338            code.reserved = reserved;
339            code.fetch = fetch;
340            errorCode = code;
341        }
342
343#if FULL_SYSTEM
344        void invoke(ThreadContext * tc);
345#endif
346    };
347
348    class X87FpExceptionPending : public X86Fault
349    {
350      public:
351        X87FpExceptionPending() :
352            X86Fault("x87 Floating-Point Exception Pending", "#MF", 16)
353        {}
354    };
355
356    class AlignmentCheck : public X86Fault
357    {
358      public:
359        AlignmentCheck() :
360            X86Fault("Alignment-Check", "#AC", 17, 0)
361        {}
362    };
363
364    class MachineCheck : public X86Abort
365    {
366      public:
367        MachineCheck() :
368            X86Abort("Machine-Check", "#MC", 18)
369        {}
370    };
371
372    class SIMDFloatingPointFault : public X86Fault
373    {
374      public:
375        SIMDFloatingPointFault() :
376            X86Fault("SIMD Floating-Point", "#XF", 19)
377        {}
378    };
379
380    class SecurityException : public X86FaultBase
381    {
382      public:
383        SecurityException() :
384            X86FaultBase("Security Exception", "#SX", 30)
385        {}
386    };
387
388    class ExternalInterrupt : public X86Interrupt
389    {
390      public:
391        ExternalInterrupt(uint8_t _vector) :
392            X86Interrupt("External Interrupt", "#INTR", _vector)
393        {}
394    };
395
396    class SystemManagementInterrupt : public X86Interrupt
397    {
398      public:
399        SystemManagementInterrupt() :
400            X86Interrupt("System Management Interrupt", "#SMI", 0)
401        {}
402    };
403
404    class InitInterrupt : public X86Interrupt
405    {
406        uint8_t vector;
407      public:
408        InitInterrupt(uint8_t _vector) :
409            X86Interrupt("INIT Interrupt", "#INIT", _vector)
410        {}
411    };
412
413    class SoftwareInterrupt : public X86Interrupt
414    {
415      public:
416        SoftwareInterrupt(uint8_t _vector) :
417            X86Interrupt("Software Interrupt", "INTn", _vector)
418        {}
419
420        bool isSoft()
421        {
422            return true;
423        }
424    };
425
426    // These faults aren't part of the ISA definition. They trigger filling
427    // the tlb on a miss and are to take the place of a hardware table walker.
428    class FakeITLBFault : public X86Fault
429    {
430      protected:
431        Addr vaddr;
432        bool write;
433        bool execute;
434      public:
435        FakeITLBFault(Addr _vaddr, bool _write, bool _execute) :
436            X86Fault("fake instruction tlb fault", "itlb", 0),
437            vaddr(_vaddr), write(_write), execute(_execute)
438        {}
439
440        void invoke(ThreadContext * tc);
441    };
442
443    class FakeDTLBFault : public X86Fault
444    {
445      protected:
446        Addr vaddr;
447        bool write;
448        bool execute;
449      public:
450        FakeDTLBFault(Addr _vaddr, bool _write, bool _execute) :
451            X86Fault("fake data tlb fault", "dtlb", 0),
452            vaddr(_vaddr), write(_write), execute(_execute)
453        {}
454
455        void invoke(ThreadContext * tc);
456    };
457};
458
459#endif // __ARCH_X86_FAULTS_HH__
460