From eab445e1bc6178bdbd0f4b5fcd5746a84687de65 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 03:44:39 -0500 Subject: Get rid of old, commented out code. --HG-- extra : convert_revision : 46e9f26917efab642b80ea9e4303ec95d43d935e --- src/arch/sparc/faults.cc | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 2c8da44c5..567ca5f5c 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -359,21 +359,6 @@ void SparcFault::invoke(ThreadContext * tc) countStat()++; //Use the SPARC trap state machine - /*// exception restart address - if (setRestartAddress() || !tc->inPalMode()) - tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc); - - if (skipFaultingInstruction()) { - // traps... skip faulting instruction. - tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, - tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); - } - - if (!tc->inPalMode()) - AlphaISA::swap_palshadow(&(tc->regs), true); - - tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); - tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/ } #endif -- cgit v1.2.3 From 694323b7c4922d0591598a0a501ff17f312c5307 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 10:54:34 -0500 Subject: Move around misc reg code src/arch/sparc/faults.cc: Moved some code here from miscregfile.cc src/arch/sparc/miscregfile.cc: Moved code from here to faults.cc, and merged (read|set)MiscRegWithEffect and it's FS version from ua2005.cc src/arch/sparc/miscregfile.hh: readFSRegWithEffect is no longer a seperate function, and is instead done in the main readRegWith Effect. --HG-- extra : convert_revision : 0b45f0f78e83929b32ddd2f443c8b1dbf9bc04fb --- src/arch/sparc/faults.cc | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 567ca5f5c..6bca6adc5 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -33,12 +33,13 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" -#include "arch/sparc/process.hh" #include "base/bitfield.hh" #include "base/trace.hh" +#include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #if !FULL_SYSTEM +#include "arch/sparc/process.hh" #include "mem/page_table.hh" #include "sim/process.hh" #endif @@ -361,6 +362,39 @@ void SparcFault::invoke(ThreadContext * tc) //Use the SPARC trap state machine } +void PowerOnReset::invoke(ThreadContext * tc) +{ + //For SPARC, when a system is first started, there is a power + //on reset Trap which sets the processor into the following state. + //Bits that aren't set aren't defined on startup. + /* + tl = MaxTL; + gl = MaxGL; + + tickFields.counter = 0; //The TICK register is unreadable bya + tickFields.npt = 1; //The TICK register is unreadable by by !priv + + softint = 0; // Clear all the soft interrupt bits + tick_cmprFields.int_dis = 1; // disable timer compare interrupts + tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + stickFields.npt = 1; //The TICK register is unreadable by by !priv + stick_cmprFields.int_dis = 1; // disable timer compare interrupts + stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + + tt[tl] = _trapType; + pstate = 0; // fields 0 but pef + pstateFields.pef = 1; + + hpstate = 0; + hpstateFields.red = 1; + hpstateFields.hpriv = 1; + hpstateFields.tlz = 0; // this is a guess + hintp = 0; // no interrupts pending + hstick_cmprFields.int_dis = 1; // disable timer compare interrupts + hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + */ +} + #endif #if !FULL_SYSTEM -- cgit v1.2.3 From 6ad386f1a8df96c9679dcffb326420b240e98c05 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 14:40:35 -0500 Subject: Calling syscalls from within the trap instruction's invoke method won't work because apparently you need an xc for that and not a tc. Cleaned up the TrapInstruction fault in light of this. --HG-- extra : convert_revision : 1805c9244cfd62d0ee7862d8fd7c9983e00c5747 --- src/arch/sparc/faults.cc | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 6bca6adc5..da7fc730d 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -399,11 +399,6 @@ void PowerOnReset::invoke(ThreadContext * tc) #if !FULL_SYSTEM -void TrapInstruction::invoke(ThreadContext * tc) -{ - // Should be handled in ISA. -} - void SpillNNormal::invoke(ThreadContext *tc) { doNormalFault(tc, trapType()); -- cgit v1.2.3 From f0c4d3664930f28229c7e336c4d4372b2e1d4c21 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 04:18:15 -0500 Subject: The new global level is computed with min, not max. --HG-- extra : convert_revision : 6339c82d3655694445c3eb43e467b9aa6b4c8224 --- src/arch/sparc/faults.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index da7fc730d..1a44d34cf 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -291,9 +291,9 @@ void doNormalFault(ThreadContext *tc, TrapType tt) //Update the global register level if(1/*We're delivering the trap in priveleged mode*/) - tc->setMiscReg(MISCREG_GL, max(GL+1, MaxGL)); + tc->setMiscReg(MISCREG_GL, min(GL+1, MaxGL)); else - tc->setMiscReg(MISCREG_GL, max(GL+1, MaxPGL)); + tc->setMiscReg(MISCREG_GL, min(GL+1, MaxPGL)); //PSTATE.mm is unchanged //PSTATE.pef = whether or not an fpu is present -- cgit v1.2.3 From 635df9ba1753915002d10611308cba98527929d3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 08:12:19 -0500 Subject: Major clean up of the fault code. --HG-- extra : convert_revision : eb7e016a127417cbb0e1e2c733b17f82469c2f24 --- src/arch/sparc/faults.cc | 281 ++++++++++++++++++----------------------------- 1 file changed, 104 insertions(+), 177 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 2c8da44c5..169ad7986 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -48,192 +48,119 @@ using namespace std; namespace SparcISA { -FaultName InternalProcessorError::_name = "intprocerr"; -TrapType InternalProcessorError::_trapType = 0x029; -FaultPriority InternalProcessorError::_priority = 4; -FaultStat InternalProcessorError::_count; - -FaultName MemAddressNotAligned::_name = "unalign"; -TrapType MemAddressNotAligned::_trapType = 0x034; -FaultPriority MemAddressNotAligned::_priority = 10; -FaultStat MemAddressNotAligned::_count; - -FaultName PowerOnReset::_name = "pow_reset"; -TrapType PowerOnReset::_trapType = 0x001; -FaultPriority PowerOnReset::_priority = 0; -FaultStat PowerOnReset::_count; - -FaultName WatchDogReset::_name = "watch_dog_reset"; -TrapType WatchDogReset::_trapType = 0x002; -FaultPriority WatchDogReset::_priority = 1; -FaultStat WatchDogReset::_count; - -FaultName ExternallyInitiatedReset::_name = "extern_reset"; -TrapType ExternallyInitiatedReset::_trapType = 0x003; -FaultPriority ExternallyInitiatedReset::_priority = 1; -FaultStat ExternallyInitiatedReset::_count; - -FaultName SoftwareInitiatedReset::_name = "software_reset"; -TrapType SoftwareInitiatedReset::_trapType = 0x004; -FaultPriority SoftwareInitiatedReset::_priority = 1; -FaultStat SoftwareInitiatedReset::_count; - -FaultName REDStateException::_name = "red_counte"; -TrapType REDStateException::_trapType = 0x005; -FaultPriority REDStateException::_priority = 1; -FaultStat REDStateException::_count; - -FaultName InstructionAccessException::_name = "inst_access"; -TrapType InstructionAccessException::_trapType = 0x008; -FaultPriority InstructionAccessException::_priority = 5; -FaultStat InstructionAccessException::_count; - -FaultName InstructionAccessMMUMiss::_name = "inst_mmu"; -TrapType InstructionAccessMMUMiss::_trapType = 0x009; -FaultPriority InstructionAccessMMUMiss::_priority = 2; -FaultStat InstructionAccessMMUMiss::_count; - -FaultName InstructionAccessError::_name = "inst_error"; -TrapType InstructionAccessError::_trapType = 0x00A; -FaultPriority InstructionAccessError::_priority = 3; -FaultStat InstructionAccessError::_count; - -FaultName IllegalInstruction::_name = "illegal_inst"; -TrapType IllegalInstruction::_trapType = 0x010; -FaultPriority IllegalInstruction::_priority = 7; -FaultStat IllegalInstruction::_count; - -FaultName PrivilegedOpcode::_name = "priv_opcode"; -TrapType PrivilegedOpcode::_trapType = 0x011; -FaultPriority PrivilegedOpcode::_priority = 6; -FaultStat PrivilegedOpcode::_count; - -FaultName UnimplementedLDD::_name = "unimp_ldd"; -TrapType UnimplementedLDD::_trapType = 0x012; -FaultPriority UnimplementedLDD::_priority = 6; -FaultStat UnimplementedLDD::_count; - -FaultName UnimplementedSTD::_name = "unimp_std"; -TrapType UnimplementedSTD::_trapType = 0x013; -FaultPriority UnimplementedSTD::_priority = 6; -FaultStat UnimplementedSTD::_count; - -FaultName FpDisabled::_name = "fp_disabled"; -TrapType FpDisabled::_trapType = 0x020; -FaultPriority FpDisabled::_priority = 8; -FaultStat FpDisabled::_count; - -FaultName FpExceptionIEEE754::_name = "fp_754"; -TrapType FpExceptionIEEE754::_trapType = 0x021; -FaultPriority FpExceptionIEEE754::_priority = 11; -FaultStat FpExceptionIEEE754::_count; - -FaultName FpExceptionOther::_name = "fp_other"; -TrapType FpExceptionOther::_trapType = 0x022; -FaultPriority FpExceptionOther::_priority = 11; -FaultStat FpExceptionOther::_count; - -FaultName TagOverflow::_name = "tag_overflow"; -TrapType TagOverflow::_trapType = 0x023; -FaultPriority TagOverflow::_priority = 14; -FaultStat TagOverflow::_count; - -FaultName DivisionByZero::_name = "div_by_zero"; -TrapType DivisionByZero::_trapType = 0x028; -FaultPriority DivisionByZero::_priority = 15; -FaultStat DivisionByZero::_count; - -FaultName DataAccessException::_name = "data_access"; -TrapType DataAccessException::_trapType = 0x030; -FaultPriority DataAccessException::_priority = 12; -FaultStat DataAccessException::_count; - -FaultName DataAccessMMUMiss::_name = "data_mmu"; -TrapType DataAccessMMUMiss::_trapType = 0x031; -FaultPriority DataAccessMMUMiss::_priority = 12; -FaultStat DataAccessMMUMiss::_count; - -FaultName DataAccessError::_name = "data_error"; -TrapType DataAccessError::_trapType = 0x032; -FaultPriority DataAccessError::_priority = 12; -FaultStat DataAccessError::_count; - -FaultName DataAccessProtection::_name = "data_protection"; -TrapType DataAccessProtection::_trapType = 0x033; -FaultPriority DataAccessProtection::_priority = 12; -FaultStat DataAccessProtection::_count; - -FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf"; -TrapType LDDFMemAddressNotAligned::_trapType = 0x035; -FaultPriority LDDFMemAddressNotAligned::_priority = 10; -FaultStat LDDFMemAddressNotAligned::_count; - -FaultName STDFMemAddressNotAligned::_name = "unalign_stdf"; -TrapType STDFMemAddressNotAligned::_trapType = 0x036; -FaultPriority STDFMemAddressNotAligned::_priority = 10; -FaultStat STDFMemAddressNotAligned::_count; - -FaultName PrivilegedAction::_name = "priv_action"; -TrapType PrivilegedAction::_trapType = 0x037; -FaultPriority PrivilegedAction::_priority = 11; -FaultStat PrivilegedAction::_count; - -FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf"; -TrapType LDQFMemAddressNotAligned::_trapType = 0x038; -FaultPriority LDQFMemAddressNotAligned::_priority = 10; -FaultStat LDQFMemAddressNotAligned::_count; - -FaultName STQFMemAddressNotAligned::_name = "unalign_stqf"; -TrapType STQFMemAddressNotAligned::_trapType = 0x039; -FaultPriority STQFMemAddressNotAligned::_priority = 10; -FaultStat STQFMemAddressNotAligned::_count; - -FaultName AsyncDataError::_name = "async_data"; -TrapType AsyncDataError::_trapType = 0x040; -FaultPriority AsyncDataError::_priority = 2; -FaultStat AsyncDataError::_count; - -FaultName CleanWindow::_name = "clean_win"; -TrapType CleanWindow::_trapType = 0x024; -FaultPriority CleanWindow::_priority = 10; -FaultStat CleanWindow::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"intprocerr", 0x029, 4}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign", 0x034, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"pow_reset", 0x001, 0}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"watch_dog_reset", 0x002, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"extern_reset", 0x003, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"software_reset", 0x004, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"red_counte", 0x005, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"inst_access", 0x008, 5}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"inst_mmu", 0x009, 2}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"inst_error", 0x00A, 3}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"illegal_inst", 0x010, 7}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"priv_opcode", 0x011, 6}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unimp_ldd", 0x012, 6}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unimp_std", 0x013, 6}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fp_disabled", 0x020, 8}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fp_754", 0x021, 11}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fp_other", 0x022, 11}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"tag_overflow", 0x023, 14}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"div_by_zero", 0x028, 15}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_access", 0x030, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_mmu", 0x031, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_error", 0x032, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_protection", 0x033, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_lddf", 0x035, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_stdf", 0x036, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"priv_action", 0x037, 11}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_ldqf", 0x038, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_stqf", 0x039, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"async_data", 0x040, 2}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"clean_win", 0x024, 10}; //The enumerated faults -FaultName InterruptLevelN::_name = "interrupt_n"; -TrapType InterruptLevelN::_baseTrapType = 0x041; -FaultStat InterruptLevelN::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"interrupt_n", 0x041, 0}; -FaultName SpillNNormal::_name = "spill_n_normal"; -TrapType SpillNNormal::_baseTrapType = 0x080; -FaultPriority SpillNNormal::_priority = 9; -FaultStat SpillNNormal::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"spill_n_normal", 0x080, 9}; -FaultName SpillNOther::_name = "spill_n_other"; -TrapType SpillNOther::_baseTrapType = 0x0A0; -FaultPriority SpillNOther::_priority = 9; -FaultStat SpillNOther::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"spill_n_other", 0x0A0, 9}; -FaultName FillNNormal::_name = "fill_n_normal"; -TrapType FillNNormal::_baseTrapType = 0x0C0; -FaultPriority FillNNormal::_priority = 9; -FaultStat FillNNormal::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fill_n_normal", 0x0C0, 9}; -FaultName FillNOther::_name = "fill_n_other"; -TrapType FillNOther::_baseTrapType = 0x0E0; -FaultPriority FillNOther::_priority = 9; -FaultStat FillNOther::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fill_n_other", 0x0E0, 9}; -FaultName TrapInstruction::_name = "trap_inst_n"; -TrapType TrapInstruction::_baseTrapType = 0x100; -FaultPriority TrapInstruction::_priority = 16; -FaultStat TrapInstruction::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"trap_inst_n", 0x100, 16}; #if !FULL_SYSTEM -FaultName PageTableFault::_name = "page_table_fault"; -TrapType PageTableFault::_trapType = 0x0000; -FaultPriority PageTableFault::_priority = 0; -FaultStat PageTableFault::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"page_table_fault", 0x0000, 0}; #endif /** @@ -353,7 +280,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt) #if FULL_SYSTEM -void SparcFault::invoke(ThreadContext * tc) +void SparcFaultBase::invoke(ThreadContext * tc) { FaultBase::invoke(tc); countStat()++; -- cgit v1.2.3 From 770b575c30e734b3ed9528558a72c476a9e4bf41 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 10:27:38 -0500 Subject: Sorted faults by the trap type constant, expanded their names, added in new faults for ua2005, and commented out ones which are apparently dropped. --HG-- extra : convert_revision : 32bd0c3a75d7c036ad4a3cb0bc1c32e0b6cb3d87 --- src/arch/sparc/faults.cc | 180 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 142 insertions(+), 38 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 6a905a76c..ebd9926b2 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -50,118 +50,222 @@ namespace SparcISA { template<> SparcFaultBase::FaultVals - SparcFault::vals = {"intprocerr", 0x029, 4}; + SparcFault::vals = + {"power_on_reset", 0x001, 0, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign", 0x034, 10}; + SparcFault::vals = + {"watch_dog_reset", 0x002, 120, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"pow_reset", 0x001, 0}; + SparcFault::vals = + {"externally_initiated_reset", 0x003, 110, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"watch_dog_reset", 0x002, 1}; + SparcFault::vals = + {"software_initiated_reset", 0x004, 130, {SH, SH, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"extern_reset", 0x003, 1}; + SparcFault::vals = + {"RED_state_exception", 0x005, 1, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"software_reset", 0x004, 1}; + SparcFault::vals = + {"store_error", 0x007, 201, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"red_counte", 0x005, 1}; + SparcFault::vals = + {"instruction_access_exception", 0x008, 300, {H, H, H}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"inst_mmu", 0x009, 2, {H, H, H}};*/ + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"instruction_access_error", 0x00A, 400, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"illegal_instruction", 0x010, 620, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"privileged_opcode", 0x011, 700, {P, SH, SH}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"unimp_ldd", 0x012, 6, {H, H, H}};*/ + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"unimp_std", 0x013, 6, {H, H, H}};*/ + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fp_disabled", 0x020, 800, {P, P, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"inst_access", 0x008, 5}; + SparcFault::vals = + {"fp_exception_other", 0x022, 1110, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"inst_mmu", 0x009, 2}; + SparcFault::vals = + {"tag_overflow", 0x023, 1400, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"inst_error", 0x00A, 3}; + SparcFault::vals = + {"clean_window", 0x024, 1010, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"illegal_inst", 0x010, 7}; + SparcFault::vals = + {"division_by_zero", 0x028, 1500, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"priv_opcode", 0x011, 6}; + SparcFault::vals = + {"internal_processor_error", 0x029, 4, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unimp_ldd", 0x012, 6}; + SparcFault::vals = + {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unimp_std", 0x013, 6}; + SparcFault::vals = + {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fp_disabled", 0x020, 8}; + SparcFault::vals = + {"data_access_exception", 0x030, 1201, {H, H, H}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"data_mmu", 0x031, 12, {H, H, H}};*/ + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"data_access_error", 0x032, 1210, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fp_754", 0x021, 11}; + SparcFault::vals = + {"data_access_protection", 0x033, 1207, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fp_other", 0x022, 11}; + SparcFault::vals = + {"mem_address_not_aligned", 0x034, 1020, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"tag_overflow", 0x023, 14}; + SparcFault::vals = + {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"div_by_zero", 0x028, 15}; + SparcFault::vals = + {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_access", 0x030, 12}; + SparcFault::vals = + {"privileged_action", 0x037, 1110, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_mmu", 0x031, 12}; + SparcFault::vals = + {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_error", 0x032, 12}; + SparcFault::vals = + {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_protection", 0x033, 12}; + SparcFault::vals = + {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_lddf", 0x035, 10}; + SparcFault::vals = + {"data_real_translation_miss", 0x03F, 1203, {H, H, H}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"async_data", 0x040, 2, {H, H, H}};*/ template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_stdf", 0x036, 10}; + SparcFault::vals = + {"interrupt_level_n", 0x041, 0, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"priv_action", 0x037, 11}; + SparcFault::vals = + {"hstick_match", 0x05E, 1601, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_ldqf", 0x038, 10}; + SparcFault::vals = + {"trap_level_zero", 0x05F, 202, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_stqf", 0x039, 10}; + SparcFault::vals = + {"PA_watchpoint", 0x061, 1209, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"async_data", 0x040, 2}; + SparcFault::vals = + {"VA_watchpoint", 0x062, 1120, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"clean_win", 0x024, 10}; + SparcFault::vals = + {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}}; -//The enumerated faults +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fast_data_access_protection", 0x06C, 1207, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"instruction_break", 0x076, 610, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"cpu_mondo", 0x07C, 1608, {P, P, SH}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"dev_mondo", 0x07D, 1611, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"interrupt_n", 0x041, 0}; + SparcFault::vals = + {"resume_error", 0x07E, 3330, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"spill_n_normal", 0x080, 9}; + SparcFault::vals = + {"spill_n_normal", 0x080, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"spill_n_other", 0x0A0, 9}; + SparcFault::vals = + {"spill_n_other", 0x0A0, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fill_n_normal", 0x0C0, 9}; + SparcFault::vals = + {"fill_n_normal", 0x0C0, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fill_n_other", 0x0E0, 9}; + SparcFault::vals = + {"fill_n_other", 0x0E0, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"trap_inst_n", 0x100, 16}; + SparcFault::vals = + {"trap_instruction", 0x100, 1602, {P, P, H}}; #if !FULL_SYSTEM template<> SparcFaultBase::FaultVals - SparcFault::vals = {"page_table_fault", 0x0000, 0}; + SparcFault::vals = + {"page_table_fault", 0x0000, 0, {SH, SH, SH}}; #endif /** -- cgit v1.2.3 From 63bbc8929d778c15f5c7479819226c19a42dc2b9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 13:58:00 -0500 Subject: First cut at full blown SPARC faults. There are a few details that are missing. --HG-- extra : convert_revision : 8023db1479cb9bf99fc9edfeb521c4e5b581f895 --- src/arch/sparc/faults.cc | 240 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 211 insertions(+), 29 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index ebd9926b2..e895c02db 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -33,6 +33,7 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" +#include "arch/sparc/types.hh" #include "base/bitfield.hh" #include "base/trace.hh" #include "config/full_system.hh" @@ -268,26 +269,133 @@ template<> SparcFaultBase::FaultVals {"page_table_fault", 0x0000, 0, {SH, SH, SH}}; #endif +/** + * This causes the thread context to enter RED state. This causes the side + * effects which go with entering RED state because of a trap. + */ + +void enterREDState(ThreadContext *tc) +{ + //@todo Disable the mmu? + //@todo Disable watchpoints? + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + //HPSTATE.red = 1 + HPSTATE |= (1 << 5); + //HPSTATE.hpriv = 1 + HPSTATE |= (1 << 2); + tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); +} + +/** + * This sets everything up for a RED state trap except for actually jumping to + * the handler. + */ + +void doREDFault(ThreadContext *tc, TrapType tt) +{ + MiscReg TL = tc->readMiscReg(MISCREG_TL); + MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); + MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg ASI = tc->readMiscReg(MISCREG_ASI); + MiscReg CWP = tc->readMiscReg(MISCREG_CWP); + MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg GL = tc->readMiscReg(MISCREG_GL); + MiscReg PC = tc->readPC(); + MiscReg NPC = tc->readNextPC(); + + TL++; + + //set TSTATE.gl to gl + replaceBits(TSTATE, 42, 40, GL); + //set TSTATE.ccr to ccr + replaceBits(TSTATE, 39, 32, CCR); + //set TSTATE.asi to asi + replaceBits(TSTATE, 31, 24, ASI); + //set TSTATE.pstate to pstate + replaceBits(TSTATE, 20, 8, PSTATE); + //set TSTATE.cwp to cwp + replaceBits(TSTATE, 4, 0, CWP); + + //Write back TSTATE + tc->setMiscReg(MISCREG_TSTATE, TSTATE); + + //set TPC to PC + tc->setMiscReg(MISCREG_TPC, PC); + //set TNPC to NPC + tc->setMiscReg(MISCREG_TNPC, NPC); + + //set HTSTATE.hpstate to hpstate + tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); + + //TT = trap type; + tc->setMiscReg(MISCREG_TT, tt); + + //Update GL + tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); + + //set PSTATE.mm to 00 + //set PSTATE.pef to 1 + PSTATE |= (1 << 4); + //set PSTATE.am to 0 + PSTATE &= ~(1 << 3); + //set PSTATE.priv to 0 + PSTATE &= ~(1 << 2); + //set PSTATE.ie to 0 + PSTATE &= ~(1 << 1); + //set PSTATE.cle to 0 + PSTATE &= ~(1 << 9); + //PSTATE.tle is unchanged + //XXX Where is the tct bit? + //set PSTATE.tct to 0 + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + + //set HPSTATE.red to 1 + HPSTATE |= (1 << 5); + //set HPSTATE.hpriv to 1 + HPSTATE |= (1 << 2); + //set HPSTATE.ibe to 0 + HPSTATE &= ~(1 << 10); + //set HPSTATE.tlz to 0 + HPSTATE &= ~(1 << 0); + tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + + bool changedCWP = true; + if(tt == 0x24) + CWP++; + else if(0x80 <= tt && tt <= 0xbf) + CWP += (CANSAVE + 2); + else if(0xc0 <= tt && tt <= 0xff) + CWP--; + else + changedCWP = false; + + if(changedCWP) + { + CWP = (CWP + NWindows) % NWindows; + tc->setMiscRegWithEffect(MISCREG_CWP, CWP); + } +} + /** * This sets everything up for a normal trap except for actually jumping to - * the handler. It will need to be expanded to include the state machine in - * the manual. Right now it assumes that traps will always be to the - * privileged level. + * the handler. */ -void doNormalFault(ThreadContext *tc, TrapType tt) +void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) { - uint64_t TL = tc->readMiscReg(MISCREG_TL); - uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE); - uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE); - uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - uint64_t CCR = tc->readMiscReg(MISCREG_CCR); - uint64_t ASI = tc->readMiscReg(MISCREG_ASI); - uint64_t CWP = tc->readMiscReg(MISCREG_CWP); - uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); - uint64_t GL = tc->readMiscReg(MISCREG_GL); - uint64_t PC = tc->readPC(); - uint64_t NPC = tc->readNextPC(); + MiscReg TL = tc->readMiscReg(MISCREG_TL); + MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); + MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg ASI = tc->readMiscReg(MISCREG_ASI); + MiscReg CWP = tc->readMiscReg(MISCREG_CWP); + MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg GL = tc->readMiscReg(MISCREG_GL); + MiscReg PC = tc->readPC(); + MiscReg NPC = tc->readNextPC(); //Increment the trap level TL++; @@ -321,10 +429,10 @@ void doNormalFault(ThreadContext *tc, TrapType tt) tc->setMiscReg(MISCREG_TT, tt); //Update the global register level - if(1/*We're delivering the trap in priveleged mode*/) - tc->setMiscReg(MISCREG_GL, min(GL+1, MaxGL)); + if(!gotoHpriv) + tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxPGL)); else - tc->setMiscReg(MISCREG_GL, min(GL+1, MaxPGL)); + tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); //PSTATE.mm is unchanged //PSTATE.pef = whether or not an fpu is present @@ -333,7 +441,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt) PSTATE |= (1 << 4); //PSTATE.am = 0 PSTATE &= ~(1 << 3); - if(1/*We're delivering the trap in priveleged mode*/) + if(!gotoHpriv) { //PSTATE.priv = 1 PSTATE |= (1 << 2); @@ -354,7 +462,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt) //XXX Where exactly is this field? tc->setMiscReg(MISCREG_PSTATE, PSTATE); - if(0/*We're delivering the trap in hyperprivileged mode*/) + if(gotoHpriv) { //HPSTATE.red = 0 HPSTATE &= ~(1 << 5); @@ -383,6 +491,29 @@ void doNormalFault(ThreadContext *tc, TrapType tt) } } +void getREDVector(Addr & PC, Addr & NPC) +{ + const Addr RSTVAddr = 0xFFFFFFFFF0000000ULL; + PC = RSTVAddr | 0xA0; + NPC = PC + sizeof(MachInst); +} + +void getHyperVector(Addr & PC, Addr & NPC, MiscReg TT) +{ + Addr HTBA ; + PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); + NPC = PC + sizeof(MachInst); +} + +void getPrivVector(Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) +{ + Addr TBA ; + PC = (TBA & ~mask(15)) | + (TL > 1 ? (1 << 14) : 0) | + ((TT << 5) & mask(14)); + NPC = PC + sizeof(MachInst); +} + #if FULL_SYSTEM void SparcFaultBase::invoke(ThreadContext * tc) @@ -390,11 +521,64 @@ void SparcFaultBase::invoke(ThreadContext * tc) FaultBase::invoke(tc); countStat()++; - //Use the SPARC trap state machine + //We can refer to this to see what the trap level -was-, but something + //in the middle could change it in the regfile out from under us. + MiscReg TL = tc->readMiscReg(MISCREG_TL); + MiscReg TT = tc->readMiscReg(MISCREG_TT); + MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + + Addr PC, NPC; + + PrivilegeLevel current; + if(!(PSTATE & (1 << 2))) + current = User; + else if(!(HPSTATE & (1 << 2))) + current = Privileged; + else + current = Hyperprivileged; + + PrivilegeLevel level = getNextLevel(current); + + if(HPSTATE & (1 << 5) || TL == MaxTL - 1) + { + getREDVector(PC, NPC); + enterREDState(tc); + doREDFault(tc, TT); + } + else if(TL == MaxTL) + { + //Do error_state somehow? + //Probably inject a WDR fault using the interrupt mechanism. + //What should the PC and NPC be set to? + } + else if(TL > MaxPTL && level == Privileged) + { + //guest_watchdog fault + doNormalFault(tc, trapType(), true); + getHyperVector(PC, NPC, 2); + } + else if(level == Hyperprivileged) + { + doNormalFault(tc, trapType(), true); + getHyperVector(PC, NPC, trapType()); + } + else + { + doNormalFault(tc, trapType(), false); + getPrivVector(PC, NPC, trapType(), TL+1); + } + + tc->setPC(PC); + tc->setNextPC(NPC); + tc->setNextNPC(NPC + sizeof(MachInst)); } void PowerOnReset::invoke(ThreadContext * tc) { + //First, enter RED state. + enterREDState(tc); + //For SPARC, when a system is first started, there is a power //on reset Trap which sets the processor into the following state. //Bits that aren't set aren't defined on startup. @@ -426,17 +610,15 @@ void PowerOnReset::invoke(ThreadContext * tc) */ } -#endif - -#if !FULL_SYSTEM +#else // !FULL_SYSTEM void SpillNNormal::invoke(ThreadContext *tc) { - doNormalFault(tc, trapType()); + doNormalFault(tc, trapType(), false); Process *p = tc->getProcessPtr(); - //This will only work in faults from a SparcLiveProcess + //XXX This will only work in faults from a SparcLiveProcess SparcLiveProcess *lp = dynamic_cast(p); assert(lp); @@ -449,15 +631,15 @@ void SpillNNormal::invoke(ThreadContext *tc) void FillNNormal::invoke(ThreadContext *tc) { - doNormalFault(tc, trapType()); + doNormalFault(tc, trapType(), false); Process * p = tc->getProcessPtr(); - //This will only work in faults from a SparcLiveProcess + //XXX This will only work in faults from a SparcLiveProcess SparcLiveProcess *lp = dynamic_cast(p); assert(lp); - //The adjust the PC and NPC + //Then adjust the PC and NPC Addr fillStart = lp->readFillStart(); tc->setPC(fillStart); tc->setNextPC(fillStart + sizeof(MachInst)); -- cgit v1.2.3 From 50462c15aafc4ea076fb4bce69abe9cc32c33788 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Nov 2006 19:24:35 -0500 Subject: Fix a couple uninitialized variables. --HG-- extra : convert_revision : d17d28a9520524e5f56bd79beb9b2be6ce76a22f --- src/arch/sparc/faults.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/arch/sparc/faults.cc') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index e895c02db..57ee040f1 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -493,21 +493,22 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) void getREDVector(Addr & PC, Addr & NPC) { + //XXX The following constant might belong in a header file. const Addr RSTVAddr = 0xFFFFFFFFF0000000ULL; PC = RSTVAddr | 0xA0; NPC = PC + sizeof(MachInst); } -void getHyperVector(Addr & PC, Addr & NPC, MiscReg TT) +void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT) { - Addr HTBA ; + Addr HTBA = tc->readMiscReg(MISCREG_HTBA); PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); NPC = PC + sizeof(MachInst); } -void getPrivVector(Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) +void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) { - Addr TBA ; + Addr TBA = tc->readMiscReg(MISCREG_TBA); PC = (TBA & ~mask(15)) | (TL > 1 ? (1 << 14) : 0) | ((TT << 5) & mask(14)); @@ -556,17 +557,17 @@ void SparcFaultBase::invoke(ThreadContext * tc) { //guest_watchdog fault doNormalFault(tc, trapType(), true); - getHyperVector(PC, NPC, 2); + getHyperVector(tc, PC, NPC, 2); } else if(level == Hyperprivileged) { doNormalFault(tc, trapType(), true); - getHyperVector(PC, NPC, trapType()); + getHyperVector(tc, PC, NPC, trapType()); } else { doNormalFault(tc, trapType(), false); - getPrivVector(PC, NPC, trapType(), TL+1); + getPrivVector(tc, PC, NPC, trapType(), TL+1); } tc->setPC(PC); -- cgit v1.2.3