diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2006-05-26 18:40:00 -0400 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2006-05-26 18:40:00 -0400 |
commit | e04f60667af9884fa871935e4c1274bdf0311707 (patch) | |
tree | 0d580e464c384d8636f9a9c685aaa491db9d8793 /src/arch/sparc/regfile.hh | |
parent | 28ea9729427d2c994d54f0548f80afaeb221b88f (diff) | |
download | gem5-e04f60667af9884fa871935e4c1274bdf0311707.tar.xz |
Implement PR/HPR/ASR for full system
Rip out storage in miscreg file that will never store anything
Add storage and defines for Priv and Hyperpriv registers
Change defines to match the spec register numbers
Change the way misc registers are named to match the spec with offsets to deal with ASR/PR/HPR/FSR.
Change contextval to an int since both global registers and windowed registers are indexed by int in UA2005.
Use bitfields for things that are rarely used in decoder
Instead of decoding ASR/PR/HPR and having a specfic instruction, use a generic instruction instead
Still todo:
Protect rdpr, rdhpr, wrpr, wrhpr with checks that fault in insufficient privs
Deal with signaling interrupts on timer expiration
Deal with writes to softint/PIL generating interrupts how those are vectored to the CPU
Other misc:
Instruction decoding needs major help!
src/arch/sparc/isa/decoder.isa:
Remove tons of MISCREG_XXXX defines that weren't used and ControlRegs in that were never used. Ones that were used rarely
changed to bitfields.
src/arch/sparc/isa/formats/integerop.isa:
These seems like a whole lot of overkill in printing, but i'll leave it the way it is for now. Allow Ccr to be set
at once
src/arch/sparc/isa/formats/priv.isa:
PrivTick is handled by miscreg now, don't need a seperate class for it
src/arch/sparc/isa/operands.isa:
prune the number of control regs down to a reasonable amount
src/arch/sparc/isa_traits.hh:
Replace 8 defines with 1 and flick some bits
src/arch/sparc/process.cc:
Better to clean the entire registers that specific bits which leads to indetermanistic behavior.
src/arch/sparc/regfile.hh:
Rip out storage that will never be backed by anything
Add storage for Priv and Hyperpriv registers
change defines to match the spec
change the way misc registers are named to match the spec with offsets to deal with ASR/PR/HPR/FSR.
change contextval to an int since both global registers and windowed registers are indexed by int in UA2005.
--HG--
extra : convert_revision : 64276a3ea884eea70112e721f85a515946ded4c2
Diffstat (limited to 'src/arch/sparc/regfile.hh')
-rw-r--r-- | src/arch/sparc/regfile.hh | 427 |
1 files changed, 225 insertions, 202 deletions
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 96f36eb91..4dfdc0cf3 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -32,6 +32,7 @@ #include "arch/sparc/faults.hh" #include "base/trace.hh" #include "sim/byteswap.hh" +#include "sim/eventq.hh" #include "sim/host.hh" class Checkpoint; @@ -42,7 +43,7 @@ namespace SparcISA typedef uint8_t RegIndex; // MAXTL - maximum trap level - const int MaxPTL = 6; + const int MaxPTL = 2; const int MaxTL = 6; const int MaxGL = 3; const int MaxPGL = 2; @@ -50,6 +51,15 @@ namespace SparcISA // NWINDOWS - number of register windows, can be 3 to 32 const int NWindows = 32; + + const int AsrStart = 0; + const int PrStart = 32; + const int HprStart = 64; + const int MiscStart = 96; + + + const uint64_t Bit64 = 0x8000000000000000; + class IntRegFile { protected: @@ -277,156 +287,83 @@ namespace SparcISA enum MiscRegIndex { - MISCREG_PSTATE, - MISCREG_PSTATE_AG, - MISCREG_PSTATE_IE, - MISCREG_PSTATE_PRIV, - MISCREG_PSTATE_AM, - MISCREG_PSTATE_PEF, - MISCREG_PSTATE_RED, - MISCREG_PSTATE_MM, - MISCREG_PSTATE_TLE, - MISCREG_PSTATE_CLE, - MISCREG_TBA, - MISCREG_Y, - MISCREG_Y_VALUE, - MISCREG_PIL, - MISCREG_CWP, - MISCREG_TT_BASE, - MISCREG_TT_END = MISCREG_TT_BASE + MaxTL, - MISCREG_CCR, - MISCREG_CCR_ICC, - MISCREG_CCR_ICC_C, - MISCREG_CCR_ICC_V, - MISCREG_CCR_ICC_Z, - MISCREG_CCR_ICC_N, - MISCREG_CCR_XCC, - MISCREG_CCR_XCC_C, - MISCREG_CCR_XCC_V, - MISCREG_CCR_XCC_Z, - MISCREG_CCR_XCC_N, - MISCREG_ASI, - MISCREG_TL, - MISCREG_TPC_BASE, - MISCREG_TPC_END = MISCREG_TPC_BASE + MaxTL, - MISCREG_TNPC_BASE, - MISCREG_TNPC_END = MISCREG_TNPC_BASE + MaxTL, - MISCREG_TSTATE_BASE, - MISCREG_TSTATE_END = MISCREG_TSTATE_BASE + MaxTL, - MISCREG_TSTATE_CWP_BASE, - MISCREG_TSTATE_CWP_END = MISCREG_TSTATE_CWP_BASE + MaxTL, - MISCREG_TSTATE_PSTATE_BASE, - MISCREG_TSTATE_PSTATE_END = MISCREG_TSTATE_PSTATE_BASE + MaxTL, - MISCREG_TSTATE_ASI_BASE, - MISCREG_TSTATE_ASI_END = MISCREG_TSTATE_ASI_BASE + MaxTL, - MISCREG_TSTATE_CCR_BASE, - MISCREG_TSTATE_CCR_END = MISCREG_TSTATE_CCR_BASE + MaxTL, - MISCREG_TICK, - MISCREG_TICK_COUNTER, - MISCREG_TICK_NPT, - MISCREG_CANSAVE, - MISCREG_CANRESTORE, - MISCREG_OTHERWIN, - MISCREG_CLEANWIN, - MISCREG_WSTATE, - MISCREG_WSTATE_NORMAL, - MISCREG_WSTATE_OTHER, - MISCREG_VER, - MISCREG_VER_MAXWIN, - MISCREG_VER_MAXTL, - MISCREG_VER_MASK, - MISCREG_VER_IMPL, - MISCREG_VER_MANUF, - MISCREG_FSR, - MISCREG_FSR_CEXC, - MISCREG_FSR_CEXC_NXC, - MISCREG_FSR_CEXC_DZC, - MISCREG_FSR_CEXC_UFC, - MISCREG_FSR_CEXC_OFC, - MISCREG_FSR_CEXC_NVC, - MISCREG_FSR_AEXC, - MISCREG_FSR_AEXC_NXC, - MISCREG_FSR_AEXC_DZC, - MISCREG_FSR_AEXC_UFC, - MISCREG_FSR_AEXC_OFC, - MISCREG_FSR_AEXC_NVC, - MISCREG_FSR_FCC0, - MISCREG_FSR_QNE, - MISCREG_FSR_FTT, - MISCREG_FSR_VER, - MISCREG_FSR_NS, - MISCREG_FSR_TEM, - MISCREG_FSR_TEM_NXM, - MISCREG_FSR_TEM_DZM, - MISCREG_FSR_TEM_UFM, - MISCREG_FSR_TEM_OFM, - MISCREG_FSR_TEM_NVM, - MISCREG_FSR_RD, - MISCREG_FSR_FCC1, - MISCREG_FSR_FCC2, - MISCREG_FSR_FCC3, - MISCREG_FPRS, - MISCREG_FPRS_DL, - MISCREG_FPRS_DU, - MISCREG_FPRS_FEF, - numMiscRegs + /** Ancillary State Registers */ + MISCREG_Y = AsrStart + 0, + MISCREG_CCR = AsrStart + 2, + MISCREG_ASI = AsrStart + 3, + MISCREG_TICK = AsrStart + 4, + MISCREG_PC = AsrStart + 5, + MISCREG_FPRS = AsrStart + 6, + MISCREG_PCR = AsrStart + 16, + MISCREG_PIC = AsrStart + 17, + MISCREG_GSR = AsrStart + 19, + MISCREG_SOFTINT_SET = AsrStart + 20, + MISCREG_SOFTINT_CLR = AsrStart + 21, + MISCREG_SOFTINT = AsrStart + 22, + MISCREG_TICK_CMPR = AsrStart + 23, + MISCREG_STICK = AsrStart + 24, + MISCREG_STICK_CMPR = AsrStart + 25, + + /** Privilged Registers */ + MISCREG_TPC = PrStart + 0, + MISCREG_TNPC = PrStart + 1, + MISCREG_TSTATE = PrStart + 2, + MISCREG_TT = PrStart + 3, + MISCREG_PRIVTICK = PrStart + 4, + MISCREG_TBA = PrStart + 5, + MISCREG_PSTATE = PrStart + 6, + MISCREG_TL = PrStart + 7, + MISCREG_PIL = PrStart + 8, + MISCREG_CWP = PrStart + 9, + MISCREG_CANSAVE = PrStart + 10, + MISCREG_CANRESTORE = PrStart + 11, + MISCREG_CLEANWIN = PrStart + 12, + MISCREG_OTHERWIN = PrStart + 13, + MISCREG_WSTATE = PrStart + 14, + MISCREG_GL = PrStart + 16, + + /** Hyper privileged registers */ + MISCREG_HPSTATE = HprStart + 0, + MISCREG_HTSTATE = HprStart + 1, + MISCREG_HINTP = HprStart + 3, + MISCREG_HTBA = HprStart + 5, + MISCREG_HVER = HprStart + 6, + MISCREG_STRAND_STS_REG = HprStart + 16, + MISCREG_HSTICK_CMPR = HprStart + 31, + + /** Floating Point Status Register */ + MISCREG_FSR = MiscStart + 0 + }; // The control registers, broken out into fields class MiscRegFile { private: - union - { - uint16_t pstate; // Process State Register - struct - { - uint16_t ag:1; // Alternate Globals - uint16_t ie:1; // Interrupt enable - uint16_t priv:1; // Privelege mode - uint16_t am:1; // Address mask - uint16_t pef:1; // PSTATE enable floating-point - uint16_t red:1; // RED (reset, error, debug) state - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - }; - uint64_t tba; // Trap Base Address - union - { + + /* ASR Registers */ + union { uint64_t y; // Y (used in obsolete multiplication) - struct - { + struct { uint64_t value:32; // The actual value stored in y uint64_t :32; // reserved bits } yFields; }; - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured - // on the previous level) - union - { + union { uint8_t ccr; // Condition Code Register - struct - { - union - { + struct { + union { uint8_t icc:4; // 32-bit condition codes - struct - { + struct { uint8_t c:1; // Carry uint8_t v:1; // Overflow uint8_t z:1; // Zero uint8_t n:1; // Negative } iccFields; }; - union - { + union { uint8_t xcc:4; // 64-bit condition codes - struct - { + struct { uint8_t c:1; // Carry uint8_t v:1; // Overflow uint8_t z:1; // Zero @@ -436,73 +373,143 @@ namespace SparcISA } ccrFields; }; uint8_t asi; // Address Space Identifier - uint8_t tl; // Trap Level + union { + uint64_t tick; // Hardware clock-tick counter + struct { + int64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + }; + union { + uint8_t fprs; // Floating-Point Register State + struct { + uint8_t dl:1; // Dirty lower + uint8_t du:1; // Dirty upper + uint8_t fef:1; // FPRS enable floating-Point + } fprsFields; + }; + union { + uint64_t softint; + struct { + uint64_t tm:1; + uint64_t int_level:14; + uint64_t sm:1; + } softintFields; + }; + union { + uint64_t tick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } tick_cmprFields; + }; + union { + uint64_t stick; // Hardware clock-tick counter + struct { + int64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } stickFields; + }; + union { + uint64_t stick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } stick_cmprFields; + }; + + + /* Privileged Registers */ uint64_t tpc[MaxTL]; // Trap Program Counter (value from // previous trap level) uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from // previous trap level) - union - { + union { uint64_t tstate[MaxTL]; // Trap State - struct - { + struct { //Values are from previous trap level uint64_t cwp:5; // Current Window Pointer - uint64_t :2; // Reserved bits - uint64_t pstate:10; // Process State - uint64_t :6; // Reserved bits + uint64_t :3; // Reserved bits + uint64_t pstate:13; // Process State + uint64_t :3; // Reserved bits uint64_t asi:8; // Address Space Identifier uint64_t ccr:8; // Condition Code Register + uint64_t gl:8; // Global level } tstateFields[MaxTL]; }; - union - { - uint64_t tick; // Hardware clock-tick counter - struct - { - uint64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + // on the previous level) + uint64_t tba; // Trap Base Address + + union { + uint16_t pstate; // Process State Register + struct { + uint16_t :1; // reserved + uint16_t ie:1; // Interrupt enable + uint16_t priv:1; // Privelege mode + uint16_t am:1; // Address mask + uint16_t pef:1; // PSTATE enable floating-point + uint16_t :1; // reserved2 + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; }; + uint8_t tl; // Trap Level + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer uint8_t cansave; // Savable windows uint8_t canrestore; // Restorable windows - uint8_t otherwin; // Other windows uint8_t cleanwin; // Clean windows - union - { + uint8_t otherwin; // Other windows + union { uint8_t wstate; // Window State - struct - { + struct { uint8_t normal:3; // Bits TT<4:2> are set to on a normal // register window trap uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" // register window trap } wstateFields; }; - union - { - uint64_t ver; // Version - struct - { - uint64_t maxwin:5; // Max CWP value - uint64_t :2; // Reserved bits - uint64_t maxtl:8; // Maximum trap level - uint64_t :8; // Reserved bits - uint64_t mask:8; // Processor mask set revision number - uint64_t impl:16; // Implementation identification number - uint64_t manuf:16; // Manufacturer code - } verFields; + uint8_t gl; // Global level register + + + /** Hyperprivileged Registers */ + union { + uint64_t hpstate; // Hyperprivileged State Register + struct { + uint8_t tlz: 1; + uint8_t :1; + uint8_t hpriv:1; + uint8_t :2; + uint8_t red:1; + uint8_t :4; + uint8_t ibe:1; + uint8_t id:1; + } hpstateFields; }; - union - { + + uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register + uint64_t hintp; + uint64_t htba; // Hyperprivileged Trap Base Address register + union { + uint64_t hstick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } hstick_cmprFields; + }; + + uint64_t strandStatusReg; // Per strand status register + + + /** Floating point misc registers. */ + union { uint64_t fsr; // Floating-Point State Register - struct - { - union - { + struct { + union { uint64_t cexc:5; // Current excpetion - struct - { + struct { uint64_t nxc:1; // Inexact uint64_t dzc:1; // Divide by zero uint64_t ufc:1; // Underflow @@ -510,11 +517,9 @@ namespace SparcISA uint64_t nvc:1; // Invalid operand } cexcFields; }; - union - { + union { uint64_t aexc:5; // Accrued exception - struct - { + struct { uint64_t nxc:1; // Inexact uint64_t dzc:1; // Divide by zero uint64_t ufc:1; // Underflow @@ -530,11 +535,9 @@ namespace SparcISA uint64_t ver:3; // Version (of the FPU) uint64_t :2; // Reserved bits uint64_t ns:1; // Nonstandard floating point - union - { + union { uint64_t tem:5; // Trap Enable Mask - struct - { + struct { uint64_t nxm:1; // Inexact uint64_t dzm:1; // Divide by zero uint64_t ufm:1; // Underflow @@ -550,16 +553,24 @@ namespace SparcISA uint64_t :26; // Reserved bits } fsrFields; }; - union - { - uint8_t fprs; // Floating-Point Register State - struct - { - uint8_t dl:1; // Dirty lower - uint8_t du:1; // Dirty upper - uint8_t fef:1; // FPRS enable floating-Point - } fprsFields; - }; + + // These need to check the int_dis field and if 0 then + // set appropriate bit in softint and checkinterrutps on the cpu + void processTickCompare() { panic("tick compare not implemented\n"); } + void processSTickCompare(){ panic("tick compare not implemented\n"); } + void processHSTickCompare(){ panic("tick compare not implemented\n"); } + + typedef EventWrapper<MiscRegFile, + &MiscRegFile::processTickCompare> TickCompareEvent; + TickCompareEvent tickCompare; + + typedef EventWrapper<MiscRegFile, + &MiscRegFile::processSTickCompare> STickCompareEvent; + STickCompareEvent sTickCompare; + + typedef EventWrapper<MiscRegFile, + &MiscRegFile::processHSTickCompare> HSTickCompareEvent; + HSTickCompareEvent hSTickCompare; public: @@ -572,6 +583,7 @@ namespace SparcISA //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; tt[tl] = PowerOnReset.trapType(); pstateFields.mm = 0; //Total Store Order pstateFields.red = 1; //Enter RED_State @@ -581,9 +593,18 @@ namespace SparcISA pstateFields.ag = 1; //Globals are replaced with alternate globals pstateFields.tle = 0; //Big Endian mode for traps pstateFields.cle = 0; //Big Endian mode for non-traps - tickFields.counter = 0; //The TICK register is unreadable by - tickFields.npt = 1; //The TICK register is unreadable by - //non-priveleged software + tickFields.counter = 0; //The TICK register is unreadable bya + tickFields.npt = 1; //The TICK register is unreadable by by !priv + tick_cmpr.int_dis = 1; // disable timer compare interrupts + stickFields.counter = 0; //The TICK register is unreadable by + stickFields.npt = 1; //The TICK register is unreadable by by !priv + hpstateFields.id = 1; + hpstateFields.ibe = 0; + hpstateFields.red = 1; + hpstateFields.hpriv = 1; + hpstateFields.tlz = 0; // this is a guess + + #else /* //This sets up the initial state of the processor for usermode processes pstateFields.priv = 0; //Process runs in user mode @@ -604,6 +625,7 @@ namespace SparcISA } MiscRegFile() + : tickCompare(this), sTickCompare(this), hSTickCompare(this) { reset(); } @@ -622,6 +644,10 @@ namespace SparcISA void unserialize(Checkpoint * cp, const std::string & section); void copyMiscRegs(ExecContext * xc); + + bool isHyperPriv() { return hpstateFields.hpriv; } + bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } + bool isNonPriv() { return !isPriv(); } }; typedef union @@ -775,22 +801,17 @@ namespace SparcISA CONTEXT_CWP, CONTEXT_GLOBALS }; - - union ContextVal - { - MiscReg reg; - int globalLevel; - }; + typedef int ContextVal; void changeContext(ContextParam param, ContextVal val) { switch(param) { case CONTEXT_CWP: - intRegFile.setCWP(val.reg); + intRegFile.setCWP(val); break; case CONTEXT_GLOBALS: - intRegFile.setGlobals(val.globalLevel); + intRegFile.setGlobals(val); break; default: panic("Tried to set illegal context parameter in the SPARC regfile.\n"); @@ -802,6 +823,8 @@ namespace SparcISA void copyMiscRegs(ExecContext *src, ExecContext *dest); + int InterruptLevel(uint64_t softint); + } // namespace SparcISA #endif |