faults.hh revision 6023
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 uint8_t vector; 414 public: 415 InitInterrupt(uint8_t _vector) : 416 X86Interrupt("INIT Interrupt", "#INIT", _vector) 417 {} 418 }; 419 420 class SoftwareInterrupt : public X86Interrupt 421 { 422 public: 423 SoftwareInterrupt(uint8_t _vector) : 424 X86Interrupt("Software Interrupt", "#INTR", _vector) 425 {} 426 427 bool isSoft() 428 { 429 return true; 430 } 431 }; 432}; 433 434#endif // __ARCH_X86_FAULTS_HH__ 435