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