faults.hh revision 6009
16019Shines@cs.fsu.edu/*
26019Shines@cs.fsu.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
36019Shines@cs.fsu.edu * All rights reserved.
46019Shines@cs.fsu.edu *
56019Shines@cs.fsu.edu * Redistribution and use of this software in source and binary forms,
66019Shines@cs.fsu.edu * with or without modification, are permitted provided that the
76019Shines@cs.fsu.edu * following conditions are met:
86019Shines@cs.fsu.edu *
96019Shines@cs.fsu.edu * The software must be used only for Non-Commercial Use which means any
106019Shines@cs.fsu.edu * use which is NOT directed to receiving any direct monetary
116019Shines@cs.fsu.edu * compensation for, or commercial advantage from such use.  Illustrative
126019Shines@cs.fsu.edu * examples of non-commercial use are academic research, personal study,
136019Shines@cs.fsu.edu * teaching, education and corporate research & development.
146019Shines@cs.fsu.edu * Illustrative examples of commercial use are distributing products for
156019Shines@cs.fsu.edu * commercial advantage and providing services using the software for
166019Shines@cs.fsu.edu * commercial advantage.
176019Shines@cs.fsu.edu *
186019Shines@cs.fsu.edu * If you wish to use this software or functionality therein that may be
196019Shines@cs.fsu.edu * covered by patents for commercial use, please contact:
206019Shines@cs.fsu.edu *     Director of Intellectual Property Licensing
216019Shines@cs.fsu.edu *     Office of Strategy and Technology
226019Shines@cs.fsu.edu *     Hewlett-Packard Company
236019Shines@cs.fsu.edu *     1501 Page Mill Road
246019Shines@cs.fsu.edu *     Palo Alto, California  94304
256019Shines@cs.fsu.edu *
266019Shines@cs.fsu.edu * Redistributions of source code must retain the above copyright notice,
276019Shines@cs.fsu.edu * this list of conditions and the following disclaimer.  Redistributions
286019Shines@cs.fsu.edu * in binary form must reproduce the above copyright notice, this list of
296019Shines@cs.fsu.edu * conditions and the following disclaimer in the documentation and/or
306019Shines@cs.fsu.edu * other materials provided with the distribution.  Neither the name of
316019Shines@cs.fsu.edu * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
326019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from
336019Shines@cs.fsu.edu * this software without specific prior written permission.  No right of
346019Shines@cs.fsu.edu * sublicense is granted herewith.  Derivatives of the software and
356019Shines@cs.fsu.edu * output created using the software may be prepared, but only for
366019Shines@cs.fsu.edu * Non-Commercial Uses.  Derivatives of the software may be shared with
376019Shines@cs.fsu.edu * others provided: (i) the others agree to abide by the list of
386019Shines@cs.fsu.edu * conditions herein which includes the Non-Commercial Use restrictions;
396019Shines@cs.fsu.edu * and (ii) such Derivatives of the software include the above copyright
406019Shines@cs.fsu.edu * notice to acknowledge the contribution from this software where
416019Shines@cs.fsu.edu * applicable, this list of conditions and the disclaimer below.
426019Shines@cs.fsu.edu *
436019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
446019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
456019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
466019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
476019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
486019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
496019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
506019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
516019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
526019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
536019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
546019Shines@cs.fsu.edu *
556019Shines@cs.fsu.edu * Authors: Gabe Black
566019Shines@cs.fsu.edu */
576019Shines@cs.fsu.edu
586019Shines@cs.fsu.edu#ifndef __ARCH_X86_FAULTS_HH__
596019Shines@cs.fsu.edu#define __ARCH_X86_FAULTS_HH__
606019Shines@cs.fsu.edu
616019Shines@cs.fsu.edu#include "base/bitunion.hh"
626019Shines@cs.fsu.edu#include "base/misc.hh"
636019Shines@cs.fsu.edu#include "sim/faults.hh"
646019Shines@cs.fsu.edu
656019Shines@cs.fsu.edu#include <string>
666019Shines@cs.fsu.edu
676019Shines@cs.fsu.edunamespace X86ISA
686019Shines@cs.fsu.edu{
696019Shines@cs.fsu.edu    // Base class for all x86 "faults" where faults is in the m5 sense
706019Shines@cs.fsu.edu    class X86FaultBase : public FaultBase
716019Shines@cs.fsu.edu    {
726019Shines@cs.fsu.edu      protected:
736019Shines@cs.fsu.edu        const char * faultName;
746019Shines@cs.fsu.edu        const char * mnem;
756019Shines@cs.fsu.edu        uint8_t vector;
766019Shines@cs.fsu.edu        uint64_t errorCode;
776019Shines@cs.fsu.edu
786019Shines@cs.fsu.edu        X86FaultBase(const char * _faultName, const char * _mnem,
796019Shines@cs.fsu.edu                     const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
806019Shines@cs.fsu.edu            : faultName(_faultName), mnem(_mnem),
816019Shines@cs.fsu.edu              vector(_vector), errorCode(_errorCode)
826019Shines@cs.fsu.edu        {
836019Shines@cs.fsu.edu        }
846019Shines@cs.fsu.edu
856019Shines@cs.fsu.edu        const char * name() const
866019Shines@cs.fsu.edu        {
876019Shines@cs.fsu.edu            return faultName;
886019Shines@cs.fsu.edu        }
896019Shines@cs.fsu.edu
906019Shines@cs.fsu.edu        virtual bool isBenign()
916019Shines@cs.fsu.edu        {
926019Shines@cs.fsu.edu            return true;
936019Shines@cs.fsu.edu        }
946019Shines@cs.fsu.edu
956019Shines@cs.fsu.edu        virtual const char * mnemonic() const
966019Shines@cs.fsu.edu        {
976019Shines@cs.fsu.edu            return mnem;
986019Shines@cs.fsu.edu        }
996019Shines@cs.fsu.edu
1006019Shines@cs.fsu.edu        virtual bool isSoft()
1016019Shines@cs.fsu.edu        {
1026019Shines@cs.fsu.edu            return false;
1036019Shines@cs.fsu.edu        }
1046019Shines@cs.fsu.edu
1056019Shines@cs.fsu.edu#if FULL_SYSTEM
1066019Shines@cs.fsu.edu        void invoke(ThreadContext * tc);
1076019Shines@cs.fsu.edu
1086019Shines@cs.fsu.edu        virtual std::string describe() const;
1096019Shines@cs.fsu.edu#endif
1106019Shines@cs.fsu.edu    };
1116019Shines@cs.fsu.edu
1126019Shines@cs.fsu.edu    // Base class for x86 faults which behave as if the underlying instruction
1136019Shines@cs.fsu.edu    // didn't happen.
1146019Shines@cs.fsu.edu    class X86Fault : public X86FaultBase
1156019Shines@cs.fsu.edu    {
1166019Shines@cs.fsu.edu      protected:
1176019Shines@cs.fsu.edu        X86Fault(const char * name, const char * mnem,
1186019Shines@cs.fsu.edu                 const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
1196019Shines@cs.fsu.edu            : X86FaultBase(name, mnem, vector, _errorCode)
1206019Shines@cs.fsu.edu        {}
1216019Shines@cs.fsu.edu    };
1226019Shines@cs.fsu.edu
1236019Shines@cs.fsu.edu    // Base class for x86 traps which behave as if the underlying instruction
1246019Shines@cs.fsu.edu    // completed.
1256019Shines@cs.fsu.edu    class X86Trap : public X86FaultBase
1266019Shines@cs.fsu.edu    {
1276019Shines@cs.fsu.edu      protected:
1286019Shines@cs.fsu.edu        X86Trap(const char * name, const char * mnem,
1296019Shines@cs.fsu.edu                const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
1306019Shines@cs.fsu.edu            : X86FaultBase(name, mnem, vector, _errorCode)
1316019Shines@cs.fsu.edu        {}
1326019Shines@cs.fsu.edu
1336019Shines@cs.fsu.edu#if FULL_SYSTEM
1346019Shines@cs.fsu.edu        void invoke(ThreadContext * tc);
1356019Shines@cs.fsu.edu#endif
1366019Shines@cs.fsu.edu    };
1376019Shines@cs.fsu.edu
1386019Shines@cs.fsu.edu    // Base class for x86 aborts which seem to be catastrophic failures.
1396019Shines@cs.fsu.edu    class X86Abort : public X86FaultBase
1406019Shines@cs.fsu.edu    {
1416019Shines@cs.fsu.edu      protected:
1426019Shines@cs.fsu.edu        X86Abort(const char * name, const char * mnem,
1436019Shines@cs.fsu.edu                const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
1446019Shines@cs.fsu.edu            : X86FaultBase(name, mnem, vector, _errorCode)
1456019Shines@cs.fsu.edu        {}
1466019Shines@cs.fsu.edu
1476019Shines@cs.fsu.edu#if FULL_SYSTEM
1486019Shines@cs.fsu.edu        void invoke(ThreadContext * tc);
1496019Shines@cs.fsu.edu#endif
1506019Shines@cs.fsu.edu    };
151
152    // Base class for x86 interrupts.
153    class X86Interrupt : public X86FaultBase
154    {
155      protected:
156        X86Interrupt(const char * name, const char * mnem,
157                const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
158            : X86FaultBase(name, mnem, _vector, _errorCode)
159        {}
160    };
161
162    class UnimpInstFault : public FaultBase
163    {
164      public:
165        const char * name() const
166        {
167            return "unimplemented_micro";
168        }
169
170        void invoke(ThreadContext * tc)
171        {
172            panic("Unimplemented instruction!");
173        }
174    };
175
176    static inline Fault genMachineCheckFault()
177    {
178        panic("Machine check fault not implemented in x86!\n");
179    }
180
181    // Below is a summary of the interrupt/exception information in the
182    // architecture manuals.
183
184    // Class  |  Type    | vector |               Cause                 | mnem
185    //------------------------------------------------------------------------
186    //Contrib   Fault     0         Divide-by-Zero-Error                  #DE
187    //Benign    Either    1         Debug                                 #DB
188    //Benign    Interrupt 2         Non-Maskable-Interrupt                #NMI
189    //Benign    Trap      3         Breakpoint                            #BP
190    //Benign    Trap      4         Overflow                              #OF
191    //Benign    Fault     5         Bound-Range                           #BR
192    //Benign    Fault     6         Invalid-Opcode                        #UD
193    //Benign    Fault     7         Device-Not-Available                  #NM
194    //Benign    Abort     8         Double-Fault                          #DF
195    //                    9         Coprocessor-Segment-Overrun
196    //Contrib   Fault     10        Invalid-TSS                           #TS
197    //Contrib   Fault     11        Segment-Not-Present                   #NP
198    //Contrib   Fault     12        Stack                                 #SS
199    //Contrib   Fault     13        General-Protection                    #GP
200    //Either    Fault     14        Page-Fault                            #PF
201    //                    15        Reserved
202    //Benign    Fault     16        x87 Floating-Point Exception Pending  #MF
203    //Benign    Fault     17        Alignment-Check                       #AC
204    //Benign    Abort     18        Machine-Check                         #MC
205    //Benign    Fault     19        SIMD Floating-Point                   #XF
206    //                    20-29     Reserved
207    //Contrib   ?         30        Security Exception                    #SX
208    //                    31        Reserved
209    //Benign    Interrupt 0-255     External Interrupts                   #INTR
210    //Benign    Interrupt 0-255     Software Interrupts                   INTn
211
212    class DivideByZero : public X86Fault
213    {
214      public:
215        DivideByZero() :
216            X86Fault("Divide-by-Zero-Error", "#DE", 0)
217        {}
218    };
219
220    class DebugException : public X86FaultBase
221    {
222      public:
223        DebugException() :
224            X86FaultBase("Debug", "#DB", 1)
225        {}
226    };
227
228    class NonMaskableInterrupt : public X86Interrupt
229    {
230      public:
231        NonMaskableInterrupt(uint8_t _vector) :
232            X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector)
233        {}
234    };
235
236    class Breakpoint : public X86Trap
237    {
238      public:
239        Breakpoint() :
240            X86Trap("Breakpoint", "#BP", 3)
241        {}
242    };
243
244    class OverflowTrap : public X86Trap
245    {
246      public:
247        OverflowTrap() :
248            X86Trap("Overflow", "#OF", 4)
249        {}
250    };
251
252    class BoundRange : public X86Fault
253    {
254      public:
255        BoundRange() :
256            X86Fault("Bound-Range", "#BR", 5)
257        {}
258    };
259
260    class InvalidOpcode : public X86Fault
261    {
262      public:
263        InvalidOpcode() :
264            X86Fault("Invalid-Opcode", "#UD", 6)
265        {}
266    };
267
268    class DeviceNotAvailable : public X86Fault
269    {
270      public:
271        DeviceNotAvailable() :
272            X86Fault("Device-Not-Available", "#NM", 7)
273        {}
274    };
275
276    class DoubleFault : public X86Abort
277    {
278      public:
279        DoubleFault() :
280            X86Abort("Double-Fault", "#DF", 8, 0)
281        {}
282    };
283
284    class InvalidTSS : public X86Fault
285    {
286      public:
287        InvalidTSS(uint32_t _errorCode) :
288            X86Fault("Invalid-TSS", "#TS", 10, _errorCode)
289        {}
290    };
291
292    class SegmentNotPresent : public X86Fault
293    {
294      public:
295        SegmentNotPresent(uint32_t _errorCode) :
296            X86Fault("Segment-Not-Present", "#NP", 11, _errorCode)
297        {}
298    };
299
300    class StackFault : public X86Fault
301    {
302      public:
303        StackFault(uint32_t _errorCode) :
304            X86Fault("Stack", "#SS", 12, _errorCode)
305        {}
306    };
307
308    class GeneralProtection : public X86Fault
309    {
310      public:
311        GeneralProtection(uint32_t _errorCode) :
312            X86Fault("General-Protection", "#GP", 13, _errorCode)
313        {}
314    };
315
316    class PageFault : public X86Fault
317    {
318      protected:
319        BitUnion32(PageFaultErrorCode)
320            Bitfield<0> present;
321            Bitfield<1> write;
322            Bitfield<2> user;
323            Bitfield<3> reserved;
324            Bitfield<4> fetch;
325        EndBitUnion(PageFaultErrorCode)
326
327        Addr addr;
328
329      public:
330        PageFault(Addr _addr, uint32_t _errorCode) :
331            X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
332        {}
333
334        PageFault(Addr _addr, bool present, bool write,
335                bool user, bool reserved, bool fetch) :
336            X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
337        {
338            PageFaultErrorCode code = 0;
339            code.present = present;
340            code.write = write;
341            code.user = user;
342            code.reserved = reserved;
343            code.fetch = fetch;
344            errorCode = code;
345        }
346
347#if FULL_SYSTEM
348        void invoke(ThreadContext * tc);
349
350        virtual std::string describe() const;
351#endif
352    };
353
354    class X87FpExceptionPending : public X86Fault
355    {
356      public:
357        X87FpExceptionPending() :
358            X86Fault("x87 Floating-Point Exception Pending", "#MF", 16)
359        {}
360    };
361
362    class AlignmentCheck : public X86Fault
363    {
364      public:
365        AlignmentCheck() :
366            X86Fault("Alignment-Check", "#AC", 17, 0)
367        {}
368    };
369
370    class MachineCheck : public X86Abort
371    {
372      public:
373        MachineCheck() :
374            X86Abort("Machine-Check", "#MC", 18)
375        {}
376    };
377
378    class SIMDFloatingPointFault : public X86Fault
379    {
380      public:
381        SIMDFloatingPointFault() :
382            X86Fault("SIMD Floating-Point", "#XF", 19)
383        {}
384    };
385
386    class SecurityException : public X86FaultBase
387    {
388      public:
389        SecurityException() :
390            X86FaultBase("Security Exception", "#SX", 30)
391        {}
392    };
393
394    class ExternalInterrupt : public X86Interrupt
395    {
396      public:
397        ExternalInterrupt(uint8_t _vector) :
398            X86Interrupt("External Interrupt", "#INTR", _vector)
399        {}
400    };
401
402    class SystemManagementInterrupt : public X86Interrupt
403    {
404      public:
405        SystemManagementInterrupt() :
406            X86Interrupt("System Management Interrupt", "#SMI", 0)
407        {}
408    };
409
410    class InitInterrupt : public X86Interrupt
411    {
412        uint8_t vector;
413      public:
414        InitInterrupt(uint8_t _vector) :
415            X86Interrupt("INIT Interrupt", "#INIT", _vector)
416        {}
417    };
418
419    class SoftwareInterrupt : public X86Interrupt
420    {
421      public:
422        SoftwareInterrupt(uint8_t _vector) :
423            X86Interrupt("Software Interrupt", "#INTR", _vector)
424        {}
425
426        bool isSoft()
427        {
428            return true;
429        }
430    };
431};
432
433#endif // __ARCH_X86_FAULTS_HH__
434