faults.hh revision 5881:73c0aaaaf186
19897Sandreas@sandberg.pp.se/* 29897Sandreas@sandberg.pp.se * Copyright (c) 2007 The Hewlett-Packard Development Company 39897Sandreas@sandberg.pp.se * All rights reserved. 49897Sandreas@sandberg.pp.se * 59897Sandreas@sandberg.pp.se * Redistribution and use of this software in source and binary forms, 69897Sandreas@sandberg.pp.se * with or without modification, are permitted provided that the 79897Sandreas@sandberg.pp.se * following conditions are met: 89897Sandreas@sandberg.pp.se * 99897Sandreas@sandberg.pp.se * The software must be used only for Non-Commercial Use which means any 109897Sandreas@sandberg.pp.se * use which is NOT directed to receiving any direct monetary 119897Sandreas@sandberg.pp.se * compensation for, or commercial advantage from such use. Illustrative 129897Sandreas@sandberg.pp.se * examples of non-commercial use are academic research, personal study, 139897Sandreas@sandberg.pp.se * teaching, education and corporate research & development. 149897Sandreas@sandberg.pp.se * Illustrative examples of commercial use are distributing products for 159897Sandreas@sandberg.pp.se * commercial advantage and providing services using the software for 169897Sandreas@sandberg.pp.se * commercial advantage. 179897Sandreas@sandberg.pp.se * 189897Sandreas@sandberg.pp.se * If you wish to use this software or functionality therein that may be 199897Sandreas@sandberg.pp.se * covered by patents for commercial use, please contact: 209897Sandreas@sandberg.pp.se * Director of Intellectual Property Licensing 219897Sandreas@sandberg.pp.se * Office of Strategy and Technology 229897Sandreas@sandberg.pp.se * Hewlett-Packard Company 239897Sandreas@sandberg.pp.se * 1501 Page Mill Road 249897Sandreas@sandberg.pp.se * Palo Alto, California 94304 259897Sandreas@sandberg.pp.se * 269897Sandreas@sandberg.pp.se * Redistributions of source code must retain the above copyright notice, 279897Sandreas@sandberg.pp.se * this list of conditions and the following disclaimer. Redistributions 289897Sandreas@sandberg.pp.se * in binary form must reproduce the above copyright notice, this list of 299897Sandreas@sandberg.pp.se * conditions and the following disclaimer in the documentation and/or 309897Sandreas@sandberg.pp.se * other materials provided with the distribution. Neither the name of 319897Sandreas@sandberg.pp.se * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 3211793Sbrandon.potter@amd.com * contributors may be used to endorse or promote products derived from 3313344Sgabeblack@google.com * this software without specific prior written permission. No right of 3413344Sgabeblack@google.com * sublicense is granted herewith. Derivatives of the software and 359897Sandreas@sandberg.pp.se * output created using the software may be prepared, but only for 369897Sandreas@sandberg.pp.se * Non-Commercial Uses. Derivatives of the software may be shared with 379897Sandreas@sandberg.pp.se * others provided: (i) the others agree to abide by the list of 389897Sandreas@sandberg.pp.se * conditions herein which includes the Non-Commercial Use restrictions; 399897Sandreas@sandberg.pp.se * and (ii) such Derivatives of the software include the above copyright 409897Sandreas@sandberg.pp.se * notice to acknowledge the contribution from this software where 419897Sandreas@sandberg.pp.se * applicable, this list of conditions and the disclaimer below. 429897Sandreas@sandberg.pp.se * 439897Sandreas@sandberg.pp.se * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 449897Sandreas@sandberg.pp.se * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 459897Sandreas@sandberg.pp.se * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 469897Sandreas@sandberg.pp.se * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 479897Sandreas@sandberg.pp.se * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 489897Sandreas@sandberg.pp.se * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 499897Sandreas@sandberg.pp.se * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 509897Sandreas@sandberg.pp.se * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 519897Sandreas@sandberg.pp.se * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5213234Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 539897Sandreas@sandberg.pp.se * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 549897Sandreas@sandberg.pp.se * 559897Sandreas@sandberg.pp.se * Authors: Gabe Black 569897Sandreas@sandberg.pp.se */ 579897Sandreas@sandberg.pp.se 589897Sandreas@sandberg.pp.se#ifndef __ARCH_X86_FAULTS_HH__ 599911Sandreas@sandberg.pp.se#define __ARCH_X86_FAULTS_HH__ 609897Sandreas@sandberg.pp.se 619897Sandreas@sandberg.pp.se#include "base/bitunion.hh" 629897Sandreas@sandberg.pp.se#include "base/misc.hh" 639897Sandreas@sandberg.pp.se#include "sim/faults.hh" 649897Sandreas@sandberg.pp.se 659897Sandreas@sandberg.pp.senamespace X86ISA 669897Sandreas@sandberg.pp.se{ 679897Sandreas@sandberg.pp.se // Base class for all x86 "faults" where faults is in the m5 sense 689897Sandreas@sandberg.pp.se class X86FaultBase : public FaultBase 699897Sandreas@sandberg.pp.se { 709897Sandreas@sandberg.pp.se protected: 719897Sandreas@sandberg.pp.se const char * faultName; 729897Sandreas@sandberg.pp.se const char * mnem; 739897Sandreas@sandberg.pp.se uint8_t vector; 749897Sandreas@sandberg.pp.se uint64_t errorCode; 759897Sandreas@sandberg.pp.se 769911Sandreas@sandberg.pp.se X86FaultBase(const char * _faultName, const char * _mnem, 779897Sandreas@sandberg.pp.se const uint8_t _vector, uint64_t _errorCode = -1) : 789897Sandreas@sandberg.pp.se faultName(_faultName), mnem(_mnem), 799897Sandreas@sandberg.pp.se vector(_vector), errorCode(_errorCode) 809897Sandreas@sandberg.pp.se { 819897Sandreas@sandberg.pp.se } 829897Sandreas@sandberg.pp.se 839897Sandreas@sandberg.pp.se const char * name() const 849897Sandreas@sandberg.pp.se { 859897Sandreas@sandberg.pp.se return faultName; 869897Sandreas@sandberg.pp.se } 879897Sandreas@sandberg.pp.se 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 bool write; 433 bool execute; 434 public: 435 FakeITLBFault(Addr _vaddr, bool _write, bool _execute) : 436 X86Fault("fake instruction tlb fault", "itlb", 0), 437 vaddr(_vaddr), write(_write), execute(_execute) 438 {} 439 440 void invoke(ThreadContext * tc); 441 }; 442 443 class FakeDTLBFault : public X86Fault 444 { 445 protected: 446 Addr vaddr; 447 bool write; 448 bool execute; 449 public: 450 FakeDTLBFault(Addr _vaddr, bool _write, bool _execute) : 451 X86Fault("fake data tlb fault", "dtlb", 0), 452 vaddr(_vaddr), write(_write), execute(_execute) 453 {} 454 455 void invoke(ThreadContext * tc); 456 }; 457}; 458 459#endif // __ARCH_X86_FAULTS_HH__ 460