summaryrefslogtreecommitdiff
path: root/src/arch/sparc/regfile.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/regfile.hh')
-rw-r--r--src/arch/sparc/regfile.hh462
1 files changed, 240 insertions, 222 deletions
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index 5169a332f..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,11 +43,23 @@ namespace SparcISA
typedef uint8_t RegIndex;
// MAXTL - maximum trap level
- const int MaxTL = 4;
+ const int MaxPTL = 2;
+ const int MaxTL = 6;
+ const int MaxGL = 3;
+ const int MaxPGL = 2;
// 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:
@@ -63,8 +76,7 @@ namespace SparcISA
(unsigned int)(-1) :
(1 << FrameOffsetBits) - 1;
- IntReg regGlobals[RegsPerFrame];
- IntReg altGlobals[RegsPerFrame];
+ IntReg regGlobals[MaxGL][RegsPerFrame];
IntReg regSegments[2 * NWindows][RegsPerFrame];
enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
@@ -72,8 +84,7 @@ namespace SparcISA
IntReg * regView[NumFrames];
static const int RegGlobalOffset = 0;
- static const int AltGlobalOffset = 8;
- static const int FrameOffset = 16;
+ static const int FrameOffset = MaxGL * RegsPerFrame;
int offset[NumFrames];
public:
@@ -88,8 +99,9 @@ namespace SparcISA
void clear()
{
- bzero(regGlobals, sizeof(regGlobals));
- bzero(altGlobals, sizeof(altGlobals));
+ int x;
+ for (x = 0; x < MaxGL; x++)
+ memset(regGlobals[x], 0, sizeof(regGlobals[x]));
for(int x = 0; x < 2 * NWindows; x++)
bzero(regSegments[x], sizeof(regSegments[x]));
}
@@ -97,7 +109,7 @@ namespace SparcISA
IntRegFile()
{
offset[Globals] = 0;
- regView[Globals] = regGlobals;
+ regView[Globals] = regGlobals[0];
setCWP(0);
clear();
}
@@ -135,21 +147,13 @@ namespace SparcISA
DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
}
- void setAltGlobals(bool useAlt)
+ void setGlobals(int gl)
{
- DPRINTF(Sparc, "Now using %s globals",
- useAlt ? "alternate" : "regular");
- regView[Globals] = useAlt ? altGlobals : regGlobals;
- // You have not included an out-of-class definition of your static
- // members. See [9.4.2]/4 and about a billion gcc bug reports. If
- // statements get around the problem through some magic, and than
- // seems nicer that putting a definition of them in a c file
- // somewhere.
- if (useAlt)
- offset[Globals] = AltGlobalOffset;
- else
- offset[Globals] = RegGlobalOffset;
+ DPRINTF(Sparc, "Now using %d globals", gl);
+
+ regView[Globals] = regGlobals[gl];
+ offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
}
void serialize(std::ostream &os);
@@ -283,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
@@ -442,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
@@ -516,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
@@ -536,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
@@ -556,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:
@@ -578,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
@@ -587,8 +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.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
@@ -609,6 +625,7 @@ namespace SparcISA
}
MiscRegFile()
+ : tickCompare(this), sTickCompare(this), hSTickCompare(this)
{
reset();
}
@@ -627,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
@@ -687,7 +708,7 @@ namespace SparcISA
floatRegFile.clear();
}
- int flattenIntIndex(int reg)
+ int FlattenIntIndex(int reg)
{
return intRegFile.flattenIndex(reg);
}
@@ -780,22 +801,17 @@ namespace SparcISA
CONTEXT_CWP,
CONTEXT_GLOBALS
};
-
- union ContextVal
- {
- MiscReg reg;
- bool altGlobals;
- };
+ 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.setAltGlobals(val.altGlobals);
+ intRegFile.setGlobals(val);
break;
default:
panic("Tried to set illegal context parameter in the SPARC regfile.\n");
@@ -807,6 +823,8 @@ namespace SparcISA
void copyMiscRegs(ExecContext *src, ExecContext *dest);
+ int InterruptLevel(uint64_t softint);
+
} // namespace SparcISA
#endif