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