faults.hh revision 5655:74f76480407f
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/misc.hh"
62#include "sim/faults.hh"
63
64namespace X86ISA
65{
66    // Base class for all x86 "faults" where faults is in the m5 sense
67    class X86FaultBase : public FaultBase
68    {
69      protected:
70        const char * faultName;
71        const char * mnem;
72        uint64_t errorCode;
73
74        X86FaultBase(const char * _faultName, const char * _mnem,
75                uint64_t _errorCode = 0) :
76            faultName(_faultName), mnem(_mnem), errorCode(_errorCode)
77        {
78        }
79
80        const char * name() const
81        {
82            return faultName;
83        }
84
85        virtual bool isBenign()
86        {
87            return true;
88        }
89
90        virtual const char * mnemonic() const
91        {
92            return mnem;
93        }
94    };
95
96    // Base class for x86 faults which behave as if the underlying instruction
97    // didn't happen.
98    class X86Fault : public X86FaultBase
99    {
100      protected:
101        X86Fault(const char * name, const char * mnem,
102                uint64_t _errorCode = 0) :
103            X86FaultBase(name, mnem, _errorCode)
104        {}
105    };
106
107    // Base class for x86 traps which behave as if the underlying instruction
108    // completed.
109    class X86Trap : public X86FaultBase
110    {
111      protected:
112        X86Trap(const char * name, const char * mnem,
113                uint64_t _errorCode = 0) :
114            X86FaultBase(name, mnem, _errorCode)
115        {}
116
117#if FULL_SYSTEM
118        void invoke(ThreadContext * tc);
119#endif
120    };
121
122    // Base class for x86 aborts which seem to be catastrophic failures.
123    class X86Abort : public X86FaultBase
124    {
125      protected:
126        X86Abort(const char * name, const char * mnem,
127                uint64_t _errorCode = 0) :
128            X86FaultBase(name, mnem, _errorCode)
129        {}
130
131#if FULL_SYSTEM
132        void invoke(ThreadContext * tc);
133#endif
134    };
135
136    // Base class for x86 interrupts.
137    class X86Interrupt : public X86FaultBase
138    {
139      protected:
140        X86Interrupt(const char * name, const char * mnem,
141                uint64_t _errorCode = 0) :
142            X86FaultBase(name, mnem, _errorCode)
143        {}
144
145#if FULL_SYSTEM
146        void invoke(ThreadContext * tc);
147#endif
148    };
149
150    class UnimpInstFault : public FaultBase
151    {
152      public:
153        const char * name() const
154        {
155            return "unimplemented_micro";
156        }
157
158        void invoke(ThreadContext * tc)
159        {
160            panic("Unimplemented instruction!");
161        }
162    };
163
164    static inline Fault genMachineCheckFault()
165    {
166        panic("Machine check fault not implemented in x86!\n");
167    }
168
169    // Below is a summary of the interrupt/exception information in the
170    // architecture manuals.
171
172    // Class  |  Type    | vector |               Cause                 | mnem
173    //------------------------------------------------------------------------
174    //Contrib   Fault     0         Divide-by-Zero-Error                  #DE
175    //Benign    Either    1         Debug                                 #DB
176    //Benign    Interrupt 2         Non-Maskable-Interrupt                #NMI
177    //Benign    Trap      3         Breakpoint                            #BP
178    //Benign    Trap      4         Overflow                              #OF
179    //Benign    Fault     5         Bound-Range                           #BR
180    //Benign    Fault     6         Invalid-Opcode                        #UD
181    //Benign    Fault     7         Device-Not-Available                  #NM
182    //Benign    Abort     8         Double-Fault                          #DF
183    //                    9         Coprocessor-Segment-Overrun
184    //Contrib   Fault     10        Invalid-TSS                           #TS
185    //Contrib   Fault     11        Segment-Not-Present                   #NP
186    //Contrib   Fault     12        Stack                                 #SS
187    //Contrib   Fault     13        General-Protection                    #GP
188    //Either    Fault     14        Page-Fault                            #PF
189    //                    15        Reserved
190    //Benign    Fault     16        x87 Floating-Point Exception Pending  #MF
191    //Benign    Fault     17        Alignment-Check                       #AC
192    //Benign    Abort     18        Machine-Check                         #MC
193    //Benign    Fault     19        SIMD Floating-Point                   #XF
194    //                    20-29     Reserved
195    //Contrib   ?         30        Security Exception                    #SX
196    //                    31        Reserved
197    //Benign    Interrupt 0-255     External Interrupts                   #INTR
198    //Benign    Interrupt 0-255     Software Interrupts                   INTn
199
200    class DivideByZero : public X86Fault
201    {
202      public:
203        DivideByZero() :
204            X86Fault("Divide-by-Zero-Error", "#DE")
205        {}
206    };
207
208    class DebugException : public X86FaultBase
209    {
210      public:
211        DebugException() :
212            X86FaultBase("Debug", "#DB")
213        {}
214    };
215
216    class NonMaskableInterrupt : public X86Interrupt
217    {
218        uint8_t vector;
219      public:
220        NonMaskableInterrupt(uint8_t _vector) :
221            X86Interrupt("Non Maskable Interrupt", "#NMI"), vector(_vector)
222        {}
223    };
224
225    class Breakpoint : public X86Trap
226    {
227      public:
228        Breakpoint() :
229            X86Trap("Breakpoint", "#BP")
230        {}
231    };
232
233    class OverflowTrap : public X86Trap
234    {
235      public:
236        OverflowTrap() :
237            X86Trap("Overflow", "#OF")
238        {}
239    };
240
241    class BoundRange : public X86Fault
242    {
243      public:
244        BoundRange() :
245            X86Fault("Bound-Range", "#BR")
246        {}
247    };
248
249    class InvalidOpcode : public X86Fault
250    {
251      public:
252        InvalidOpcode() :
253            X86Fault("Invalid-Opcode", "#UD")
254        {}
255    };
256
257    class DeviceNotAvailable : public X86Fault
258    {
259      public:
260        DeviceNotAvailable() :
261            X86Fault("Device-Not-Available", "#NM")
262        {}
263    };
264
265    class DoubleFault : public X86Abort
266    {
267      public:
268        DoubleFault() :
269            X86Abort("Double-Fault", "#DF")
270        {}
271    };
272
273    class InvalidTSS : public X86Fault
274    {
275      public:
276        InvalidTSS() :
277            X86Fault("Invalid-TSS", "#TS")
278        {}
279    };
280
281    class SegmentNotPresent : public X86Fault
282    {
283      public:
284        SegmentNotPresent() :
285            X86Fault("Segment-Not-Present", "#NP")
286        {}
287    };
288
289    class StackFault : public X86Fault
290    {
291      public:
292        StackFault() :
293            X86Fault("Stack", "#SS")
294        {}
295    };
296
297    class GeneralProtection : public X86Fault
298    {
299      public:
300        GeneralProtection(uint64_t _errorCode) :
301            X86Fault("General-Protection", "#GP", _errorCode)
302        {}
303    };
304
305    class PageFault : public X86Fault
306    {
307      public:
308        PageFault() :
309            X86Fault("Page-Fault", "#PF")
310        {}
311    };
312
313    class X87FpExceptionPending : public X86Fault
314    {
315      public:
316        X87FpExceptionPending() :
317            X86Fault("x87 Floating-Point Exception Pending", "#MF")
318        {}
319    };
320
321    class AlignmentCheck : public X86Fault
322    {
323      public:
324        AlignmentCheck() :
325            X86Fault("Alignment-Check", "#AC")
326        {}
327    };
328
329    class MachineCheck : public X86Abort
330    {
331      public:
332        MachineCheck() :
333            X86Abort("Machine-Check", "#MC")
334        {}
335    };
336
337    class SIMDFloatingPointFault : public X86Fault
338    {
339      public:
340        SIMDFloatingPointFault() :
341            X86Fault("SIMD Floating-Point", "#XF")
342        {}
343    };
344
345    class SecurityException : public X86FaultBase
346    {
347      public:
348        SecurityException() :
349            X86FaultBase("Security Exception", "#SX")
350        {}
351    };
352
353    class ExternalInterrupt : public X86Interrupt
354    {
355        uint8_t vector;
356      public:
357        ExternalInterrupt(uint8_t _vector) :
358            X86Interrupt("External Interrupt", "#INTR"), vector(_vector)
359        {}
360    };
361
362    class SystemManagementInterrupt : public X86Interrupt
363    {
364      public:
365        SystemManagementInterrupt() :
366            X86Interrupt("System Management Interrupt", "#SMI")
367        {}
368    };
369
370    class InitInterrupt : public X86Interrupt
371    {
372        uint8_t vector;
373      public:
374        InitInterrupt(uint8_t _vector) :
375            X86Interrupt("INIT Interrupt", "#INIT"), vector(_vector)
376        {}
377    };
378
379    class SoftwareInterrupt : public X86Interrupt
380    {
381      public:
382        SoftwareInterrupt() :
383            X86Interrupt("Software Interrupt", "INTn")
384        {}
385    };
386
387    // These faults aren't part of the ISA definition. They trigger filling
388    // the tlb on a miss and are to take the place of a hardware table walker.
389    class FakeITLBFault : public X86Fault
390    {
391      protected:
392        Addr vaddr;
393      public:
394        FakeITLBFault(Addr _vaddr) :
395            X86Fault("fake instruction tlb fault", "itlb"),
396            vaddr(_vaddr)
397        {}
398
399        void invoke(ThreadContext * tc);
400    };
401
402    class FakeDTLBFault : public X86Fault
403    {
404      protected:
405        Addr vaddr;
406      public:
407        FakeDTLBFault(Addr _vaddr) :
408            X86Fault("fake data tlb fault", "dtlb"),
409            vaddr(_vaddr)
410        {}
411
412        void invoke(ThreadContext * tc);
413    };
414};
415
416#endif // __ARCH_X86_FAULTS_HH__
417