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