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