faults.cc (3572:aa8751395277) | faults.cc (3573:2038a2e549b5) |
---|---|
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 19 unchanged lines hidden (view full) --- 28 * Authors: Gabe Black 29 * Kevin Lim 30 */ 31 32#include <algorithm> 33 34#include "arch/sparc/faults.hh" 35#include "arch/sparc/isa_traits.hh" | 1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 19 unchanged lines hidden (view full) --- 28 * Authors: Gabe Black 29 * Kevin Lim 30 */ 31 32#include <algorithm> 33 34#include "arch/sparc/faults.hh" 35#include "arch/sparc/isa_traits.hh" |
36#include "arch/sparc/process.hh" |
|
36#include "base/bitfield.hh" 37#include "base/trace.hh" | 37#include "base/bitfield.hh" 38#include "base/trace.hh" |
38#include "config/full_system.hh" | |
39#include "cpu/base.hh" 40#include "cpu/thread_context.hh" 41#if !FULL_SYSTEM | 39#include "cpu/base.hh" 40#include "cpu/thread_context.hh" 41#if !FULL_SYSTEM |
42#include "arch/sparc/process.hh" | |
43#include "mem/page_table.hh" 44#include "sim/process.hh" 45#endif 46 47using namespace std; 48 49namespace SparcISA 50{ 51 | 42#include "mem/page_table.hh" 43#include "sim/process.hh" 44#endif 45 46using namespace std; 47 48namespace SparcISA 49{ 50 |
52FaultName InternalProcessorError::_name = "intprocerr"; 53TrapType InternalProcessorError::_trapType = 0x029; 54FaultPriority InternalProcessorError::_priority = 4; 55FaultStat InternalProcessorError::_count; | 51template<> SparcFaultBase::FaultVals 52 SparcFault<InternalProcessorError>::vals = {"intprocerr", 0x029, 4}; |
56 | 53 |
57FaultName MemAddressNotAligned::_name = "unalign"; 58TrapType MemAddressNotAligned::_trapType = 0x034; 59FaultPriority MemAddressNotAligned::_priority = 10; 60FaultStat MemAddressNotAligned::_count; | 54template<> SparcFaultBase::FaultVals 55 SparcFault<MemAddressNotAligned>::vals = {"unalign", 0x034, 10}; |
61 | 56 |
62FaultName PowerOnReset::_name = "pow_reset"; 63TrapType PowerOnReset::_trapType = 0x001; 64FaultPriority PowerOnReset::_priority = 0; 65FaultStat PowerOnReset::_count; | 57template<> SparcFaultBase::FaultVals 58 SparcFault<PowerOnReset>::vals = {"pow_reset", 0x001, 0}; |
66 | 59 |
67FaultName WatchDogReset::_name = "watch_dog_reset"; 68TrapType WatchDogReset::_trapType = 0x002; 69FaultPriority WatchDogReset::_priority = 1; 70FaultStat WatchDogReset::_count; | 60template<> SparcFaultBase::FaultVals 61 SparcFault<WatchDogReset>::vals = {"watch_dog_reset", 0x002, 1}; |
71 | 62 |
72FaultName ExternallyInitiatedReset::_name = "extern_reset"; 73TrapType ExternallyInitiatedReset::_trapType = 0x003; 74FaultPriority ExternallyInitiatedReset::_priority = 1; 75FaultStat ExternallyInitiatedReset::_count; | 63template<> SparcFaultBase::FaultVals 64 SparcFault<ExternallyInitiatedReset>::vals = {"extern_reset", 0x003, 1}; |
76 | 65 |
77FaultName SoftwareInitiatedReset::_name = "software_reset"; 78TrapType SoftwareInitiatedReset::_trapType = 0x004; 79FaultPriority SoftwareInitiatedReset::_priority = 1; 80FaultStat SoftwareInitiatedReset::_count; | 66template<> SparcFaultBase::FaultVals 67 SparcFault<SoftwareInitiatedReset>::vals = {"software_reset", 0x004, 1}; |
81 | 68 |
82FaultName REDStateException::_name = "red_counte"; 83TrapType REDStateException::_trapType = 0x005; 84FaultPriority REDStateException::_priority = 1; 85FaultStat REDStateException::_count; | 69template<> SparcFaultBase::FaultVals 70 SparcFault<REDStateException>::vals = {"red_counte", 0x005, 1}; |
86 | 71 |
87FaultName InstructionAccessException::_name = "inst_access"; 88TrapType InstructionAccessException::_trapType = 0x008; 89FaultPriority InstructionAccessException::_priority = 5; 90FaultStat InstructionAccessException::_count; | 72template<> SparcFaultBase::FaultVals 73 SparcFault<InstructionAccessException>::vals = {"inst_access", 0x008, 5}; |
91 | 74 |
92FaultName InstructionAccessMMUMiss::_name = "inst_mmu"; 93TrapType InstructionAccessMMUMiss::_trapType = 0x009; 94FaultPriority InstructionAccessMMUMiss::_priority = 2; 95FaultStat InstructionAccessMMUMiss::_count; | 75template<> SparcFaultBase::FaultVals 76 SparcFault<InstructionAccessMMUMiss>::vals = {"inst_mmu", 0x009, 2}; |
96 | 77 |
97FaultName InstructionAccessError::_name = "inst_error"; 98TrapType InstructionAccessError::_trapType = 0x00A; 99FaultPriority InstructionAccessError::_priority = 3; 100FaultStat InstructionAccessError::_count; | 78template<> SparcFaultBase::FaultVals 79 SparcFault<InstructionAccessError>::vals = {"inst_error", 0x00A, 3}; |
101 | 80 |
102FaultName IllegalInstruction::_name = "illegal_inst"; 103TrapType IllegalInstruction::_trapType = 0x010; 104FaultPriority IllegalInstruction::_priority = 7; 105FaultStat IllegalInstruction::_count; | 81template<> SparcFaultBase::FaultVals 82 SparcFault<IllegalInstruction>::vals = {"illegal_inst", 0x010, 7}; |
106 | 83 |
107FaultName PrivilegedOpcode::_name = "priv_opcode"; 108TrapType PrivilegedOpcode::_trapType = 0x011; 109FaultPriority PrivilegedOpcode::_priority = 6; 110FaultStat PrivilegedOpcode::_count; | 84template<> SparcFaultBase::FaultVals 85 SparcFault<PrivilegedOpcode>::vals = {"priv_opcode", 0x011, 6}; |
111 | 86 |
112FaultName UnimplementedLDD::_name = "unimp_ldd"; 113TrapType UnimplementedLDD::_trapType = 0x012; 114FaultPriority UnimplementedLDD::_priority = 6; 115FaultStat UnimplementedLDD::_count; | 87template<> SparcFaultBase::FaultVals 88 SparcFault<UnimplementedLDD>::vals = {"unimp_ldd", 0x012, 6}; |
116 | 89 |
117FaultName UnimplementedSTD::_name = "unimp_std"; 118TrapType UnimplementedSTD::_trapType = 0x013; 119FaultPriority UnimplementedSTD::_priority = 6; 120FaultStat UnimplementedSTD::_count; | 90template<> SparcFaultBase::FaultVals 91 SparcFault<UnimplementedSTD>::vals = {"unimp_std", 0x013, 6}; |
121 | 92 |
122FaultName FpDisabled::_name = "fp_disabled"; 123TrapType FpDisabled::_trapType = 0x020; 124FaultPriority FpDisabled::_priority = 8; 125FaultStat FpDisabled::_count; | 93template<> SparcFaultBase::FaultVals 94 SparcFault<FpDisabled>::vals = {"fp_disabled", 0x020, 8}; |
126 | 95 |
127FaultName FpExceptionIEEE754::_name = "fp_754"; 128TrapType FpExceptionIEEE754::_trapType = 0x021; 129FaultPriority FpExceptionIEEE754::_priority = 11; 130FaultStat FpExceptionIEEE754::_count; | 96template<> SparcFaultBase::FaultVals 97 SparcFault<FpExceptionIEEE754>::vals = {"fp_754", 0x021, 11}; |
131 | 98 |
132FaultName FpExceptionOther::_name = "fp_other"; 133TrapType FpExceptionOther::_trapType = 0x022; 134FaultPriority FpExceptionOther::_priority = 11; 135FaultStat FpExceptionOther::_count; | 99template<> SparcFaultBase::FaultVals 100 SparcFault<FpExceptionOther>::vals = {"fp_other", 0x022, 11}; |
136 | 101 |
137FaultName TagOverflow::_name = "tag_overflow"; 138TrapType TagOverflow::_trapType = 0x023; 139FaultPriority TagOverflow::_priority = 14; 140FaultStat TagOverflow::_count; | 102template<> SparcFaultBase::FaultVals 103 SparcFault<TagOverflow>::vals = {"tag_overflow", 0x023, 14}; |
141 | 104 |
142FaultName DivisionByZero::_name = "div_by_zero"; 143TrapType DivisionByZero::_trapType = 0x028; 144FaultPriority DivisionByZero::_priority = 15; 145FaultStat DivisionByZero::_count; | 105template<> SparcFaultBase::FaultVals 106 SparcFault<DivisionByZero>::vals = {"div_by_zero", 0x028, 15}; |
146 | 107 |
147FaultName DataAccessException::_name = "data_access"; 148TrapType DataAccessException::_trapType = 0x030; 149FaultPriority DataAccessException::_priority = 12; 150FaultStat DataAccessException::_count; | 108template<> SparcFaultBase::FaultVals 109 SparcFault<DataAccessException>::vals = {"data_access", 0x030, 12}; |
151 | 110 |
152FaultName DataAccessMMUMiss::_name = "data_mmu"; 153TrapType DataAccessMMUMiss::_trapType = 0x031; 154FaultPriority DataAccessMMUMiss::_priority = 12; 155FaultStat DataAccessMMUMiss::_count; | 111template<> SparcFaultBase::FaultVals 112 SparcFault<DataAccessMMUMiss>::vals = {"data_mmu", 0x031, 12}; |
156 | 113 |
157FaultName DataAccessError::_name = "data_error"; 158TrapType DataAccessError::_trapType = 0x032; 159FaultPriority DataAccessError::_priority = 12; 160FaultStat DataAccessError::_count; | 114template<> SparcFaultBase::FaultVals 115 SparcFault<DataAccessError>::vals = {"data_error", 0x032, 12}; |
161 | 116 |
162FaultName DataAccessProtection::_name = "data_protection"; 163TrapType DataAccessProtection::_trapType = 0x033; 164FaultPriority DataAccessProtection::_priority = 12; 165FaultStat DataAccessProtection::_count; | 117template<> SparcFaultBase::FaultVals 118 SparcFault<DataAccessProtection>::vals = {"data_protection", 0x033, 12}; |
166 | 119 |
167FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf"; 168TrapType LDDFMemAddressNotAligned::_trapType = 0x035; 169FaultPriority LDDFMemAddressNotAligned::_priority = 10; 170FaultStat LDDFMemAddressNotAligned::_count; | 120template<> SparcFaultBase::FaultVals 121 SparcFault<LDDFMemAddressNotAligned>::vals = {"unalign_lddf", 0x035, 10}; |
171 | 122 |
172FaultName STDFMemAddressNotAligned::_name = "unalign_stdf"; 173TrapType STDFMemAddressNotAligned::_trapType = 0x036; 174FaultPriority STDFMemAddressNotAligned::_priority = 10; 175FaultStat STDFMemAddressNotAligned::_count; | 123template<> SparcFaultBase::FaultVals 124 SparcFault<STDFMemAddressNotAligned>::vals = {"unalign_stdf", 0x036, 10}; |
176 | 125 |
177FaultName PrivilegedAction::_name = "priv_action"; 178TrapType PrivilegedAction::_trapType = 0x037; 179FaultPriority PrivilegedAction::_priority = 11; 180FaultStat PrivilegedAction::_count; | 126template<> SparcFaultBase::FaultVals 127 SparcFault<PrivilegedAction>::vals = {"priv_action", 0x037, 11}; |
181 | 128 |
182FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf"; 183TrapType LDQFMemAddressNotAligned::_trapType = 0x038; 184FaultPriority LDQFMemAddressNotAligned::_priority = 10; 185FaultStat LDQFMemAddressNotAligned::_count; | 129template<> SparcFaultBase::FaultVals 130 SparcFault<LDQFMemAddressNotAligned>::vals = {"unalign_ldqf", 0x038, 10}; |
186 | 131 |
187FaultName STQFMemAddressNotAligned::_name = "unalign_stqf"; 188TrapType STQFMemAddressNotAligned::_trapType = 0x039; 189FaultPriority STQFMemAddressNotAligned::_priority = 10; 190FaultStat STQFMemAddressNotAligned::_count; | 132template<> SparcFaultBase::FaultVals 133 SparcFault<STQFMemAddressNotAligned>::vals = {"unalign_stqf", 0x039, 10}; |
191 | 134 |
192FaultName AsyncDataError::_name = "async_data"; 193TrapType AsyncDataError::_trapType = 0x040; 194FaultPriority AsyncDataError::_priority = 2; 195FaultStat AsyncDataError::_count; | 135template<> SparcFaultBase::FaultVals 136 SparcFault<AsyncDataError>::vals = {"async_data", 0x040, 2}; |
196 | 137 |
197FaultName CleanWindow::_name = "clean_win"; 198TrapType CleanWindow::_trapType = 0x024; 199FaultPriority CleanWindow::_priority = 10; 200FaultStat CleanWindow::_count; | 138template<> SparcFaultBase::FaultVals 139 SparcFault<CleanWindow>::vals = {"clean_win", 0x024, 10}; |
201 202//The enumerated faults 203 | 140 141//The enumerated faults 142 |
204FaultName InterruptLevelN::_name = "interrupt_n"; 205TrapType InterruptLevelN::_baseTrapType = 0x041; 206FaultStat InterruptLevelN::_count; | 143template<> SparcFaultBase::FaultVals 144 SparcFault<InterruptLevelN>::vals = {"interrupt_n", 0x041, 0}; |
207 | 145 |
208FaultName SpillNNormal::_name = "spill_n_normal"; 209TrapType SpillNNormal::_baseTrapType = 0x080; 210FaultPriority SpillNNormal::_priority = 9; 211FaultStat SpillNNormal::_count; | 146template<> SparcFaultBase::FaultVals 147 SparcFault<SpillNNormal>::vals = {"spill_n_normal", 0x080, 9}; |
212 | 148 |
213FaultName SpillNOther::_name = "spill_n_other"; 214TrapType SpillNOther::_baseTrapType = 0x0A0; 215FaultPriority SpillNOther::_priority = 9; 216FaultStat SpillNOther::_count; | 149template<> SparcFaultBase::FaultVals 150 SparcFault<SpillNOther>::vals = {"spill_n_other", 0x0A0, 9}; |
217 | 151 |
218FaultName FillNNormal::_name = "fill_n_normal"; 219TrapType FillNNormal::_baseTrapType = 0x0C0; 220FaultPriority FillNNormal::_priority = 9; 221FaultStat FillNNormal::_count; | 152template<> SparcFaultBase::FaultVals 153 SparcFault<FillNNormal>::vals = {"fill_n_normal", 0x0C0, 9}; |
222 | 154 |
223FaultName FillNOther::_name = "fill_n_other"; 224TrapType FillNOther::_baseTrapType = 0x0E0; 225FaultPriority FillNOther::_priority = 9; 226FaultStat FillNOther::_count; | 155template<> SparcFaultBase::FaultVals 156 SparcFault<FillNOther>::vals = {"fill_n_other", 0x0E0, 9}; |
227 | 157 |
228FaultName TrapInstruction::_name = "trap_inst_n"; 229TrapType TrapInstruction::_baseTrapType = 0x100; 230FaultPriority TrapInstruction::_priority = 16; 231FaultStat TrapInstruction::_count; | 158template<> SparcFaultBase::FaultVals 159 SparcFault<TrapInstruction>::vals = {"trap_inst_n", 0x100, 16}; |
232 233#if !FULL_SYSTEM | 160 161#if !FULL_SYSTEM |
234FaultName PageTableFault::_name = "page_table_fault"; 235TrapType PageTableFault::_trapType = 0x0000; 236FaultPriority PageTableFault::_priority = 0; 237FaultStat PageTableFault::_count; | 162template<> SparcFaultBase::FaultVals 163 SparcFault<PageTableFault>::vals = {"page_table_fault", 0x0000, 0}; |
238#endif 239 240/** 241 * This sets everything up for a normal trap except for actually jumping to 242 * the handler. It will need to be expanded to include the state machine in 243 * the manual. Right now it assumes that traps will always be to the 244 * privileged level. 245 */ --- 40 unchanged lines hidden (view full) --- 286 //set HTSTATE.hpstate to hpstate 287 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 288 289 //TT = trap type; 290 tc->setMiscReg(MISCREG_TT, tt); 291 292 //Update the global register level 293 if(1/*We're delivering the trap in priveleged mode*/) | 164#endif 165 166/** 167 * This sets everything up for a normal trap except for actually jumping to 168 * the handler. It will need to be expanded to include the state machine in 169 * the manual. Right now it assumes that traps will always be to the 170 * privileged level. 171 */ --- 40 unchanged lines hidden (view full) --- 212 //set HTSTATE.hpstate to hpstate 213 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 214 215 //TT = trap type; 216 tc->setMiscReg(MISCREG_TT, tt); 217 218 //Update the global register level 219 if(1/*We're delivering the trap in priveleged mode*/) |
294 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); | 220 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL)); |
295 else | 221 else |
296 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL)); | 222 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL)); |
297 298 //PSTATE.mm is unchanged 299 //PSTATE.pef = whether or not an fpu is present 300 //XXX We'll say there's one present, even though there aren't 301 //implementations for a decent number of the instructions 302 PSTATE |= (1 << 4); 303 //PSTATE.am = 0 304 PSTATE &= ~(1 << 3); --- 44 unchanged lines hidden (view full) --- 349 { 350 CWP = (CWP + NWindows) % NWindows; 351 tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 352 } 353} 354 355#if FULL_SYSTEM 356 | 223 224 //PSTATE.mm is unchanged 225 //PSTATE.pef = whether or not an fpu is present 226 //XXX We'll say there's one present, even though there aren't 227 //implementations for a decent number of the instructions 228 PSTATE |= (1 << 4); 229 //PSTATE.am = 0 230 PSTATE &= ~(1 << 3); --- 44 unchanged lines hidden (view full) --- 275 { 276 CWP = (CWP + NWindows) % NWindows; 277 tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 278 } 279} 280 281#if FULL_SYSTEM 282 |
357void SparcFault::invoke(ThreadContext * tc) | 283void SparcFaultBase::invoke(ThreadContext * tc) |
358{ 359 FaultBase::invoke(tc); 360 countStat()++; 361 362 //Use the SPARC trap state machine | 284{ 285 FaultBase::invoke(tc); 286 countStat()++; 287 288 //Use the SPARC trap state machine |
363} | 289 /*// exception restart address 290 if (setRestartAddress() || !tc->inPalMode()) 291 tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc); |
364 | 292 |
365void PowerOnReset::invoke(ThreadContext * tc) 366{ 367 //For SPARC, when a system is first started, there is a power 368 //on reset Trap which sets the processor into the following state. 369 //Bits that aren't set aren't defined on startup. 370 /* 371 tl = MaxTL; 372 gl = MaxGL; | 293 if (skipFaultingInstruction()) { 294 // traps... skip faulting instruction. 295 tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, 296 tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); 297 } |
373 | 298 |
374 tickFields.counter = 0; //The TICK register is unreadable bya 375 tickFields.npt = 1; //The TICK register is unreadable by by !priv | 299 if (!tc->inPalMode()) 300 AlphaISA::swap_palshadow(&(tc->regs), true); |
376 | 301 |
377 softint = 0; // Clear all the soft interrupt bits 378 tick_cmprFields.int_dis = 1; // disable timer compare interrupts 379 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 380 stickFields.npt = 1; //The TICK register is unreadable by by !priv 381 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 382 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 383 384 tt[tl] = _trapType; 385 pstate = 0; // fields 0 but pef 386 pstateFields.pef = 1; 387 388 hpstate = 0; 389 hpstateFields.red = 1; 390 hpstateFields.hpriv = 1; 391 hpstateFields.tlz = 0; // this is a guess 392 hintp = 0; // no interrupts pending 393 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 394 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 395 */ | 302 tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); 303 tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/ |
396} 397 398#endif 399 400#if !FULL_SYSTEM 401 | 304} 305 306#endif 307 308#if !FULL_SYSTEM 309 |
310void TrapInstruction::invoke(ThreadContext * tc) 311{ 312 // Should be handled in ISA. 313} 314 |
|
402void SpillNNormal::invoke(ThreadContext *tc) 403{ 404 doNormalFault(tc, trapType()); 405 406 Process *p = tc->getProcessPtr(); 407 408 //This will only work in faults from a SparcLiveProcess 409 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); --- 50 unchanged lines hidden --- | 315void SpillNNormal::invoke(ThreadContext *tc) 316{ 317 doNormalFault(tc, trapType()); 318 319 Process *p = tc->getProcessPtr(); 320 321 //This will only work in faults from a SparcLiveProcess 322 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); --- 50 unchanged lines hidden --- |