summaryrefslogtreecommitdiff
path: root/src/arch/sparc/regfile.hh
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2006-05-26 18:40:00 -0400
committerAli Saidi <saidi@eecs.umich.edu>2006-05-26 18:40:00 -0400
commite04f60667af9884fa871935e4c1274bdf0311707 (patch)
tree0d580e464c384d8636f9a9c685aaa491db9d8793 /src/arch/sparc/regfile.hh
parent28ea9729427d2c994d54f0548f80afaeb221b88f (diff)
downloadgem5-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.hh427
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