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