faults.hh revision 6009
1/*
2 * Copyright (c) 2007 The Hewlett-Packard Development Company
3 * All rights reserved.
4 *
5 * Redistribution and use of this software in source and binary forms,
6 * with or without modification, are permitted provided that the
7 * following conditions are met:
8 *
9 * The software must be used only for Non-Commercial Use which means any
10 * use which is NOT directed to receiving any direct monetary
11 * compensation for, or commercial advantage from such use.  Illustrative
12 * examples of non-commercial use are academic research, personal study,
13 * teaching, education and corporate research & development.
14 * Illustrative examples of commercial use are distributing products for
15 * commercial advantage and providing services using the software for
16 * commercial advantage.
17 *
18 * If you wish to use this software or functionality therein that may be
19 * covered by patents for commercial use, please contact:
20 *     Director of Intellectual Property Licensing
21 *     Office of Strategy and Technology
22 *     Hewlett-Packard Company
23 *     1501 Page Mill Road
24 *     Palo Alto, California  94304
25 *
26 * Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer.  Redistributions
28 * in binary form must reproduce the above copyright notice, this list of
29 * conditions and the following disclaimer in the documentation and/or
30 * other materials provided with the distribution.  Neither the name of
31 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
32 * contributors may be used to endorse or promote products derived from
33 * this software without specific prior written permission.  No right of
34 * sublicense is granted herewith.  Derivatives of the software and
35 * output created using the software may be prepared, but only for
36 * Non-Commercial Uses.  Derivatives of the software may be shared with
37 * others provided: (i) the others agree to abide by the list of
38 * conditions herein which includes the Non-Commercial Use restrictions;
39 * and (ii) such Derivatives of the software include the above copyright
40 * notice to acknowledge the contribution from this software where
41 * applicable, this list of conditions and the disclaimer below.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 *
55 * Authors: Gabe Black
56 */
57
58#ifndef __ARCH_X86_FAULTS_HH__
59#define __ARCH_X86_FAULTS_HH__
60
61#include "base/bitunion.hh"
62#include "base/misc.hh"
63#include "sim/faults.hh"
64
65#include <string>
66
67namespace X86ISA
68{
69    // Base class for all x86 "faults" where faults is in the m5 sense
70    class X86FaultBase : public FaultBase
71    {
72      protected:
73        const char * faultName;
74        const char * mnem;
75        uint8_t vector;
76        uint64_t errorCode;
77
78        X86FaultBase(const char * _faultName, const char * _mnem,
79                     const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
80            : faultName(_faultName), mnem(_mnem),
81              vector(_vector), errorCode(_errorCode)
82        {
83        }
84
85        const char * name() const
86        {
87            return faultName;
88        }
89
90        virtual bool isBenign()
91        {
92            return true;
93        }
94
95        virtual const char * mnemonic() const
96        {
97            return mnem;
98        }
99
100        virtual bool isSoft()
101        {
102            return false;
103        }
104
105#if FULL_SYSTEM
106        void invoke(ThreadContext * tc);
107
108        virtual std::string describe() const;
109#endif
110    };
111
112    // Base class for x86 faults which behave as if the underlying instruction
113    // didn't happen.
114    class X86Fault : public X86FaultBase
115    {
116      protected:
117        X86Fault(const char * name, const char * mnem,
118                 const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
119            : X86FaultBase(name, mnem, vector, _errorCode)
120        {}
121    };
122
123    // Base class for x86 traps which behave as if the underlying instruction
124    // completed.
125    class X86Trap : public X86FaultBase
126    {
127      protected:
128        X86Trap(const char * name, const char * mnem,
129                const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
130            : X86FaultBase(name, mnem, vector, _errorCode)
131        {}
132
133#if FULL_SYSTEM
134        void invoke(ThreadContext * tc);
135#endif
136    };
137
138    // Base class for x86 aborts which seem to be catastrophic failures.
139    class X86Abort : public X86FaultBase
140    {
141      protected:
142        X86Abort(const char * name, const char * mnem,
143                const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
144            : X86FaultBase(name, mnem, vector, _errorCode)
145        {}
146
147#if FULL_SYSTEM
148        void invoke(ThreadContext * tc);
149#endif
150    };
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