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