SPARC: Clean up some historical style issues.
This commit is contained in:
parent
0b7967d606
commit
cdc585e0e8
51 changed files with 2213 additions and 2189 deletions
|
@ -33,277 +33,286 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
bool AsiIsBlock(ASI asi)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(asi == ASI_BLK_AIUP) ||
|
|
||||||
(asi == ASI_BLK_AIUS) ||
|
|
||||||
(asi == ASI_BLK_AIUP_L) ||
|
|
||||||
(asi == ASI_BLK_AIUS_L) ||
|
|
||||||
(asi == ASI_BLK_P) ||
|
|
||||||
(asi == ASI_BLK_S) ||
|
|
||||||
(asi == ASI_BLK_PL) ||
|
|
||||||
(asi == ASI_BLK_SL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AsiIsPrimary(ASI asi)
|
bool
|
||||||
{
|
asiIsBlock(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_AIUP) ||
|
return asi == ASI_BLK_AIUP ||
|
||||||
(asi == ASI_BLK_AIUP) ||
|
asi == ASI_BLK_AIUS ||
|
||||||
(asi == ASI_AIUP_L) ||
|
asi == ASI_BLK_AIUP_L ||
|
||||||
(asi == ASI_BLK_AIUP_L) ||
|
asi == ASI_BLK_AIUS_L ||
|
||||||
(asi == ASI_LDTX_AIUP) ||
|
asi == ASI_BLK_P ||
|
||||||
(asi == ASI_LDTX_AIUP_L) ||
|
asi == ASI_BLK_S ||
|
||||||
(asi == ASI_P) ||
|
asi == ASI_BLK_PL ||
|
||||||
(asi == ASI_PNF) ||
|
asi == ASI_BLK_SL;
|
||||||
(asi == ASI_PL) ||
|
}
|
||||||
(asi == ASI_PNFL) ||
|
|
||||||
(asi == ASI_PST8_P) ||
|
|
||||||
(asi == ASI_PST16_P) ||
|
|
||||||
(asi == ASI_PST32_P) ||
|
|
||||||
(asi == ASI_PST8_PL) ||
|
|
||||||
(asi == ASI_PST16_PL) ||
|
|
||||||
(asi == ASI_PST32_PL) ||
|
|
||||||
(asi == ASI_FL8_P) ||
|
|
||||||
(asi == ASI_FL16_P) ||
|
|
||||||
(asi == ASI_FL8_PL) ||
|
|
||||||
(asi == ASI_FL16_PL) ||
|
|
||||||
(asi == ASI_LDTX_P) ||
|
|
||||||
(asi == ASI_LDTX_PL) ||
|
|
||||||
(asi == ASI_BLK_P) ||
|
|
||||||
(asi == ASI_BLK_PL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AsiIsSecondary(ASI asi)
|
bool
|
||||||
{
|
asiIsPrimary(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_AIUS) ||
|
return asi == ASI_AIUP ||
|
||||||
(asi == ASI_BLK_AIUS) ||
|
asi == ASI_BLK_AIUP ||
|
||||||
(asi == ASI_AIUS_L) ||
|
asi == ASI_AIUP_L ||
|
||||||
(asi == ASI_BLK_AIUS_L) ||
|
asi == ASI_BLK_AIUP_L ||
|
||||||
(asi == ASI_LDTX_AIUS) ||
|
asi == ASI_LDTX_AIUP ||
|
||||||
(asi == ASI_LDTX_AIUS_L) ||
|
asi == ASI_LDTX_AIUP_L ||
|
||||||
(asi == ASI_S) ||
|
asi == ASI_P ||
|
||||||
(asi == ASI_SNF) ||
|
asi == ASI_PNF ||
|
||||||
(asi == ASI_SL) ||
|
asi == ASI_PL ||
|
||||||
(asi == ASI_SNFL) ||
|
asi == ASI_PNFL ||
|
||||||
(asi == ASI_PST8_S) ||
|
asi == ASI_PST8_P ||
|
||||||
(asi == ASI_PST16_S) ||
|
asi == ASI_PST16_P ||
|
||||||
(asi == ASI_PST32_S) ||
|
asi == ASI_PST32_P ||
|
||||||
(asi == ASI_PST8_SL) ||
|
asi == ASI_PST8_PL ||
|
||||||
(asi == ASI_PST16_SL) ||
|
asi == ASI_PST16_PL ||
|
||||||
(asi == ASI_PST32_SL) ||
|
asi == ASI_PST32_PL ||
|
||||||
(asi == ASI_FL8_S) ||
|
asi == ASI_FL8_P ||
|
||||||
(asi == ASI_FL16_S) ||
|
asi == ASI_FL16_P ||
|
||||||
(asi == ASI_FL8_SL) ||
|
asi == ASI_FL8_PL ||
|
||||||
(asi == ASI_FL16_SL) ||
|
asi == ASI_FL16_PL ||
|
||||||
(asi == ASI_LDTX_S) ||
|
asi == ASI_LDTX_P ||
|
||||||
(asi == ASI_LDTX_SL) ||
|
asi == ASI_LDTX_PL ||
|
||||||
(asi == ASI_BLK_S) ||
|
asi == ASI_BLK_P ||
|
||||||
(asi == ASI_BLK_SL);
|
asi == ASI_BLK_PL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsNucleus(ASI asi)
|
bool
|
||||||
{
|
asiIsSecondary(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_N) ||
|
return asi == ASI_AIUS ||
|
||||||
(asi == ASI_NL) ||
|
asi == ASI_BLK_AIUS ||
|
||||||
(asi == ASI_LDTX_N) ||
|
asi == ASI_AIUS_L ||
|
||||||
(asi == ASI_LDTX_NL);
|
asi == ASI_BLK_AIUS_L ||
|
||||||
}
|
asi == ASI_LDTX_AIUS ||
|
||||||
|
asi == ASI_LDTX_AIUS_L ||
|
||||||
|
asi == ASI_S ||
|
||||||
|
asi == ASI_SNF ||
|
||||||
|
asi == ASI_SL ||
|
||||||
|
asi == ASI_SNFL ||
|
||||||
|
asi == ASI_PST8_S ||
|
||||||
|
asi == ASI_PST16_S ||
|
||||||
|
asi == ASI_PST32_S ||
|
||||||
|
asi == ASI_PST8_SL ||
|
||||||
|
asi == ASI_PST16_SL ||
|
||||||
|
asi == ASI_PST32_SL ||
|
||||||
|
asi == ASI_FL8_S ||
|
||||||
|
asi == ASI_FL16_S ||
|
||||||
|
asi == ASI_FL8_SL ||
|
||||||
|
asi == ASI_FL16_SL ||
|
||||||
|
asi == ASI_LDTX_S ||
|
||||||
|
asi == ASI_LDTX_SL ||
|
||||||
|
asi == ASI_BLK_S ||
|
||||||
|
asi == ASI_BLK_SL;
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsAsIfUser(ASI asi)
|
bool
|
||||||
{
|
asiIsNucleus(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_AIUP) ||
|
return asi == ASI_N ||
|
||||||
(asi == ASI_AIUS) ||
|
asi == ASI_NL ||
|
||||||
(asi == ASI_BLK_AIUP) ||
|
asi == ASI_LDTX_N ||
|
||||||
(asi == ASI_BLK_AIUS) ||
|
asi == ASI_LDTX_NL;
|
||||||
(asi == ASI_AIUP_L) ||
|
}
|
||||||
(asi == ASI_AIUS_L) ||
|
|
||||||
(asi == ASI_BLK_AIUP_L) ||
|
|
||||||
(asi == ASI_BLK_AIUS_L) ||
|
|
||||||
(asi == ASI_LDTX_AIUP) ||
|
|
||||||
(asi == ASI_LDTX_AIUS) ||
|
|
||||||
(asi == ASI_LDTX_AIUP_L) ||
|
|
||||||
(asi == ASI_LDTX_AIUS_L);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AsiIsIO(ASI asi)
|
bool
|
||||||
{
|
asiIsAsIfUser(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_REAL_IO) ||
|
return asi == ASI_AIUP ||
|
||||||
(asi == ASI_REAL_IO_L);
|
asi == ASI_AIUS ||
|
||||||
}
|
asi == ASI_BLK_AIUP ||
|
||||||
|
asi == ASI_BLK_AIUS ||
|
||||||
|
asi == ASI_AIUP_L ||
|
||||||
|
asi == ASI_AIUS_L ||
|
||||||
|
asi == ASI_BLK_AIUP_L ||
|
||||||
|
asi == ASI_BLK_AIUS_L ||
|
||||||
|
asi == ASI_LDTX_AIUP ||
|
||||||
|
asi == ASI_LDTX_AIUS ||
|
||||||
|
asi == ASI_LDTX_AIUP_L ||
|
||||||
|
asi == ASI_LDTX_AIUS_L;
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsReal(ASI asi)
|
bool
|
||||||
{
|
asiIsIO(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_REAL) ||
|
return asi == ASI_REAL_IO ||
|
||||||
(asi == ASI_REAL_IO) ||
|
asi == ASI_REAL_IO_L;
|
||||||
(asi == ASI_REAL_L) ||
|
}
|
||||||
(asi == ASI_REAL_IO_L) ||
|
|
||||||
(asi == ASI_LDTX_REAL) ||
|
|
||||||
(asi == ASI_LDTX_REAL_L);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AsiIsLittle(ASI asi)
|
bool
|
||||||
{
|
asiIsReal(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_NL) ||
|
return asi == ASI_REAL ||
|
||||||
(asi == ASI_AIUP_L) ||
|
asi == ASI_REAL_IO ||
|
||||||
(asi == ASI_AIUS_L) ||
|
asi == ASI_REAL_L ||
|
||||||
(asi == ASI_REAL_L) ||
|
asi == ASI_REAL_IO_L ||
|
||||||
(asi == ASI_REAL_IO_L) ||
|
asi == ASI_LDTX_REAL ||
|
||||||
(asi == ASI_BLK_AIUP_L) ||
|
asi == ASI_LDTX_REAL_L;
|
||||||
(asi == ASI_BLK_AIUS_L) ||
|
}
|
||||||
(asi == ASI_LDTX_AIUP_L) ||
|
|
||||||
(asi == ASI_LDTX_AIUS_L) ||
|
|
||||||
(asi == ASI_LDTX_REAL_L) ||
|
|
||||||
(asi == ASI_LDTX_NL) ||
|
|
||||||
(asi == ASI_PL) ||
|
|
||||||
(asi == ASI_SL) ||
|
|
||||||
(asi == ASI_PNFL) ||
|
|
||||||
(asi == ASI_SNFL) ||
|
|
||||||
(asi == ASI_PST8_PL) ||
|
|
||||||
(asi == ASI_PST8_SL) ||
|
|
||||||
(asi == ASI_PST16_PL) ||
|
|
||||||
(asi == ASI_PST16_SL) ||
|
|
||||||
(asi == ASI_PST32_PL) ||
|
|
||||||
(asi == ASI_PST32_SL) ||
|
|
||||||
(asi == ASI_FL8_PL) ||
|
|
||||||
(asi == ASI_FL8_SL) ||
|
|
||||||
(asi == ASI_FL16_PL) ||
|
|
||||||
(asi == ASI_FL16_SL) ||
|
|
||||||
(asi == ASI_LDTX_PL) ||
|
|
||||||
(asi == ASI_LDTX_SL) ||
|
|
||||||
(asi == ASI_BLK_PL) ||
|
|
||||||
(asi == ASI_BLK_SL) ||
|
|
||||||
(asi == ASI_LTX_L);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AsiIsTwin(ASI asi)
|
bool
|
||||||
{
|
asiIsLittle(ASI asi)
|
||||||
return
|
{
|
||||||
(asi >= ASI_LDTX_AIUP &&
|
return asi == ASI_NL ||
|
||||||
|
asi == ASI_AIUP_L ||
|
||||||
|
asi == ASI_AIUS_L ||
|
||||||
|
asi == ASI_REAL_L ||
|
||||||
|
asi == ASI_REAL_IO_L ||
|
||||||
|
asi == ASI_BLK_AIUP_L ||
|
||||||
|
asi == ASI_BLK_AIUS_L ||
|
||||||
|
asi == ASI_LDTX_AIUP_L ||
|
||||||
|
asi == ASI_LDTX_AIUS_L ||
|
||||||
|
asi == ASI_LDTX_REAL_L ||
|
||||||
|
asi == ASI_LDTX_NL ||
|
||||||
|
asi == ASI_PL ||
|
||||||
|
asi == ASI_SL ||
|
||||||
|
asi == ASI_PNFL ||
|
||||||
|
asi == ASI_SNFL ||
|
||||||
|
asi == ASI_PST8_PL ||
|
||||||
|
asi == ASI_PST8_SL ||
|
||||||
|
asi == ASI_PST16_PL ||
|
||||||
|
asi == ASI_PST16_SL ||
|
||||||
|
asi == ASI_PST32_PL ||
|
||||||
|
asi == ASI_PST32_SL ||
|
||||||
|
asi == ASI_FL8_PL ||
|
||||||
|
asi == ASI_FL8_SL ||
|
||||||
|
asi == ASI_FL16_PL ||
|
||||||
|
asi == ASI_FL16_SL ||
|
||||||
|
asi == ASI_LDTX_PL ||
|
||||||
|
asi == ASI_LDTX_SL ||
|
||||||
|
asi == ASI_BLK_PL ||
|
||||||
|
asi == ASI_BLK_SL ||
|
||||||
|
asi == ASI_LTX_L;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
asiIsTwin(ASI asi)
|
||||||
|
{
|
||||||
|
return (asi >= ASI_LDTX_AIUP &&
|
||||||
asi <= ASI_LDTX_N &&
|
asi <= ASI_LDTX_N &&
|
||||||
asi != ASI_QUEUE) ||
|
asi != ASI_QUEUE) ||
|
||||||
(asi >= ASI_LDTX_AIUP_L &&
|
(asi >= ASI_LDTX_AIUP_L &&
|
||||||
asi <= ASI_LDTX_NL &&
|
asi <= ASI_LDTX_NL &&
|
||||||
asi != 0x2D) ||
|
asi != 0x2D) ||
|
||||||
asi == ASI_LDTX_P ||
|
asi == ASI_LDTX_P ||
|
||||||
asi == ASI_LDTX_S ||
|
asi == ASI_LDTX_S ||
|
||||||
asi == ASI_LDTX_PL ||
|
asi == ASI_LDTX_PL ||
|
||||||
asi == ASI_LDTX_SL;
|
asi == ASI_LDTX_SL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsPartialStore(ASI asi)
|
bool
|
||||||
{
|
asiIsPartialStore(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_PST8_P) ||
|
return asi == ASI_PST8_P ||
|
||||||
(asi == ASI_PST8_S) ||
|
asi == ASI_PST8_S ||
|
||||||
(asi == ASI_PST16_P) ||
|
asi == ASI_PST16_P ||
|
||||||
(asi == ASI_PST16_S) ||
|
asi == ASI_PST16_S ||
|
||||||
(asi == ASI_PST32_P) ||
|
asi == ASI_PST32_P ||
|
||||||
(asi == ASI_PST32_S) ||
|
asi == ASI_PST32_S ||
|
||||||
(asi == ASI_PST8_PL) ||
|
asi == ASI_PST8_PL ||
|
||||||
(asi == ASI_PST8_SL) ||
|
asi == ASI_PST8_SL ||
|
||||||
(asi == ASI_PST16_PL) ||
|
asi == ASI_PST16_PL ||
|
||||||
(asi == ASI_PST16_SL) ||
|
asi == ASI_PST16_SL ||
|
||||||
(asi == ASI_PST32_PL) ||
|
asi == ASI_PST32_PL ||
|
||||||
(asi == ASI_PST32_SL);
|
asi == ASI_PST32_SL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsFloatingLoad(ASI asi)
|
bool
|
||||||
{
|
asiIsFloatingLoad(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_FL8_P) ||
|
return asi == ASI_FL8_P ||
|
||||||
(asi == ASI_FL8_S) ||
|
asi == ASI_FL8_S ||
|
||||||
(asi == ASI_FL16_P) ||
|
asi == ASI_FL16_P ||
|
||||||
(asi == ASI_FL16_S) ||
|
asi == ASI_FL16_S ||
|
||||||
(asi == ASI_FL8_PL) ||
|
asi == ASI_FL8_PL ||
|
||||||
(asi == ASI_FL8_SL) ||
|
asi == ASI_FL8_SL ||
|
||||||
(asi == ASI_FL16_PL) ||
|
asi == ASI_FL16_PL ||
|
||||||
(asi == ASI_FL16_SL);
|
asi == ASI_FL16_SL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsNoFault(ASI asi)
|
bool
|
||||||
{
|
asiIsNoFault(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_PNF) ||
|
return asi == ASI_PNF ||
|
||||||
(asi == ASI_SNF) ||
|
asi == ASI_SNF ||
|
||||||
(asi == ASI_PNFL) ||
|
asi == ASI_PNFL ||
|
||||||
(asi == ASI_SNFL);
|
asi == ASI_SNFL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsScratchPad(ASI asi)
|
bool
|
||||||
{
|
asiIsScratchPad(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_SCRATCHPAD) ||
|
return asi == ASI_SCRATCHPAD ||
|
||||||
(asi == ASI_HYP_SCRATCHPAD);
|
asi == ASI_HYP_SCRATCHPAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsCmt(ASI asi)
|
bool
|
||||||
{
|
asiIsCmt(ASI asi)
|
||||||
return
|
{
|
||||||
(asi == ASI_CMT_PER_STRAND) ||
|
return asi == ASI_CMT_PER_STRAND ||
|
||||||
(asi == ASI_CMT_SHARED);
|
asi == ASI_CMT_SHARED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsQueue(ASI asi)
|
bool
|
||||||
{
|
asiIsQueue(ASI asi)
|
||||||
return asi == ASI_QUEUE;
|
{
|
||||||
}
|
return asi == ASI_QUEUE;
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsInterrupt(ASI asi)
|
bool
|
||||||
{
|
asiIsInterrupt(ASI asi)
|
||||||
return asi == ASI_SWVR_INTR_RECEIVE ||
|
{
|
||||||
asi == ASI_SWVR_UDB_INTR_W ||
|
return asi == ASI_SWVR_INTR_RECEIVE ||
|
||||||
asi == ASI_SWVR_UDB_INTR_R ;
|
asi == ASI_SWVR_UDB_INTR_W ||
|
||||||
}
|
asi == ASI_SWVR_UDB_INTR_R ;
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsMmu(ASI asi)
|
bool
|
||||||
{
|
asiIsMmu(ASI asi)
|
||||||
return asi == ASI_MMU ||
|
{
|
||||||
asi == ASI_LSU_CONTROL_REG ||
|
return asi == ASI_MMU ||
|
||||||
(asi >= ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 &&
|
asi == ASI_LSU_CONTROL_REG ||
|
||||||
asi <= ASI_IMMU_CTXT_ZERO_CONFIG) ||
|
(asi >= ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 &&
|
||||||
(asi >= ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 &&
|
asi <= ASI_IMMU_CTXT_ZERO_CONFIG) ||
|
||||||
asi <= ASI_IMMU_CTXT_NONZERO_CONFIG) ||
|
(asi >= ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 &&
|
||||||
(asi >= ASI_IMMU &&
|
asi <= ASI_IMMU_CTXT_NONZERO_CONFIG) ||
|
||||||
asi <= ASI_IMMU_TSB_PS1_PTR_REG) ||
|
(asi >= ASI_IMMU &&
|
||||||
(asi >= ASI_ITLB_DATA_IN_REG &&
|
asi <= ASI_IMMU_TSB_PS1_PTR_REG) ||
|
||||||
asi <= ASI_TLB_INVALIDATE_ALL);
|
(asi >= ASI_ITLB_DATA_IN_REG &&
|
||||||
}
|
asi <= ASI_TLB_INVALIDATE_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsUnPriv(ASI asi)
|
bool
|
||||||
{
|
asiIsUnPriv(ASI asi)
|
||||||
return asi >= 0x80;
|
{
|
||||||
}
|
return asi >= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsPriv(ASI asi)
|
bool
|
||||||
{
|
asiIsPriv(ASI asi)
|
||||||
return asi <= 0x2f;
|
{
|
||||||
}
|
return asi <= 0x2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AsiIsHPriv(ASI asi)
|
bool
|
||||||
{
|
asiIsHPriv(ASI asi)
|
||||||
return asi >= 0x30 && asi <= 0x7f;
|
{
|
||||||
}
|
return asi >= 0x30 && asi <= 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsReg(ASI asi)
|
bool
|
||||||
{
|
asiIsReg(ASI asi)
|
||||||
return AsiIsMmu(asi) || AsiIsScratchPad(asi) ||
|
{
|
||||||
AsiIsSparcError(asi) || AsiIsInterrupt(asi)
|
return asiIsMmu(asi) || asiIsScratchPad(asi) ||
|
||||||
|| AsiIsCmt(asi);
|
asiIsSparcError(asi) || asiIsInterrupt(asi)
|
||||||
}
|
|| asiIsCmt(asi);
|
||||||
|
}
|
||||||
|
|
||||||
bool AsiIsSparcError(ASI asi)
|
bool
|
||||||
{
|
asiIsSparcError(ASI asi)
|
||||||
return asi == ASI_SPARC_ERROR_EN_REG ||
|
{
|
||||||
asi == ASI_SPARC_ERROR_STATUS_REG;
|
return asi == ASI_SPARC_ERROR_EN_REG ||
|
||||||
}
|
asi == ASI_SPARC_ERROR_STATUS_REG;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,243 +34,244 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
enum ASI {
|
|
||||||
ASI_IMPLICIT = 0x00,
|
|
||||||
/* Priveleged ASIs */
|
|
||||||
//0x00-0x03 implementation dependent
|
|
||||||
ASI_NUCLEUS = 0x4,
|
|
||||||
ASI_N = 0x4,
|
|
||||||
//0x05-0x0B implementation dependent
|
|
||||||
ASI_NL = 0xC,
|
|
||||||
ASI_NUCLEUS_LITTLE = ASI_NL,
|
|
||||||
//0x0D-0x0F implementation dependent
|
|
||||||
ASI_AIUP = 0x10,
|
|
||||||
ASI_AS_IF_USER_PRIMARY = ASI_AIUP,
|
|
||||||
ASI_AIUS = 0x11,
|
|
||||||
ASI_AS_IF_USER_SECONDARY = ASI_AIUS,
|
|
||||||
//0x12-0x13 implementation dependent
|
|
||||||
ASI_REAL = 0x14,
|
|
||||||
ASI_REAL_IO = 0x15,
|
|
||||||
ASI_BLK_AIUP = 0x16,
|
|
||||||
ASI_BLOCK_AS_IF_USER_PRIMARY = ASI_BLK_AIUP,
|
|
||||||
ASI_BLK_AIUS = 0x17,
|
|
||||||
ASI_BLOCK_AS_IF_USER_SECONDARY = ASI_BLK_AIUS,
|
|
||||||
ASI_AIUP_L = 0x18,
|
|
||||||
ASI_AS_IF_USER_PRIMARY_LITTLE = ASI_AIUP_L,
|
|
||||||
ASI_AIUS_L = 0x19,
|
|
||||||
ASI_AS_IF_USER_SECONDARY_LITTLE = ASI_AIUS_L,
|
|
||||||
//0x1A-0x1B implementation dependent
|
|
||||||
ASI_REAL_L = 0x1C,
|
|
||||||
ASI_REAL_LITTLE = ASI_REAL_L,
|
|
||||||
ASI_REAL_IO_L = 0x1D,
|
|
||||||
ASI_REAL_IO_LITTLE = ASI_REAL_IO_L,
|
|
||||||
ASI_BLK_AIUP_L = 0x1E,
|
|
||||||
ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE = ASI_BLK_AIUP_L,
|
|
||||||
ASI_BLK_AIUS_L = 0x1F,
|
|
||||||
ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE = ASI_BLK_AIUS_L,
|
|
||||||
ASI_SCRATCHPAD = 0x20,
|
|
||||||
ASI_MMU = 0x21,
|
|
||||||
ASI_LDTX_AIUP = 0x22,
|
|
||||||
ASI_LD_TWINX_AS_IF_USER_PRIMARY = ASI_LDTX_AIUP,
|
|
||||||
ASI_LDTX_AIUS = 0x23,
|
|
||||||
ASI_LD_TWINX_AS_IF_USER_SECONDARY = ASI_LDTX_AIUS,
|
|
||||||
ASI_QUAD_LDD = 0x24,
|
|
||||||
ASI_QUEUE = 0x25,
|
|
||||||
ASI_QUAD_LDD_REAL = 0x26,
|
|
||||||
ASI_LDTX_REAL = ASI_QUAD_LDD_REAL,
|
|
||||||
ASI_LDTX_N = 0x27,
|
|
||||||
ASI_LD_TWINX_NUCLEUS = ASI_LDTX_N,
|
|
||||||
ASI_ST_BLKINIT_NUCLEUS = ASI_LDTX_N,
|
|
||||||
ASI_STBI_N = ASI_LDTX_N,
|
|
||||||
//0x28-0x29 implementation dependent
|
|
||||||
ASI_LDTX_AIUP_L = 0x2A,
|
|
||||||
ASI_TWINX_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
|
|
||||||
ASI_ST_BLKINIT_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
|
|
||||||
ASI_STBI_AIUP_L = ASI_LDTX_AIUP_L,
|
|
||||||
ASI_LDTX_AIUS_L = 0x2B,
|
|
||||||
ASI_LD_TWINX_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
|
|
||||||
ASI_ST_BLKINIT_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
|
|
||||||
ASI_STBI_AIUS_L = ASI_LDTX_AIUS_L,
|
|
||||||
ASI_LTX_L = 0x2C,
|
|
||||||
ASI_TWINX_LITTLE = ASI_LTX_L,
|
|
||||||
//0x2D implementation dependent
|
|
||||||
ASI_LDTX_REAL_L = 0x2E,
|
|
||||||
ASI_LD_TWINX_REAL_LITTLE = ASI_LDTX_REAL_L,
|
|
||||||
ASI_LDTX_NL = 0x2F,
|
|
||||||
ASI_LD_TWINX_NUCLEUS_LITTLE = ASI_LDTX_NL,
|
|
||||||
//0x20 implementation dependent
|
|
||||||
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x31,
|
|
||||||
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x32,
|
|
||||||
ASI_DMMU_CTXT_ZERO_CONFIG = 0x33,
|
|
||||||
//0x34 implementation dependent
|
|
||||||
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x35,
|
|
||||||
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x36,
|
|
||||||
ASI_IMMU_CTXT_ZERO_CONFIG = 0x37,
|
|
||||||
//0x38 implementation dependent
|
|
||||||
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x39,
|
|
||||||
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3A,
|
|
||||||
ASI_DMMU_CTXT_NONZERO_CONFIG = 0x3B,
|
|
||||||
//0x3C implementation dependent
|
|
||||||
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x3D,
|
|
||||||
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3E,
|
|
||||||
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
|
|
||||||
ASI_STREAM_MA = 0x40,
|
|
||||||
ASI_CMT_SHARED = 0x41,
|
|
||||||
//0x41 implementation dependent
|
|
||||||
ASI_SPARC_BIST_CONTROL = 0x42,
|
|
||||||
ASI_INST_MASK_REG = 0x42,
|
|
||||||
ASI_LSU_DIAG_REG = 0x42,
|
|
||||||
//0x43 implementation dependent
|
|
||||||
ASI_STM_CTL_REG = 0x44,
|
|
||||||
ASI_LSU_CONTROL_REG = 0x45,
|
|
||||||
ASI_DCACHE_DATA = 0x46,
|
|
||||||
ASI_DCACHE_TAG = 0x47,
|
|
||||||
ASI_INTR_DISPATCH_STATUS = 0x48,
|
|
||||||
ASI_INTR_RECEIVE = 0x49,
|
|
||||||
ASI_UPA_CONFIG_REGISTER = 0x4A,
|
|
||||||
ASI_SPARC_ERROR_EN_REG = 0x4B,
|
|
||||||
ASI_SPARC_ERROR_STATUS_REG = 0x4C,
|
|
||||||
ASI_SPARC_ERROR_ADDRESS_REG = 0x4D,
|
|
||||||
ASI_ECACHE_TAG_DATA = 0x4E,
|
|
||||||
ASI_HYP_SCRATCHPAD = 0x4F,
|
|
||||||
ASI_IMMU = 0x50,
|
|
||||||
ASI_IMMU_TSB_PS0_PTR_REG = 0x51,
|
|
||||||
ASI_IMMU_TSB_PS1_PTR_REG = 0x52,
|
|
||||||
//0x53 implementation dependent
|
|
||||||
ASI_ITLB_DATA_IN_REG = 0x54,
|
|
||||||
ASI_ITLB_DATA_ACCESS_REG = 0x55,
|
|
||||||
ASI_ITLB_TAG_READ_REG = 0x56,
|
|
||||||
ASI_IMMU_DEMAP = 0x57,
|
|
||||||
ASI_DMMU = 0x58,
|
|
||||||
ASI_DMMU_TSB_PS0_PTR_REG = 0x59,
|
|
||||||
ASI_DMMU_TSB_PS1_PTR_REG = 0x5A,
|
|
||||||
ASI_DMMU_TSB_DIRECT_PTR_REG = 0x5B,
|
|
||||||
ASI_DTLB_DATA_IN_REG = 0x5C,
|
|
||||||
ASI_DTLB_DATA_ACCESS_REG = 0x5D,
|
|
||||||
ASI_DTLB_TAG_READ_REG = 0x5E,
|
|
||||||
ASI_DMMU_DEMAP = 0x5F,
|
|
||||||
ASI_TLB_INVALIDATE_ALL = 0x60,
|
|
||||||
//0x61-0x62 implementation dependent
|
|
||||||
ASI_CMT_PER_STRAND = 0x63,
|
|
||||||
//0x64-0x65 implementation dependent
|
|
||||||
ASI_ICACHE_INSTR = 0x66,
|
|
||||||
ASI_ICACHE_TAG = 0x67,
|
|
||||||
//0x68-0x71 implementation dependent
|
|
||||||
ASI_SWVR_INTR_RECEIVE = 0x72,
|
|
||||||
ASI_SWVR_UDB_INTR_W = 0x73,
|
|
||||||
ASI_SWVR_UDB_INTR_R = 0x74,
|
|
||||||
//0x74-0x7F reserved
|
|
||||||
/* Unpriveleged ASIs */
|
|
||||||
ASI_P = 0x80,
|
|
||||||
ASI_PRIMARY = ASI_P,
|
|
||||||
ASI_S = 0x81,
|
|
||||||
ASI_SECONDARY = ASI_S,
|
|
||||||
ASI_PNF = 0x82,
|
|
||||||
ASI_PRIMARY_NO_FAULT = ASI_PNF,
|
|
||||||
ASI_SNF = 0x83,
|
|
||||||
ASI_SECONDARY_NO_FAULT = ASI_SNF,
|
|
||||||
//0x84-0x87 reserved
|
|
||||||
ASI_PL = 0x88,
|
|
||||||
ASI_PRIMARY_LITTLE = ASI_PL,
|
|
||||||
ASI_SL = 0x89,
|
|
||||||
ASI_SECONDARY_LITTLE = ASI_SL,
|
|
||||||
ASI_PNFL = 0x8A,
|
|
||||||
ASI_PRIMARY_NO_FAULT_LITTLE = ASI_PNFL,
|
|
||||||
ASI_SNFL = 0x8B,
|
|
||||||
ASI_SECONDARY_NO_FAULT_LITTLE = ASI_SNFL,
|
|
||||||
//0x8C-0xBF reserved
|
|
||||||
ASI_PST8_P = 0xC0,
|
|
||||||
ASI_PST8_PRIMARY = ASI_PST8_P,
|
|
||||||
ASI_PST8_S = 0xC1,
|
|
||||||
ASI_PST8_SECONDARY = ASI_PST8_S,
|
|
||||||
ASI_PST16_P = 0xC2,
|
|
||||||
ASI_PST16_PRIMARY = ASI_PST16_P,
|
|
||||||
ASI_PST16_S = 0xC3,
|
|
||||||
ASI_PST16_SECONDARY = ASI_PST16_S,
|
|
||||||
ASI_PST32_P = 0xC4,
|
|
||||||
ASI_PST32_PRIMARY = ASI_PST32_P,
|
|
||||||
ASI_PST32_S = 0xC5,
|
|
||||||
ASI_PST32_SECONDARY = ASI_PST32_S,
|
|
||||||
//0xC6-0xC7 implementation dependent
|
|
||||||
ASI_PST8_PL = 0xC8,
|
|
||||||
ASI_PST8_PRIMARY_LITTLE = ASI_PST8_PL,
|
|
||||||
ASI_PST8_SL = 0xC9,
|
|
||||||
ASI_PST8_SECONDARY_LITTLE = ASI_PST8_SL,
|
|
||||||
ASI_PST16_PL = 0xCA,
|
|
||||||
ASI_PST16_PRIMARY_LITTLE = ASI_PST16_PL,
|
|
||||||
ASI_PST16_SL = 0xCB,
|
|
||||||
ASI_PST16_SECONDARY_LITTLE = ASI_PST16_SL,
|
|
||||||
ASI_PST32_PL = 0xCC,
|
|
||||||
ASI_PST32_PRIMARY_LITTLE = ASI_PST32_PL,
|
|
||||||
ASI_PST32_SL = 0xCD,
|
|
||||||
ASI_PST32_SECONDARY_LITTLE = ASI_PST32_SL,
|
|
||||||
//0xCE-0xCF implementation dependent
|
|
||||||
ASI_FL8_P = 0xD0,
|
|
||||||
ASI_FL8_PRIMARY = ASI_FL8_P,
|
|
||||||
ASI_FL8_S = 0xD1,
|
|
||||||
ASI_FL8_SECONDARY = ASI_FL8_S,
|
|
||||||
ASI_FL16_P = 0xD2,
|
|
||||||
ASI_FL16_PRIMARY = ASI_FL16_P,
|
|
||||||
ASI_FL16_S = 0xD3,
|
|
||||||
ASI_FL16_SECONDARY = ASI_FL16_S,
|
|
||||||
//0xD4-0xD7 implementation dependent
|
|
||||||
ASI_FL8_PL = 0xD8,
|
|
||||||
ASI_FL8_PRIMARY_LITTLE = ASI_FL8_PL,
|
|
||||||
ASI_FL8_SL = 0xD9,
|
|
||||||
ASI_FL8_SECONDARY_LITTLE = ASI_FL8_SL,
|
|
||||||
ASI_FL16_PL = 0xDA,
|
|
||||||
ASI_FL16_PRIMARY_LITTLE = ASI_FL16_PL,
|
|
||||||
ASI_FL16_SL = 0xDB,
|
|
||||||
ASI_FL16_SECONDARY_LITTLE = ASI_FL16_SL,
|
|
||||||
//0xDC-0xDF implementation dependent
|
|
||||||
//0xE0-0xE1 reserved
|
|
||||||
ASI_LDTX_P = 0xE2,
|
|
||||||
ASI_LD_TWINX_PRIMARY = ASI_LDTX_P,
|
|
||||||
ASI_LDTX_S = 0xE3,
|
|
||||||
ASI_LD_TWINX_SECONDARY = ASI_LDTX_S,
|
|
||||||
//0xE4-0xE9 implementation dependent
|
|
||||||
ASI_LDTX_PL = 0xEA,
|
|
||||||
ASI_LD_TWINX_PRIMARY_LITTLE = ASI_LDTX_PL,
|
|
||||||
ASI_LDTX_SL = 0xEB,
|
|
||||||
ASI_LD_TWINX_SECONDARY_LITTLE = ASI_LDTX_SL,
|
|
||||||
//0xEC-0xEF implementation dependent
|
|
||||||
ASI_BLK_P = 0xF0,
|
|
||||||
ASI_BLOCK_PRIMARY = ASI_BLK_P,
|
|
||||||
ASI_BLK_S = 0xF1,
|
|
||||||
ASI_BLOCK_SECONDARY = ASI_BLK_S,
|
|
||||||
//0xF2-0xF7 implementation dependent
|
|
||||||
ASI_BLK_PL = 0xF8,
|
|
||||||
ASI_BLOCK_PRIMARY_LITTLE = ASI_BLK_PL,
|
|
||||||
ASI_BLK_SL = 0xF9,
|
|
||||||
ASI_BLOCK_SECONDARY_LITTLE = ASI_BLK_SL,
|
|
||||||
//0xFA-0xFF implementation dependent
|
|
||||||
MAX_ASI = 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
//Functions that classify an asi
|
enum ASI {
|
||||||
bool AsiIsBlock(ASI);
|
ASI_IMPLICIT = 0x00,
|
||||||
bool AsiIsPrimary(ASI);
|
/* Priveleged ASIs */
|
||||||
bool AsiIsSecondary(ASI);
|
// 0x00-0x03 implementation dependent
|
||||||
bool AsiIsNucleus(ASI);
|
ASI_NUCLEUS = 0x4,
|
||||||
bool AsiIsAsIfUser(ASI);
|
ASI_N = 0x4,
|
||||||
bool AsiIsIO(ASI);
|
// 0x05-0x0B implementation dependent
|
||||||
bool AsiIsReal(ASI);
|
ASI_NL = 0xC,
|
||||||
bool AsiIsLittle(ASI);
|
ASI_NUCLEUS_LITTLE = ASI_NL,
|
||||||
bool AsiIsTwin(ASI);
|
// 0x0D-0x0F implementation dependent
|
||||||
bool AsiIsPartialStore(ASI);
|
ASI_AIUP = 0x10,
|
||||||
bool AsiIsFloatingLoad(ASI);
|
ASI_AS_IF_USER_PRIMARY = ASI_AIUP,
|
||||||
bool AsiIsNoFault(ASI);
|
ASI_AIUS = 0x11,
|
||||||
bool AsiIsScratchPad(ASI);
|
ASI_AS_IF_USER_SECONDARY = ASI_AIUS,
|
||||||
bool AsiIsCmt(ASI);
|
// 0x12-0x13 implementation dependent
|
||||||
bool AsiIsQueue(ASI);
|
ASI_REAL = 0x14,
|
||||||
bool AsiIsDtlb(ASI);
|
ASI_REAL_IO = 0x15,
|
||||||
bool AsiIsMmu(ASI);
|
ASI_BLK_AIUP = 0x16,
|
||||||
bool AsiIsUnPriv(ASI);
|
ASI_BLOCK_AS_IF_USER_PRIMARY = ASI_BLK_AIUP,
|
||||||
bool AsiIsPriv(ASI);
|
ASI_BLK_AIUS = 0x17,
|
||||||
bool AsiIsHPriv(ASI);
|
ASI_BLOCK_AS_IF_USER_SECONDARY = ASI_BLK_AIUS,
|
||||||
bool AsiIsReg(ASI);
|
ASI_AIUP_L = 0x18,
|
||||||
bool AsiIsInterrupt(ASI);
|
ASI_AS_IF_USER_PRIMARY_LITTLE = ASI_AIUP_L,
|
||||||
bool AsiIsSparcError(ASI);
|
ASI_AIUS_L = 0x19,
|
||||||
|
ASI_AS_IF_USER_SECONDARY_LITTLE = ASI_AIUS_L,
|
||||||
|
// 0x1A-0x1B implementation dependent
|
||||||
|
ASI_REAL_L = 0x1C,
|
||||||
|
ASI_REAL_LITTLE = ASI_REAL_L,
|
||||||
|
ASI_REAL_IO_L = 0x1D,
|
||||||
|
ASI_REAL_IO_LITTLE = ASI_REAL_IO_L,
|
||||||
|
ASI_BLK_AIUP_L = 0x1E,
|
||||||
|
ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE = ASI_BLK_AIUP_L,
|
||||||
|
ASI_BLK_AIUS_L = 0x1F,
|
||||||
|
ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE = ASI_BLK_AIUS_L,
|
||||||
|
ASI_SCRATCHPAD = 0x20,
|
||||||
|
ASI_MMU = 0x21,
|
||||||
|
ASI_LDTX_AIUP = 0x22,
|
||||||
|
ASI_LD_TWINX_AS_IF_USER_PRIMARY = ASI_LDTX_AIUP,
|
||||||
|
ASI_LDTX_AIUS = 0x23,
|
||||||
|
ASI_LD_TWINX_AS_IF_USER_SECONDARY = ASI_LDTX_AIUS,
|
||||||
|
ASI_QUAD_LDD = 0x24,
|
||||||
|
ASI_QUEUE = 0x25,
|
||||||
|
ASI_QUAD_LDD_REAL = 0x26,
|
||||||
|
ASI_LDTX_REAL = ASI_QUAD_LDD_REAL,
|
||||||
|
ASI_LDTX_N = 0x27,
|
||||||
|
ASI_LD_TWINX_NUCLEUS = ASI_LDTX_N,
|
||||||
|
ASI_ST_BLKINIT_NUCLEUS = ASI_LDTX_N,
|
||||||
|
ASI_STBI_N = ASI_LDTX_N,
|
||||||
|
// 0x28-0x29 implementation dependent
|
||||||
|
ASI_LDTX_AIUP_L = 0x2A,
|
||||||
|
ASI_TWINX_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
|
||||||
|
ASI_ST_BLKINIT_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
|
||||||
|
ASI_STBI_AIUP_L = ASI_LDTX_AIUP_L,
|
||||||
|
ASI_LDTX_AIUS_L = 0x2B,
|
||||||
|
ASI_LD_TWINX_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
|
||||||
|
ASI_ST_BLKINIT_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
|
||||||
|
ASI_STBI_AIUS_L = ASI_LDTX_AIUS_L,
|
||||||
|
ASI_LTX_L = 0x2C,
|
||||||
|
ASI_TWINX_LITTLE = ASI_LTX_L,
|
||||||
|
// 0x2D implementation dependent
|
||||||
|
ASI_LDTX_REAL_L = 0x2E,
|
||||||
|
ASI_LD_TWINX_REAL_LITTLE = ASI_LDTX_REAL_L,
|
||||||
|
ASI_LDTX_NL = 0x2F,
|
||||||
|
ASI_LD_TWINX_NUCLEUS_LITTLE = ASI_LDTX_NL,
|
||||||
|
// 0x20 implementation dependent
|
||||||
|
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x31,
|
||||||
|
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x32,
|
||||||
|
ASI_DMMU_CTXT_ZERO_CONFIG = 0x33,
|
||||||
|
// 0x34 implementation dependent
|
||||||
|
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x35,
|
||||||
|
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x36,
|
||||||
|
ASI_IMMU_CTXT_ZERO_CONFIG = 0x37,
|
||||||
|
// 0x38 implementation dependent
|
||||||
|
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x39,
|
||||||
|
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3A,
|
||||||
|
ASI_DMMU_CTXT_NONZERO_CONFIG = 0x3B,
|
||||||
|
// 0x3C implementation dependent
|
||||||
|
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x3D,
|
||||||
|
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3E,
|
||||||
|
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
|
||||||
|
ASI_STREAM_MA = 0x40,
|
||||||
|
ASI_CMT_SHARED = 0x41,
|
||||||
|
// 0x41 implementation dependent
|
||||||
|
ASI_SPARC_BIST_CONTROL = 0x42,
|
||||||
|
ASI_INST_MASK_REG = 0x42,
|
||||||
|
ASI_LSU_DIAG_REG = 0x42,
|
||||||
|
// 0x43 implementation dependent
|
||||||
|
ASI_STM_CTL_REG = 0x44,
|
||||||
|
ASI_LSU_CONTROL_REG = 0x45,
|
||||||
|
ASI_DCACHE_DATA = 0x46,
|
||||||
|
ASI_DCACHE_TAG = 0x47,
|
||||||
|
ASI_INTR_DISPATCH_STATUS = 0x48,
|
||||||
|
ASI_INTR_RECEIVE = 0x49,
|
||||||
|
ASI_UPA_CONFIG_REGISTER = 0x4A,
|
||||||
|
ASI_SPARC_ERROR_EN_REG = 0x4B,
|
||||||
|
ASI_SPARC_ERROR_STATUS_REG = 0x4C,
|
||||||
|
ASI_SPARC_ERROR_ADDRESS_REG = 0x4D,
|
||||||
|
ASI_ECACHE_TAG_DATA = 0x4E,
|
||||||
|
ASI_HYP_SCRATCHPAD = 0x4F,
|
||||||
|
ASI_IMMU = 0x50,
|
||||||
|
ASI_IMMU_TSB_PS0_PTR_REG = 0x51,
|
||||||
|
ASI_IMMU_TSB_PS1_PTR_REG = 0x52,
|
||||||
|
// 0x53 implementation dependent
|
||||||
|
ASI_ITLB_DATA_IN_REG = 0x54,
|
||||||
|
ASI_ITLB_DATA_ACCESS_REG = 0x55,
|
||||||
|
ASI_ITLB_TAG_READ_REG = 0x56,
|
||||||
|
ASI_IMMU_DEMAP = 0x57,
|
||||||
|
ASI_DMMU = 0x58,
|
||||||
|
ASI_DMMU_TSB_PS0_PTR_REG = 0x59,
|
||||||
|
ASI_DMMU_TSB_PS1_PTR_REG = 0x5A,
|
||||||
|
ASI_DMMU_TSB_DIRECT_PTR_REG = 0x5B,
|
||||||
|
ASI_DTLB_DATA_IN_REG = 0x5C,
|
||||||
|
ASI_DTLB_DATA_ACCESS_REG = 0x5D,
|
||||||
|
ASI_DTLB_TAG_READ_REG = 0x5E,
|
||||||
|
ASI_DMMU_DEMAP = 0x5F,
|
||||||
|
ASI_TLB_INVALIDATE_ALL = 0x60,
|
||||||
|
// 0x61-0x62 implementation dependent
|
||||||
|
ASI_CMT_PER_STRAND = 0x63,
|
||||||
|
// 0x64-0x65 implementation dependent
|
||||||
|
ASI_ICACHE_INSTR = 0x66,
|
||||||
|
ASI_ICACHE_TAG = 0x67,
|
||||||
|
// 0x68-0x71 implementation dependent
|
||||||
|
ASI_SWVR_INTR_RECEIVE = 0x72,
|
||||||
|
ASI_SWVR_UDB_INTR_W = 0x73,
|
||||||
|
ASI_SWVR_UDB_INTR_R = 0x74,
|
||||||
|
// 0x74-0x7F reserved
|
||||||
|
/* Unpriveleged ASIs */
|
||||||
|
ASI_P = 0x80,
|
||||||
|
ASI_PRIMARY = ASI_P,
|
||||||
|
ASI_S = 0x81,
|
||||||
|
ASI_SECONDARY = ASI_S,
|
||||||
|
ASI_PNF = 0x82,
|
||||||
|
ASI_PRIMARY_NO_FAULT = ASI_PNF,
|
||||||
|
ASI_SNF = 0x83,
|
||||||
|
ASI_SECONDARY_NO_FAULT = ASI_SNF,
|
||||||
|
// 0x84-0x87 reserved
|
||||||
|
ASI_PL = 0x88,
|
||||||
|
ASI_PRIMARY_LITTLE = ASI_PL,
|
||||||
|
ASI_SL = 0x89,
|
||||||
|
ASI_SECONDARY_LITTLE = ASI_SL,
|
||||||
|
ASI_PNFL = 0x8A,
|
||||||
|
ASI_PRIMARY_NO_FAULT_LITTLE = ASI_PNFL,
|
||||||
|
ASI_SNFL = 0x8B,
|
||||||
|
ASI_SECONDARY_NO_FAULT_LITTLE = ASI_SNFL,
|
||||||
|
// 0x8C-0xBF reserved
|
||||||
|
ASI_PST8_P = 0xC0,
|
||||||
|
ASI_PST8_PRIMARY = ASI_PST8_P,
|
||||||
|
ASI_PST8_S = 0xC1,
|
||||||
|
ASI_PST8_SECONDARY = ASI_PST8_S,
|
||||||
|
ASI_PST16_P = 0xC2,
|
||||||
|
ASI_PST16_PRIMARY = ASI_PST16_P,
|
||||||
|
ASI_PST16_S = 0xC3,
|
||||||
|
ASI_PST16_SECONDARY = ASI_PST16_S,
|
||||||
|
ASI_PST32_P = 0xC4,
|
||||||
|
ASI_PST32_PRIMARY = ASI_PST32_P,
|
||||||
|
ASI_PST32_S = 0xC5,
|
||||||
|
ASI_PST32_SECONDARY = ASI_PST32_S,
|
||||||
|
// 0xC6-0xC7 implementation dependent
|
||||||
|
ASI_PST8_PL = 0xC8,
|
||||||
|
ASI_PST8_PRIMARY_LITTLE = ASI_PST8_PL,
|
||||||
|
ASI_PST8_SL = 0xC9,
|
||||||
|
ASI_PST8_SECONDARY_LITTLE = ASI_PST8_SL,
|
||||||
|
ASI_PST16_PL = 0xCA,
|
||||||
|
ASI_PST16_PRIMARY_LITTLE = ASI_PST16_PL,
|
||||||
|
ASI_PST16_SL = 0xCB,
|
||||||
|
ASI_PST16_SECONDARY_LITTLE = ASI_PST16_SL,
|
||||||
|
ASI_PST32_PL = 0xCC,
|
||||||
|
ASI_PST32_PRIMARY_LITTLE = ASI_PST32_PL,
|
||||||
|
ASI_PST32_SL = 0xCD,
|
||||||
|
ASI_PST32_SECONDARY_LITTLE = ASI_PST32_SL,
|
||||||
|
// 0xCE-0xCF implementation dependent
|
||||||
|
ASI_FL8_P = 0xD0,
|
||||||
|
ASI_FL8_PRIMARY = ASI_FL8_P,
|
||||||
|
ASI_FL8_S = 0xD1,
|
||||||
|
ASI_FL8_SECONDARY = ASI_FL8_S,
|
||||||
|
ASI_FL16_P = 0xD2,
|
||||||
|
ASI_FL16_PRIMARY = ASI_FL16_P,
|
||||||
|
ASI_FL16_S = 0xD3,
|
||||||
|
ASI_FL16_SECONDARY = ASI_FL16_S,
|
||||||
|
// 0xD4-0xD7 implementation dependent
|
||||||
|
ASI_FL8_PL = 0xD8,
|
||||||
|
ASI_FL8_PRIMARY_LITTLE = ASI_FL8_PL,
|
||||||
|
ASI_FL8_SL = 0xD9,
|
||||||
|
ASI_FL8_SECONDARY_LITTLE = ASI_FL8_SL,
|
||||||
|
ASI_FL16_PL = 0xDA,
|
||||||
|
ASI_FL16_PRIMARY_LITTLE = ASI_FL16_PL,
|
||||||
|
ASI_FL16_SL = 0xDB,
|
||||||
|
ASI_FL16_SECONDARY_LITTLE = ASI_FL16_SL,
|
||||||
|
// 0xDC-0xDF implementation dependent
|
||||||
|
// 0xE0-0xE1 reserved
|
||||||
|
ASI_LDTX_P = 0xE2,
|
||||||
|
ASI_LD_TWINX_PRIMARY = ASI_LDTX_P,
|
||||||
|
ASI_LDTX_S = 0xE3,
|
||||||
|
ASI_LD_TWINX_SECONDARY = ASI_LDTX_S,
|
||||||
|
// 0xE4-0xE9 implementation dependent
|
||||||
|
ASI_LDTX_PL = 0xEA,
|
||||||
|
ASI_LD_TWINX_PRIMARY_LITTLE = ASI_LDTX_PL,
|
||||||
|
ASI_LDTX_SL = 0xEB,
|
||||||
|
ASI_LD_TWINX_SECONDARY_LITTLE = ASI_LDTX_SL,
|
||||||
|
// 0xEC-0xEF implementation dependent
|
||||||
|
ASI_BLK_P = 0xF0,
|
||||||
|
ASI_BLOCK_PRIMARY = ASI_BLK_P,
|
||||||
|
ASI_BLK_S = 0xF1,
|
||||||
|
ASI_BLOCK_SECONDARY = ASI_BLK_S,
|
||||||
|
// 0xF2-0xF7 implementation dependent
|
||||||
|
ASI_BLK_PL = 0xF8,
|
||||||
|
ASI_BLOCK_PRIMARY_LITTLE = ASI_BLK_PL,
|
||||||
|
ASI_BLK_SL = 0xF9,
|
||||||
|
ASI_BLOCK_SECONDARY_LITTLE = ASI_BLK_SL,
|
||||||
|
// 0xFA-0xFF implementation dependent
|
||||||
|
MAX_ASI = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions that classify an asi
|
||||||
|
bool asiIsBlock(ASI);
|
||||||
|
bool asiIsPrimary(ASI);
|
||||||
|
bool asiIsSecondary(ASI);
|
||||||
|
bool asiIsNucleus(ASI);
|
||||||
|
bool asiIsAsIfUser(ASI);
|
||||||
|
bool asiIsIO(ASI);
|
||||||
|
bool asiIsReal(ASI);
|
||||||
|
bool asiIsLittle(ASI);
|
||||||
|
bool asiIsTwin(ASI);
|
||||||
|
bool asiIsPartialStore(ASI);
|
||||||
|
bool asiIsFloatingLoad(ASI);
|
||||||
|
bool asiIsNoFault(ASI);
|
||||||
|
bool asiIsScratchPad(ASI);
|
||||||
|
bool asiIsCmt(ASI);
|
||||||
|
bool asiIsQueue(ASI);
|
||||||
|
bool asiIsDtlb(ASI);
|
||||||
|
bool asiIsMmu(ASI);
|
||||||
|
bool asiIsUnPriv(ASI);
|
||||||
|
bool asiIsPriv(ASI);
|
||||||
|
bool asiIsHPriv(ASI);
|
||||||
|
bool asiIsReg(ASI);
|
||||||
|
bool asiIsInterrupt(ASI);
|
||||||
|
bool asiIsSparcError(ASI);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_SPARC_ASI_HH__
|
#endif // __ARCH_SPARC_ASI_HH__
|
||||||
|
|
|
@ -272,18 +272,19 @@ template<> SparcFaultBase::FaultVals
|
||||||
* effects which go with entering RED state because of a trap.
|
* effects which go with entering RED state because of a trap.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void enterREDState(ThreadContext *tc)
|
void
|
||||||
|
enterREDState(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
//@todo Disable the mmu?
|
//@todo Disable the mmu?
|
||||||
//@todo Disable watchpoints?
|
//@todo Disable watchpoints?
|
||||||
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
||||||
//HPSTATE.red = 1
|
// HPSTATE.red = 1
|
||||||
HPSTATE |= (1 << 5);
|
HPSTATE |= (1 << 5);
|
||||||
//HPSTATE.hpriv = 1
|
// HPSTATE.hpriv = 1
|
||||||
HPSTATE |= (1 << 2);
|
HPSTATE |= (1 << 2);
|
||||||
tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
|
tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
|
||||||
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
|
// PSTATE.priv is set to 1 here. The manual says it should be 0, but
|
||||||
//Legion sets it to 1.
|
// Legion sets it to 1.
|
||||||
MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
||||||
PSTATE |= (1 << 2);
|
PSTATE |= (1 << 2);
|
||||||
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
|
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
|
||||||
|
@ -294,17 +295,16 @@ void enterREDState(ThreadContext *tc)
|
||||||
* the handler.
|
* the handler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void doREDFault(ThreadContext *tc, TrapType tt)
|
void
|
||||||
|
doREDFault(ThreadContext *tc, TrapType tt)
|
||||||
{
|
{
|
||||||
MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
|
MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
|
||||||
MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
|
MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
|
||||||
MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
||||||
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
||||||
//MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR);
|
|
||||||
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
|
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
|
||||||
MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
|
MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
|
||||||
MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
|
MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
|
||||||
//MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE);
|
|
||||||
MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
|
MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
|
||||||
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
|
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
|
||||||
PCState pc = tc->pcState();
|
PCState pc = tc->pcState();
|
||||||
|
@ -313,60 +313,59 @@ void doREDFault(ThreadContext *tc, TrapType tt)
|
||||||
|
|
||||||
Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
|
Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
|
||||||
|
|
||||||
//set TSTATE.gl to gl
|
// set TSTATE.gl to gl
|
||||||
replaceBits(TSTATE, 42, 40, GL);
|
replaceBits(TSTATE, 42, 40, GL);
|
||||||
//set TSTATE.ccr to ccr
|
// set TSTATE.ccr to ccr
|
||||||
replaceBits(TSTATE, 39, 32, CCR);
|
replaceBits(TSTATE, 39, 32, CCR);
|
||||||
//set TSTATE.asi to asi
|
// set TSTATE.asi to asi
|
||||||
replaceBits(TSTATE, 31, 24, ASI);
|
replaceBits(TSTATE, 31, 24, ASI);
|
||||||
//set TSTATE.pstate to pstate
|
// set TSTATE.pstate to pstate
|
||||||
replaceBits(TSTATE, 20, 8, PSTATE);
|
replaceBits(TSTATE, 20, 8, PSTATE);
|
||||||
//set TSTATE.cwp to cwp
|
// set TSTATE.cwp to cwp
|
||||||
replaceBits(TSTATE, 4, 0, CWP);
|
replaceBits(TSTATE, 4, 0, CWP);
|
||||||
|
|
||||||
//Write back TSTATE
|
// Write back TSTATE
|
||||||
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
|
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
|
||||||
|
|
||||||
//set TPC to PC
|
// set TPC to PC
|
||||||
tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
|
tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
|
||||||
//set TNPC to NPC
|
// set TNPC to NPC
|
||||||
tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
|
tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
|
||||||
|
|
||||||
//set HTSTATE.hpstate to hpstate
|
// set HTSTATE.hpstate to hpstate
|
||||||
tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
|
tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
|
||||||
|
|
||||||
//TT = trap type;
|
// TT = trap type;
|
||||||
tc->setMiscRegNoEffect(MISCREG_TT, tt);
|
tc->setMiscRegNoEffect(MISCREG_TT, tt);
|
||||||
|
|
||||||
//Update GL
|
// Update GL
|
||||||
tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
|
tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
|
||||||
|
|
||||||
PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
|
PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
|
||||||
PSTATE |= (1 << 4); //set PSTATE.pef to 1
|
PSTATE |= (1 << 4); // set PSTATE.pef to 1
|
||||||
tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
|
tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
|
||||||
|
|
||||||
//set HPSTATE.red to 1
|
// set HPSTATE.red to 1
|
||||||
HPSTATE |= (1 << 5);
|
HPSTATE |= (1 << 5);
|
||||||
//set HPSTATE.hpriv to 1
|
// set HPSTATE.hpriv to 1
|
||||||
HPSTATE |= (1 << 2);
|
HPSTATE |= (1 << 2);
|
||||||
//set HPSTATE.ibe to 0
|
// set HPSTATE.ibe to 0
|
||||||
HPSTATE &= ~(1 << 10);
|
HPSTATE &= ~(1 << 10);
|
||||||
//set HPSTATE.tlz to 0
|
// set HPSTATE.tlz to 0
|
||||||
HPSTATE &= ~(1 << 0);
|
HPSTATE &= ~(1 << 0);
|
||||||
tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
|
tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
|
||||||
|
|
||||||
bool changedCWP = true;
|
bool changedCWP = true;
|
||||||
if(tt == 0x24)
|
if (tt == 0x24)
|
||||||
CWP++;
|
CWP++;
|
||||||
else if(0x80 <= tt && tt <= 0xbf)
|
else if (0x80 <= tt && tt <= 0xbf)
|
||||||
CWP += (CANSAVE + 2);
|
CWP += (CANSAVE + 2);
|
||||||
else if(0xc0 <= tt && tt <= 0xff)
|
else if (0xc0 <= tt && tt <= 0xff)
|
||||||
CWP--;
|
CWP--;
|
||||||
else
|
else
|
||||||
changedCWP = false;
|
changedCWP = false;
|
||||||
|
|
||||||
if(changedCWP)
|
if (changedCWP) {
|
||||||
{
|
|
||||||
CWP = (CWP + NWindows) % NWindows;
|
CWP = (CWP + NWindows) % NWindows;
|
||||||
tc->setMiscReg(MISCREG_CWP, CWP);
|
tc->setMiscReg(MISCREG_CWP, CWP);
|
||||||
}
|
}
|
||||||
|
@ -377,79 +376,77 @@ void doREDFault(ThreadContext *tc, TrapType tt)
|
||||||
* the handler.
|
* the handler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
void
|
||||||
|
doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
{
|
{
|
||||||
MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
|
MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
|
||||||
MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
|
MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
|
||||||
MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
||||||
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
||||||
//MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR);
|
|
||||||
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
|
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
|
||||||
MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
|
MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
|
||||||
MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
|
MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
|
||||||
//MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE);
|
|
||||||
MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
|
MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
|
||||||
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
|
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
|
||||||
PCState pc = tc->pcState();
|
PCState pc = tc->pcState();
|
||||||
|
|
||||||
//Increment the trap level
|
// Increment the trap level
|
||||||
TL++;
|
TL++;
|
||||||
tc->setMiscRegNoEffect(MISCREG_TL, TL);
|
tc->setMiscRegNoEffect(MISCREG_TL, TL);
|
||||||
|
|
||||||
Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
|
Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
|
||||||
|
|
||||||
//Save off state
|
// Save off state
|
||||||
|
|
||||||
//set TSTATE.gl to gl
|
// set TSTATE.gl to gl
|
||||||
replaceBits(TSTATE, 42, 40, GL);
|
replaceBits(TSTATE, 42, 40, GL);
|
||||||
//set TSTATE.ccr to ccr
|
// set TSTATE.ccr to ccr
|
||||||
replaceBits(TSTATE, 39, 32, CCR);
|
replaceBits(TSTATE, 39, 32, CCR);
|
||||||
//set TSTATE.asi to asi
|
// set TSTATE.asi to asi
|
||||||
replaceBits(TSTATE, 31, 24, ASI);
|
replaceBits(TSTATE, 31, 24, ASI);
|
||||||
//set TSTATE.pstate to pstate
|
// set TSTATE.pstate to pstate
|
||||||
replaceBits(TSTATE, 20, 8, PSTATE);
|
replaceBits(TSTATE, 20, 8, PSTATE);
|
||||||
//set TSTATE.cwp to cwp
|
// set TSTATE.cwp to cwp
|
||||||
replaceBits(TSTATE, 4, 0, CWP);
|
replaceBits(TSTATE, 4, 0, CWP);
|
||||||
|
|
||||||
//Write back TSTATE
|
// Write back TSTATE
|
||||||
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
|
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
|
||||||
|
|
||||||
//set TPC to PC
|
// set TPC to PC
|
||||||
tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
|
tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
|
||||||
//set TNPC to NPC
|
// set TNPC to NPC
|
||||||
tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
|
tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
|
||||||
|
|
||||||
//set HTSTATE.hpstate to hpstate
|
// set HTSTATE.hpstate to hpstate
|
||||||
tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
|
tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
|
||||||
|
|
||||||
//TT = trap type;
|
// TT = trap type;
|
||||||
tc->setMiscRegNoEffect(MISCREG_TT, tt);
|
tc->setMiscRegNoEffect(MISCREG_TT, tt);
|
||||||
|
|
||||||
//Update the global register level
|
// Update the global register level
|
||||||
if (!gotoHpriv)
|
if (!gotoHpriv)
|
||||||
tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL));
|
tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL));
|
||||||
else
|
else
|
||||||
tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
|
tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL));
|
||||||
|
|
||||||
//PSTATE.mm is unchanged
|
// PSTATE.mm is unchanged
|
||||||
PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present
|
PSTATE |= (1 << 4); // PSTATE.pef = whether or not an fpu is present
|
||||||
PSTATE &= ~(1 << 3); //PSTATE.am = 0
|
PSTATE &= ~(1 << 3); // PSTATE.am = 0
|
||||||
PSTATE &= ~(1 << 1); //PSTATE.ie = 0
|
PSTATE &= ~(1 << 1); // PSTATE.ie = 0
|
||||||
//PSTATE.tle is unchanged
|
// PSTATE.tle is unchanged
|
||||||
//PSTATE.tct = 0
|
// PSTATE.tct = 0
|
||||||
|
|
||||||
if (gotoHpriv)
|
if (gotoHpriv) {
|
||||||
{
|
|
||||||
PSTATE &= ~(1 << 9); // PSTATE.cle = 0
|
PSTATE &= ~(1 << 9); // PSTATE.cle = 0
|
||||||
//The manual says PSTATE.priv should be 0, but Legion leaves it alone
|
// The manual says PSTATE.priv should be 0, but Legion leaves it alone
|
||||||
HPSTATE &= ~(1 << 5); //HPSTATE.red = 0
|
HPSTATE &= ~(1 << 5); // HPSTATE.red = 0
|
||||||
HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1
|
HPSTATE |= (1 << 2); // HPSTATE.hpriv = 1
|
||||||
HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0
|
HPSTATE &= ~(1 << 10); // HPSTATE.ibe = 0
|
||||||
//HPSTATE.tlz is unchanged
|
// HPSTATE.tlz is unchanged
|
||||||
tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
|
tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
|
||||||
} else { // we are going to priv
|
} else { // we are going to priv
|
||||||
PSTATE |= (1 << 2); //PSTATE.priv = 1
|
PSTATE |= (1 << 2); // PSTATE.priv = 1
|
||||||
replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle
|
replaceBits(PSTATE, 9, 9, PSTATE >> 8); // PSTATE.cle = PSTATE.tle
|
||||||
}
|
}
|
||||||
tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
|
tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
|
||||||
|
|
||||||
|
@ -464,14 +461,14 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
else
|
else
|
||||||
changedCWP = false;
|
changedCWP = false;
|
||||||
|
|
||||||
if (changedCWP)
|
if (changedCWP) {
|
||||||
{
|
|
||||||
CWP = (CWP + NWindows) % NWindows;
|
CWP = (CWP + NWindows) % NWindows;
|
||||||
tc->setMiscReg(MISCREG_CWP, CWP);
|
tc->setMiscReg(MISCREG_CWP, CWP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getREDVector(MiscReg TT, Addr &PC, Addr &NPC)
|
void
|
||||||
|
getREDVector(MiscReg TT, Addr &PC, Addr &NPC)
|
||||||
{
|
{
|
||||||
//XXX The following constant might belong in a header file.
|
//XXX The following constant might belong in a header file.
|
||||||
const Addr RSTVAddr = 0xFFF0000000ULL;
|
const Addr RSTVAddr = 0xFFF0000000ULL;
|
||||||
|
@ -479,14 +476,16 @@ void getREDVector(MiscReg TT, Addr &PC, Addr &NPC)
|
||||||
NPC = PC + sizeof(MachInst);
|
NPC = PC + sizeof(MachInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT)
|
void
|
||||||
|
getHyperVector(ThreadContext * tc, Addr &PC, Addr &NPC, MiscReg TT)
|
||||||
{
|
{
|
||||||
Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA);
|
Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA);
|
||||||
PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
|
PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
|
||||||
NPC = PC + sizeof(MachInst);
|
NPC = PC + sizeof(MachInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL)
|
void
|
||||||
|
getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, MiscReg TT, MiscReg TL)
|
||||||
{
|
{
|
||||||
Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA);
|
Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA);
|
||||||
PC = (TBA & ~mask(15)) |
|
PC = (TBA & ~mask(15)) |
|
||||||
|
@ -497,14 +496,14 @@ void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscRe
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
void SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
void
|
||||||
|
SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
//panic("Invoking a second fault!\n");
|
|
||||||
FaultBase::invoke(tc);
|
FaultBase::invoke(tc);
|
||||||
countStat()++;
|
countStat()++;
|
||||||
|
|
||||||
//We can refer to this to see what the trap level -was-, but something
|
// 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.
|
// in the middle could change it in the regfile out from under us.
|
||||||
MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
|
MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
|
||||||
MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT);
|
MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT);
|
||||||
MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
||||||
|
@ -525,16 +524,16 @@ void SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) {
|
if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) {
|
||||||
getREDVector(5, PC, NPC);
|
getREDVector(5, PC, NPC);
|
||||||
doREDFault(tc, tt);
|
doREDFault(tc, tt);
|
||||||
//This changes the hpstate and pstate, so we need to make sure we
|
// This changes the hpstate and pstate, so we need to make sure we
|
||||||
//save the old version on the trap stack in doREDFault.
|
// save the old version on the trap stack in doREDFault.
|
||||||
enterREDState(tc);
|
enterREDState(tc);
|
||||||
} else if (tl == MaxTL) {
|
} else if (tl == MaxTL) {
|
||||||
panic("Should go to error state here.. crap\n");
|
panic("Should go to error state here.. crap\n");
|
||||||
//Do error_state somehow?
|
// Do error_state somehow?
|
||||||
//Probably inject a WDR fault using the interrupt mechanism.
|
// Probably inject a WDR fault using the interrupt mechanism.
|
||||||
//What should the PC and NPC be set to?
|
// What should the PC and NPC be set to?
|
||||||
} else if (tl > MaxPTL && level == Privileged) {
|
} else if (tl > MaxPTL && level == Privileged) {
|
||||||
//guest_watchdog fault
|
// guest_watchdog fault
|
||||||
doNormalFault(tc, trapType(), true);
|
doNormalFault(tc, trapType(), true);
|
||||||
getHyperVector(tc, PC, NPC, 2);
|
getHyperVector(tc, PC, NPC, 2);
|
||||||
} else if (level == Hyperprivileged ||
|
} else if (level == Hyperprivileged ||
|
||||||
|
@ -543,7 +542,7 @@ void SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
getHyperVector(tc, PC, NPC, trapType());
|
getHyperVector(tc, PC, NPC, trapType());
|
||||||
} else {
|
} else {
|
||||||
doNormalFault(tc, trapType(), false);
|
doNormalFault(tc, trapType(), false);
|
||||||
getPrivVector(tc, PC, NPC, trapType(), tl+1);
|
getPrivVector(tc, PC, NPC, trapType(), tl + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCState pc;
|
PCState pc;
|
||||||
|
@ -555,36 +554,37 @@ void SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
tc->pcState(pc);
|
tc->pcState(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst)
|
void
|
||||||
|
PowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
//For SPARC, when a system is first started, there is a power
|
// For SPARC, when a system is first started, there is a power
|
||||||
//on reset Trap which sets the processor into the following state.
|
// on reset Trap which sets the processor into the following state.
|
||||||
//Bits that aren't set aren't defined on startup.
|
// Bits that aren't set aren't defined on startup.
|
||||||
|
|
||||||
tc->setMiscRegNoEffect(MISCREG_TL, MaxTL);
|
tc->setMiscRegNoEffect(MISCREG_TL, MaxTL);
|
||||||
tc->setMiscRegNoEffect(MISCREG_TT, trapType());
|
tc->setMiscRegNoEffect(MISCREG_TT, trapType());
|
||||||
tc->setMiscReg(MISCREG_GL, MaxGL);
|
tc->setMiscReg(MISCREG_GL, MaxGL);
|
||||||
|
|
||||||
//Turn on pef and priv, set everything else to 0
|
// Turn on pef and priv, set everything else to 0
|
||||||
tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2));
|
tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2));
|
||||||
|
|
||||||
//Turn on red and hpriv, set everything else to 0
|
// Turn on red and hpriv, set everything else to 0
|
||||||
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
||||||
//HPSTATE.red = 1
|
// HPSTATE.red = 1
|
||||||
HPSTATE |= (1 << 5);
|
HPSTATE |= (1 << 5);
|
||||||
//HPSTATE.hpriv = 1
|
// HPSTATE.hpriv = 1
|
||||||
HPSTATE |= (1 << 2);
|
HPSTATE |= (1 << 2);
|
||||||
//HPSTATE.ibe = 0
|
// HPSTATE.ibe = 0
|
||||||
HPSTATE &= ~(1 << 10);
|
HPSTATE &= ~(1 << 10);
|
||||||
//HPSTATE.tlz = 0
|
// HPSTATE.tlz = 0
|
||||||
HPSTATE &= ~(1 << 0);
|
HPSTATE &= ~(1 << 0);
|
||||||
tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
|
tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
|
||||||
|
|
||||||
//The tick register is unreadable by nonprivileged software
|
// The tick register is unreadable by nonprivileged software
|
||||||
tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
|
tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
|
||||||
|
|
||||||
//Enter RED state. We do this last so that the actual state preserved in
|
// Enter RED state. We do this last so that the actual state preserved in
|
||||||
//the trap stack is the state from before this fault.
|
// the trap stack is the state from before this fault.
|
||||||
enterREDState(tc);
|
enterREDState(tc);
|
||||||
|
|
||||||
Addr PC, NPC;
|
Addr PC, NPC;
|
||||||
|
@ -598,8 +598,8 @@ void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
pc.nupc(1);
|
pc.nupc(1);
|
||||||
tc->pcState(pc);
|
tc->pcState(pc);
|
||||||
|
|
||||||
//These registers are specified as "undefined" after a POR, and they
|
// These registers are specified as "undefined" after a POR, and they
|
||||||
//should have reasonable values after the miscregfile is reset
|
// should have reasonable values after the miscregfile is reset
|
||||||
/*
|
/*
|
||||||
// Clear all the soft interrupt bits
|
// Clear all the soft interrupt bits
|
||||||
softint = 0;
|
softint = 0;
|
||||||
|
@ -607,7 +607,7 @@ void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
tc->setMiscRegNoEffect(MISCREG_
|
tc->setMiscRegNoEffect(MISCREG_
|
||||||
tick_cmprFields.int_dis = 1;
|
tick_cmprFields.int_dis = 1;
|
||||||
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
||||||
stickFields.npt = 1; //The TICK register is unreadable by by !priv
|
stickFields.npt = 1; // The TICK register is unreadable by by !priv
|
||||||
stick_cmprFields.int_dis = 1; // disable timer compare interrupts
|
stick_cmprFields.int_dis = 1; // disable timer compare interrupts
|
||||||
stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
|
||||||
|
|
||||||
|
@ -621,13 +621,13 @@ void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
|
|
||||||
#else // !FULL_SYSTEM
|
#else // !FULL_SYSTEM
|
||||||
|
|
||||||
void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc,
|
void
|
||||||
StaticInstPtr inst)
|
FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
Process *p = tc->getProcessPtr();
|
Process *p = tc->getProcessPtr();
|
||||||
TlbEntry entry;
|
TlbEntry entry;
|
||||||
bool success = p->pTable->lookup(vaddr, entry);
|
bool success = p->pTable->lookup(vaddr, entry);
|
||||||
if(!success) {
|
if (!success) {
|
||||||
panic("Tried to execute unmapped address %#x.\n", vaddr);
|
panic("Tried to execute unmapped address %#x.\n", vaddr);
|
||||||
} else {
|
} else {
|
||||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||||
|
@ -636,16 +636,17 @@ void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
|
void
|
||||||
|
FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
Process *p = tc->getProcessPtr();
|
Process *p = tc->getProcessPtr();
|
||||||
TlbEntry entry;
|
TlbEntry entry;
|
||||||
bool success = p->pTable->lookup(vaddr, entry);
|
bool success = p->pTable->lookup(vaddr, entry);
|
||||||
if(!success) {
|
if (!success) {
|
||||||
p->checkAndAllocNextPage(vaddr);
|
p->checkAndAllocNextPage(vaddr);
|
||||||
success = p->pTable->lookup(vaddr, entry);
|
success = p->pTable->lookup(vaddr, entry);
|
||||||
}
|
}
|
||||||
if(!success) {
|
if (!success) {
|
||||||
panic("Tried to access unmapped address %#x.\n", vaddr);
|
panic("Tried to access unmapped address %#x.\n", vaddr);
|
||||||
} else {
|
} else {
|
||||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||||
|
@ -654,7 +655,8 @@ void FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
void
|
||||||
|
SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
doNormalFault(tc, trapType(), false);
|
doNormalFault(tc, trapType(), false);
|
||||||
|
|
||||||
|
@ -664,29 +666,31 @@ void SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||||
assert(lp);
|
assert(lp);
|
||||||
|
|
||||||
//Then adjust the PC and NPC
|
// Then adjust the PC and NPC
|
||||||
tc->pcState(lp->readSpillStart());
|
tc->pcState(lp->readSpillStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
void
|
||||||
|
FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
doNormalFault(tc, trapType(), false);
|
doNormalFault(tc, trapType(), false);
|
||||||
|
|
||||||
Process * p = tc->getProcessPtr();
|
Process *p = tc->getProcessPtr();
|
||||||
|
|
||||||
//XXX This will only work in faults from a SparcLiveProcess
|
//XXX This will only work in faults from a SparcLiveProcess
|
||||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||||
assert(lp);
|
assert(lp);
|
||||||
|
|
||||||
//Then adjust the PC and NPC
|
// Then adjust the PC and NPC
|
||||||
tc->pcState(lp->readFillStart());
|
tc->pcState(lp->readFillStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
|
void
|
||||||
|
TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
//In SE, this mechanism is how the process requests a service from the
|
// In SE, this mechanism is how the process requests a service from the
|
||||||
//operating system. We'll get the process object from the thread context
|
// operating system. We'll get the process object from the thread context
|
||||||
//and let it service the request.
|
// and let it service the request.
|
||||||
|
|
||||||
Process *p = tc->getProcessPtr();
|
Process *p = tc->getProcessPtr();
|
||||||
|
|
||||||
|
@ -695,8 +699,8 @@ void TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
|
|
||||||
lp->handleTrap(_n, tc);
|
lp->handleTrap(_n, tc);
|
||||||
|
|
||||||
//We need to explicitly advance the pc, since that's not done for us
|
// We need to explicitly advance the pc, since that's not done for us
|
||||||
//on a faulting instruction
|
// on a faulting instruction
|
||||||
PCState pc = tc->pcState();
|
PCState pc = tc->pcState();
|
||||||
pc.advance();
|
pc.advance();
|
||||||
tc->pcState(pc);
|
tc->pcState(pc);
|
||||||
|
|
|
@ -82,11 +82,13 @@ class SparcFault : public SparcFaultBase
|
||||||
protected:
|
protected:
|
||||||
static FaultVals vals;
|
static FaultVals vals;
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return vals.name;}
|
FaultName name() const { return vals.name; }
|
||||||
TrapType trapType() {return vals.trapType;}
|
TrapType trapType() { return vals.trapType; }
|
||||||
FaultPriority priority() {return vals.priority;}
|
FaultPriority priority() { return vals.priority; }
|
||||||
FaultStat & countStat() {return vals.count;}
|
FaultStat & countStat() { return vals.count; }
|
||||||
PrivilegeLevel getNextLevel(PrivilegeLevel current)
|
|
||||||
|
PrivilegeLevel
|
||||||
|
getNextLevel(PrivilegeLevel current)
|
||||||
{
|
{
|
||||||
return vals.nextPrivilegeLevel[current];
|
return vals.nextPrivilegeLevel[current];
|
||||||
}
|
}
|
||||||
|
@ -112,7 +114,7 @@ class StoreError : public SparcFault<StoreError> {};
|
||||||
|
|
||||||
class InstructionAccessException : public SparcFault<InstructionAccessException> {};
|
class InstructionAccessException : public SparcFault<InstructionAccessException> {};
|
||||||
|
|
||||||
//class InstructionAccessMMUMiss : public SparcFault<InstructionAccessMMUMiss> {};
|
// class InstructionAccessMMUMiss : public SparcFault<InstructionAccessMMUMiss> {};
|
||||||
|
|
||||||
class InstructionAccessError : public SparcFault<InstructionAccessError> {};
|
class InstructionAccessError : public SparcFault<InstructionAccessError> {};
|
||||||
|
|
||||||
|
@ -120,9 +122,9 @@ class IllegalInstruction : public SparcFault<IllegalInstruction> {};
|
||||||
|
|
||||||
class PrivilegedOpcode : public SparcFault<PrivilegedOpcode> {};
|
class PrivilegedOpcode : public SparcFault<PrivilegedOpcode> {};
|
||||||
|
|
||||||
//class UnimplementedLDD : public SparcFault<UnimplementedLDD> {};
|
// class UnimplementedLDD : public SparcFault<UnimplementedLDD> {};
|
||||||
|
|
||||||
//class UnimplementedSTD : public SparcFault<UnimplementedSTD> {};
|
// class UnimplementedSTD : public SparcFault<UnimplementedSTD> {};
|
||||||
|
|
||||||
class FpDisabled : public SparcFault<FpDisabled> {};
|
class FpDisabled : public SparcFault<FpDisabled> {};
|
||||||
|
|
||||||
|
@ -140,16 +142,17 @@ class InternalProcessorError :
|
||||||
public SparcFault<InternalProcessorError>
|
public SparcFault<InternalProcessorError>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isMachineCheckFault() const {return true;}
|
bool isMachineCheckFault() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstructionInvalidTSBEntry : public SparcFault<InstructionInvalidTSBEntry> {};
|
class InstructionInvalidTSBEntry :
|
||||||
|
public SparcFault<InstructionInvalidTSBEntry> {};
|
||||||
|
|
||||||
class DataInvalidTSBEntry : public SparcFault<DataInvalidTSBEntry> {};
|
class DataInvalidTSBEntry : public SparcFault<DataInvalidTSBEntry> {};
|
||||||
|
|
||||||
class DataAccessException : public SparcFault<DataAccessException> {};
|
class DataAccessException : public SparcFault<DataAccessException> {};
|
||||||
|
|
||||||
//class DataAccessMMUMiss : public SparcFault<DataAccessMMUMiss> {};
|
// class DataAccessMMUMiss : public SparcFault<DataAccessMMUMiss> {};
|
||||||
|
|
||||||
class DataAccessError : public SparcFault<DataAccessError> {};
|
class DataAccessError : public SparcFault<DataAccessError> {};
|
||||||
|
|
||||||
|
@ -159,7 +162,7 @@ class MemAddressNotAligned :
|
||||||
public SparcFault<MemAddressNotAligned>
|
public SparcFault<MemAddressNotAligned>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isAlignmentFault() const {return true;}
|
bool isAlignmentFault() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class LDDFMemAddressNotAligned : public SparcFault<LDDFMemAddressNotAligned> {};
|
class LDDFMemAddressNotAligned : public SparcFault<LDDFMemAddressNotAligned> {};
|
||||||
|
@ -177,7 +180,7 @@ class InstructionRealTranslationMiss :
|
||||||
|
|
||||||
class DataRealTranslationMiss : public SparcFault<DataRealTranslationMiss> {};
|
class DataRealTranslationMiss : public SparcFault<DataRealTranslationMiss> {};
|
||||||
|
|
||||||
//class AsyncDataError : public SparcFault<AsyncDataError> {};
|
// class AsyncDataError : public SparcFault<AsyncDataError> {};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class EnumeratedFault : public SparcFault<T>
|
class EnumeratedFault : public SparcFault<T>
|
||||||
|
@ -186,14 +189,14 @@ class EnumeratedFault : public SparcFault<T>
|
||||||
uint32_t _n;
|
uint32_t _n;
|
||||||
public:
|
public:
|
||||||
EnumeratedFault(uint32_t n) : SparcFault<T>(), _n(n) {}
|
EnumeratedFault(uint32_t n) : SparcFault<T>(), _n(n) {}
|
||||||
TrapType trapType() {return SparcFault<T>::trapType() + _n;}
|
TrapType trapType() { return SparcFault<T>::trapType() + _n; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterruptLevelN : public EnumeratedFault<InterruptLevelN>
|
class InterruptLevelN : public EnumeratedFault<InterruptLevelN>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InterruptLevelN(uint32_t n) : EnumeratedFault<InterruptLevelN>(n) {;}
|
InterruptLevelN(uint32_t n) : EnumeratedFault<InterruptLevelN>(n) {;}
|
||||||
FaultPriority priority() {return 3200 - _n*100;}
|
FaultPriority priority() { return 3200 - _n*100; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class HstickMatch : public SparcFault<HstickMatch> {};
|
class HstickMatch : public SparcFault<HstickMatch> {};
|
||||||
|
@ -247,7 +250,7 @@ class SpillNNormal : public EnumeratedFault<SpillNNormal>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpillNNormal(uint32_t n) : EnumeratedFault<SpillNNormal>(n) {;}
|
SpillNNormal(uint32_t n) : EnumeratedFault<SpillNNormal>(n) {;}
|
||||||
//These need to be handled specially to enable spill traps in SE
|
// These need to be handled specially to enable spill traps in SE
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
|
@ -257,14 +260,16 @@ class SpillNNormal : public EnumeratedFault<SpillNNormal>
|
||||||
class SpillNOther : public EnumeratedFault<SpillNOther>
|
class SpillNOther : public EnumeratedFault<SpillNOther>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpillNOther(uint32_t n) : EnumeratedFault<SpillNOther>(n) {;}
|
SpillNOther(uint32_t n) : EnumeratedFault<SpillNOther>(n)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FillNNormal : public EnumeratedFault<FillNNormal>
|
class FillNNormal : public EnumeratedFault<FillNNormal>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FillNNormal(uint32_t n) : EnumeratedFault<FillNNormal>(n) {;}
|
FillNNormal(uint32_t n) : EnumeratedFault<FillNNormal>(n)
|
||||||
//These need to be handled specially to enable fill traps in SE
|
{}
|
||||||
|
// These need to be handled specially to enable fill traps in SE
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
|
@ -274,21 +279,24 @@ class FillNNormal : public EnumeratedFault<FillNNormal>
|
||||||
class FillNOther : public EnumeratedFault<FillNOther>
|
class FillNOther : public EnumeratedFault<FillNOther>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FillNOther(uint32_t n) : EnumeratedFault<FillNOther>(n) {;}
|
FillNOther(uint32_t n) : EnumeratedFault<FillNOther>(n)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrapInstruction : public EnumeratedFault<TrapInstruction>
|
class TrapInstruction : public EnumeratedFault<TrapInstruction>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TrapInstruction(uint32_t n) : EnumeratedFault<TrapInstruction>(n) {;}
|
TrapInstruction(uint32_t n) : EnumeratedFault<TrapInstruction>(n)
|
||||||
//In SE, trap instructions are requesting services from the OS.
|
{}
|
||||||
|
// In SE, trap instructions are requesting services from the OS.
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline Fault genMachineCheckFault()
|
static inline Fault
|
||||||
|
genMachineCheckFault()
|
||||||
{
|
{
|
||||||
return new InternalProcessorError;
|
return new InternalProcessorError;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,153 +37,153 @@
|
||||||
|
|
||||||
namespace SparcISA {
|
namespace SparcISA {
|
||||||
|
|
||||||
//We only use 19 instructions for the trap handlers, but there would be
|
// We only use 19 instructions for the trap handlers, but there would be
|
||||||
//space for 32 in a real SPARC trap table.
|
// space for 32 in a real SPARC trap table.
|
||||||
const int numFillInsts = 32;
|
const int numFillInsts = 32;
|
||||||
const int numSpillInsts = 32;
|
const int numSpillInsts = 32;
|
||||||
|
|
||||||
const MachInst fillHandler64[numFillInsts] =
|
const MachInst fillHandler64[numFillInsts] =
|
||||||
{
|
{
|
||||||
htog(0x87802016), //wr %g0, ASI_AIUP, %asi
|
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
|
||||||
htog(0xe0dba7ff), //ldxa [%sp + BIAS + (0*8)] %asi, %l0
|
htog(0xe0dba7ff), // ldxa [%sp + BIAS + (0*8)] %asi, %l0
|
||||||
htog(0xe2dba807), //ldxa [%sp + BIAS + (1*8)] %asi, %l1
|
htog(0xe2dba807), // ldxa [%sp + BIAS + (1*8)] %asi, %l1
|
||||||
htog(0xe4dba80f), //ldxa [%sp + BIAS + (2*8)] %asi, %l2
|
htog(0xe4dba80f), // ldxa [%sp + BIAS + (2*8)] %asi, %l2
|
||||||
htog(0xe6dba817), //ldxa [%sp + BIAS + (3*8)] %asi, %l3
|
htog(0xe6dba817), // ldxa [%sp + BIAS + (3*8)] %asi, %l3
|
||||||
htog(0xe8dba81f), //ldxa [%sp + BIAS + (4*8)] %asi, %l4
|
htog(0xe8dba81f), // ldxa [%sp + BIAS + (4*8)] %asi, %l4
|
||||||
htog(0xeadba827), //ldxa [%sp + BIAS + (5*8)] %asi, %l5
|
htog(0xeadba827), // ldxa [%sp + BIAS + (5*8)] %asi, %l5
|
||||||
htog(0xecdba82f), //ldxa [%sp + BIAS + (6*8)] %asi, %l6
|
htog(0xecdba82f), // ldxa [%sp + BIAS + (6*8)] %asi, %l6
|
||||||
htog(0xeedba837), //ldxa [%sp + BIAS + (7*8)] %asi, %l7
|
htog(0xeedba837), // ldxa [%sp + BIAS + (7*8)] %asi, %l7
|
||||||
htog(0xf0dba83f), //ldxa [%sp + BIAS + (8*8)] %asi, %i0
|
htog(0xf0dba83f), // ldxa [%sp + BIAS + (8*8)] %asi, %i0
|
||||||
htog(0xf2dba847), //ldxa [%sp + BIAS + (9*8)] %asi, %i1
|
htog(0xf2dba847), // ldxa [%sp + BIAS + (9*8)] %asi, %i1
|
||||||
htog(0xf4dba84f), //ldxa [%sp + BIAS + (10*8)] %asi, %i2
|
htog(0xf4dba84f), // ldxa [%sp + BIAS + (10*8)] %asi, %i2
|
||||||
htog(0xf6dba857), //ldxa [%sp + BIAS + (11*8)] %asi, %i3
|
htog(0xf6dba857), // ldxa [%sp + BIAS + (11*8)] %asi, %i3
|
||||||
htog(0xf8dba85f), //ldxa [%sp + BIAS + (12*8)] %asi, %i4
|
htog(0xf8dba85f), // ldxa [%sp + BIAS + (12*8)] %asi, %i4
|
||||||
htog(0xfadba867), //ldxa [%sp + BIAS + (13*8)] %asi, %i5
|
htog(0xfadba867), // ldxa [%sp + BIAS + (13*8)] %asi, %i5
|
||||||
htog(0xfcdba86f), //ldxa [%sp + BIAS + (14*8)] %asi, %i6
|
htog(0xfcdba86f), // ldxa [%sp + BIAS + (14*8)] %asi, %i6
|
||||||
htog(0xfedba877), //ldxa [%sp + BIAS + (15*8)] %asi, %i7
|
htog(0xfedba877), // ldxa [%sp + BIAS + (15*8)] %asi, %i7
|
||||||
htog(0x83880000), //restored
|
htog(0x83880000), // restored
|
||||||
htog(0x83F00000), //retry
|
htog(0x83F00000), // retry
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000) //illtrap
|
htog(0x00000000) // illtrap
|
||||||
};
|
};
|
||||||
|
|
||||||
const MachInst fillHandler32[numFillInsts] =
|
const MachInst fillHandler32[numFillInsts] =
|
||||||
{
|
{
|
||||||
htog(0x87802016), //wr %g0, ASI_AIUP, %asi
|
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
|
||||||
htog(0xe083a000), //lduwa [%sp + (0*4)] %asi, %l0
|
htog(0xe083a000), // lduwa [%sp + (0*4)] %asi, %l0
|
||||||
htog(0xe283a004), //lduwa [%sp + (1*4)] %asi, %l1
|
htog(0xe283a004), // lduwa [%sp + (1*4)] %asi, %l1
|
||||||
htog(0xe483a008), //lduwa [%sp + (2*4)] %asi, %l2
|
htog(0xe483a008), // lduwa [%sp + (2*4)] %asi, %l2
|
||||||
htog(0xe683a00c), //lduwa [%sp + (3*4)] %asi, %l3
|
htog(0xe683a00c), // lduwa [%sp + (3*4)] %asi, %l3
|
||||||
htog(0xe883a010), //lduwa [%sp + (4*4)] %asi, %l4
|
htog(0xe883a010), // lduwa [%sp + (4*4)] %asi, %l4
|
||||||
htog(0xea83a014), //lduwa [%sp + (5*4)] %asi, %l5
|
htog(0xea83a014), // lduwa [%sp + (5*4)] %asi, %l5
|
||||||
htog(0xec83a018), //lduwa [%sp + (6*4)] %asi, %l6
|
htog(0xec83a018), // lduwa [%sp + (6*4)] %asi, %l6
|
||||||
htog(0xee83a01c), //lduwa [%sp + (7*4)] %asi, %l7
|
htog(0xee83a01c), // lduwa [%sp + (7*4)] %asi, %l7
|
||||||
htog(0xf083a020), //lduwa [%sp + (8*4)] %asi, %i0
|
htog(0xf083a020), // lduwa [%sp + (8*4)] %asi, %i0
|
||||||
htog(0xf283a024), //lduwa [%sp + (9*4)] %asi, %i1
|
htog(0xf283a024), // lduwa [%sp + (9*4)] %asi, %i1
|
||||||
htog(0xf483a028), //lduwa [%sp + (10*4)] %asi, %i2
|
htog(0xf483a028), // lduwa [%sp + (10*4)] %asi, %i2
|
||||||
htog(0xf683a02c), //lduwa [%sp + (11*4)] %asi, %i3
|
htog(0xf683a02c), // lduwa [%sp + (11*4)] %asi, %i3
|
||||||
htog(0xf883a030), //lduwa [%sp + (12*4)] %asi, %i4
|
htog(0xf883a030), // lduwa [%sp + (12*4)] %asi, %i4
|
||||||
htog(0xfa83a034), //lduwa [%sp + (13*4)] %asi, %i5
|
htog(0xfa83a034), // lduwa [%sp + (13*4)] %asi, %i5
|
||||||
htog(0xfc83a038), //lduwa [%sp + (14*4)] %asi, %i6
|
htog(0xfc83a038), // lduwa [%sp + (14*4)] %asi, %i6
|
||||||
htog(0xfe83a03c), //lduwa [%sp + (15*4)] %asi, %i7
|
htog(0xfe83a03c), // lduwa [%sp + (15*4)] %asi, %i7
|
||||||
htog(0x83880000), //restored
|
htog(0x83880000), // restored
|
||||||
htog(0x83F00000), //retry
|
htog(0x83F00000), // retry
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000) //illtrap
|
htog(0x00000000) // illtrap
|
||||||
};
|
};
|
||||||
|
|
||||||
const MachInst spillHandler64[numSpillInsts] =
|
const MachInst spillHandler64[numSpillInsts] =
|
||||||
{
|
{
|
||||||
htog(0x87802016), //wr %g0, ASI_AIUP, %asi
|
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
|
||||||
htog(0xe0f3a7ff), //stxa %l0, [%sp + BIAS + (0*8)] %asi
|
htog(0xe0f3a7ff), // stxa %l0, [%sp + BIAS + (0*8)] %asi
|
||||||
htog(0xe2f3a807), //stxa %l1, [%sp + BIAS + (1*8)] %asi
|
htog(0xe2f3a807), // stxa %l1, [%sp + BIAS + (1*8)] %asi
|
||||||
htog(0xe4f3a80f), //stxa %l2, [%sp + BIAS + (2*8)] %asi
|
htog(0xe4f3a80f), // stxa %l2, [%sp + BIAS + (2*8)] %asi
|
||||||
htog(0xe6f3a817), //stxa %l3, [%sp + BIAS + (3*8)] %asi
|
htog(0xe6f3a817), // stxa %l3, [%sp + BIAS + (3*8)] %asi
|
||||||
htog(0xe8f3a81f), //stxa %l4, [%sp + BIAS + (4*8)] %asi
|
htog(0xe8f3a81f), // stxa %l4, [%sp + BIAS + (4*8)] %asi
|
||||||
htog(0xeaf3a827), //stxa %l5, [%sp + BIAS + (5*8)] %asi
|
htog(0xeaf3a827), // stxa %l5, [%sp + BIAS + (5*8)] %asi
|
||||||
htog(0xecf3a82f), //stxa %l6, [%sp + BIAS + (6*8)] %asi
|
htog(0xecf3a82f), // stxa %l6, [%sp + BIAS + (6*8)] %asi
|
||||||
htog(0xeef3a837), //stxa %l7, [%sp + BIAS + (7*8)] %asi
|
htog(0xeef3a837), // stxa %l7, [%sp + BIAS + (7*8)] %asi
|
||||||
htog(0xf0f3a83f), //stxa %i0, [%sp + BIAS + (8*8)] %asi
|
htog(0xf0f3a83f), // stxa %i0, [%sp + BIAS + (8*8)] %asi
|
||||||
htog(0xf2f3a847), //stxa %i1, [%sp + BIAS + (9*8)] %asi
|
htog(0xf2f3a847), // stxa %i1, [%sp + BIAS + (9*8)] %asi
|
||||||
htog(0xf4f3a84f), //stxa %i2, [%sp + BIAS + (10*8)] %asi
|
htog(0xf4f3a84f), // stxa %i2, [%sp + BIAS + (10*8)] %asi
|
||||||
htog(0xf6f3a857), //stxa %i3, [%sp + BIAS + (11*8)] %asi
|
htog(0xf6f3a857), // stxa %i3, [%sp + BIAS + (11*8)] %asi
|
||||||
htog(0xf8f3a85f), //stxa %i4, [%sp + BIAS + (12*8)] %asi
|
htog(0xf8f3a85f), // stxa %i4, [%sp + BIAS + (12*8)] %asi
|
||||||
htog(0xfaf3a867), //stxa %i5, [%sp + BIAS + (13*8)] %asi
|
htog(0xfaf3a867), // stxa %i5, [%sp + BIAS + (13*8)] %asi
|
||||||
htog(0xfcf3a86f), //stxa %i6, [%sp + BIAS + (14*8)] %asi
|
htog(0xfcf3a86f), // stxa %i6, [%sp + BIAS + (14*8)] %asi
|
||||||
htog(0xfef3a877), //stxa %i7, [%sp + BIAS + (15*8)] %asi
|
htog(0xfef3a877), // stxa %i7, [%sp + BIAS + (15*8)] %asi
|
||||||
htog(0x81880000), //saved
|
htog(0x81880000), // saved
|
||||||
htog(0x83F00000), //retry
|
htog(0x83F00000), // retry
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000) //illtrap
|
htog(0x00000000) // illtrap
|
||||||
};
|
};
|
||||||
|
|
||||||
const MachInst spillHandler32[numSpillInsts] =
|
const MachInst spillHandler32[numSpillInsts] =
|
||||||
{
|
{
|
||||||
htog(0x87802016), //wr %g0, ASI_AIUP, %asi
|
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
|
||||||
htog(0xe0a3a000), //stwa %l0, [%sp + (0*4)] %asi
|
htog(0xe0a3a000), // stwa %l0, [%sp + (0*4)] %asi
|
||||||
htog(0xe2a3a004), //stwa %l1, [%sp + (1*4)] %asi
|
htog(0xe2a3a004), // stwa %l1, [%sp + (1*4)] %asi
|
||||||
htog(0xe4a3a008), //stwa %l2, [%sp + (2*4)] %asi
|
htog(0xe4a3a008), // stwa %l2, [%sp + (2*4)] %asi
|
||||||
htog(0xe6a3a00c), //stwa %l3, [%sp + (3*4)] %asi
|
htog(0xe6a3a00c), // stwa %l3, [%sp + (3*4)] %asi
|
||||||
htog(0xe8a3a010), //stwa %l4, [%sp + (4*4)] %asi
|
htog(0xe8a3a010), // stwa %l4, [%sp + (4*4)] %asi
|
||||||
htog(0xeaa3a014), //stwa %l5, [%sp + (5*4)] %asi
|
htog(0xeaa3a014), // stwa %l5, [%sp + (5*4)] %asi
|
||||||
htog(0xeca3a018), //stwa %l6, [%sp + (6*4)] %asi
|
htog(0xeca3a018), // stwa %l6, [%sp + (6*4)] %asi
|
||||||
htog(0xeea3a01c), //stwa %l7, [%sp + (7*4)] %asi
|
htog(0xeea3a01c), // stwa %l7, [%sp + (7*4)] %asi
|
||||||
htog(0xf0a3a020), //stwa %i0, [%sp + (8*4)] %asi
|
htog(0xf0a3a020), // stwa %i0, [%sp + (8*4)] %asi
|
||||||
htog(0xf2a3a024), //stwa %i1, [%sp + (9*4)] %asi
|
htog(0xf2a3a024), // stwa %i1, [%sp + (9*4)] %asi
|
||||||
htog(0xf4a3a028), //stwa %i2, [%sp + (10*4)] %asi
|
htog(0xf4a3a028), // stwa %i2, [%sp + (10*4)] %asi
|
||||||
htog(0xf6a3a02c), //stwa %i3, [%sp + (11*4)] %asi
|
htog(0xf6a3a02c), // stwa %i3, [%sp + (11*4)] %asi
|
||||||
htog(0xf8a3a030), //stwa %i4, [%sp + (12*4)] %asi
|
htog(0xf8a3a030), // stwa %i4, [%sp + (12*4)] %asi
|
||||||
htog(0xfaa3a034), //stwa %i5, [%sp + (13*4)] %asi
|
htog(0xfaa3a034), // stwa %i5, [%sp + (13*4)] %asi
|
||||||
htog(0xfca3a038), //stwa %i6, [%sp + (14*4)] %asi
|
htog(0xfca3a038), // stwa %i6, [%sp + (14*4)] %asi
|
||||||
htog(0xfea3a03c), //stwa %i7, [%sp + (15*4)] %asi
|
htog(0xfea3a03c), // stwa %i7, [%sp + (15*4)] %asi
|
||||||
htog(0x81880000), //saved
|
htog(0x81880000), // saved
|
||||||
htog(0x83F00000), //retry
|
htog(0x83F00000), // retry
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000), //illtrap
|
htog(0x00000000), // illtrap
|
||||||
htog(0x00000000) //illtrap
|
htog(0x00000000) // illtrap
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SparcISA
|
} // namespace SparcISA
|
||||||
|
|
|
@ -181,9 +181,7 @@ class Interrupts : public SimObject
|
||||||
|
|
||||||
void
|
void
|
||||||
updateIntrInfo(ThreadContext *tc)
|
updateIntrInfo(ThreadContext *tc)
|
||||||
{
|
{}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
get_vec(int int_num)
|
get_vec(int int_num)
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace SparcISA
|
||||||
|
|
||||||
enum RegMask
|
enum RegMask
|
||||||
{
|
{
|
||||||
PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
|
PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -85,8 +85,8 @@ ISA::clear()
|
||||||
gl = 0;
|
gl = 0;
|
||||||
reloadRegMap();
|
reloadRegMap();
|
||||||
|
|
||||||
//y = 0;
|
// y = 0;
|
||||||
//ccr = 0;
|
// ccr = 0;
|
||||||
asi = 0;
|
asi = 0;
|
||||||
tick = ULL(1) << 63;
|
tick = ULL(1) << 63;
|
||||||
fprs = 0;
|
fprs = 0;
|
||||||
|
@ -103,18 +103,18 @@ ISA::clear()
|
||||||
pstate = 0;
|
pstate = 0;
|
||||||
tl = 0;
|
tl = 0;
|
||||||
pil = 0;
|
pil = 0;
|
||||||
//cansave = 0;
|
// cansave = 0;
|
||||||
//canrestore = 0;
|
// canrestore = 0;
|
||||||
//cleanwin = 0;
|
// cleanwin = 0;
|
||||||
//otherwin = 0;
|
// otherwin = 0;
|
||||||
//wstate = 0;
|
// wstate = 0;
|
||||||
//In a T1, bit 11 is apparently always 1
|
// In a T1, bit 11 is apparently always 1
|
||||||
hpstate = (1 << 11);
|
hpstate = (1 << 11);
|
||||||
memset(htstate, 0, sizeof(htstate));
|
memset(htstate, 0, sizeof(htstate));
|
||||||
hintp = 0;
|
hintp = 0;
|
||||||
htba = 0;
|
htba = 0;
|
||||||
hstick_cmpr = 0;
|
hstick_cmpr = 0;
|
||||||
//This is set this way in Legion for some reason
|
// This is set this way in Legion for some reason
|
||||||
strandStatusReg = 0x50000;
|
strandStatusReg = 0x50000;
|
||||||
fsr = 0;
|
fsr = 0;
|
||||||
|
|
||||||
|
@ -175,11 +175,11 @@ ISA::readMiscRegNoEffect(int miscReg)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (miscReg) {
|
switch (miscReg) {
|
||||||
//case MISCREG_TLB_DATA:
|
// case MISCREG_TLB_DATA:
|
||||||
// [original contents see above]
|
// [original contents see above]
|
||||||
//case MISCREG_Y:
|
// case MISCREG_Y:
|
||||||
// return y;
|
// return y;
|
||||||
//case MISCREG_CCR:
|
// case MISCREG_CCR:
|
||||||
// return ccr;
|
// return ccr;
|
||||||
case MISCREG_ASI:
|
case MISCREG_ASI:
|
||||||
return asi;
|
return asi;
|
||||||
|
@ -221,21 +221,21 @@ ISA::readMiscRegNoEffect(int miscReg)
|
||||||
return tl;
|
return tl;
|
||||||
case MISCREG_PIL:
|
case MISCREG_PIL:
|
||||||
return pil;
|
return pil;
|
||||||
//CWP, GL moved
|
// CWP, GL moved
|
||||||
//case MISCREG_CWP:
|
// case MISCREG_CWP:
|
||||||
// return cwp;
|
// return cwp;
|
||||||
//case MISCREG_CANSAVE:
|
// case MISCREG_CANSAVE:
|
||||||
// return cansave;
|
// return cansave;
|
||||||
//case MISCREG_CANRESTORE:
|
// case MISCREG_CANRESTORE:
|
||||||
// return canrestore;
|
// return canrestore;
|
||||||
//case MISCREG_CLEANWIN:
|
// case MISCREG_CLEANWIN:
|
||||||
// return cleanwin;
|
// return cleanwin;
|
||||||
//case MISCREG_OTHERWIN:
|
// case MISCREG_OTHERWIN:
|
||||||
// return otherwin;
|
// return otherwin;
|
||||||
//case MISCREG_WSTATE:
|
// case MISCREG_WSTATE:
|
||||||
// return wstate;
|
// return wstate;
|
||||||
//case MISCREG_GL:
|
// case MISCREG_GL:
|
||||||
// return gl;
|
// return gl;
|
||||||
|
|
||||||
/** Hyper privileged registers */
|
/** Hyper privileged registers */
|
||||||
case MISCREG_HPSTATE:
|
case MISCREG_HPSTATE:
|
||||||
|
@ -349,10 +349,10 @@ ISA::readMiscReg(int miscReg, ThreadContext * tc)
|
||||||
return readFSReg(miscReg, tc);
|
return readFSReg(miscReg, tc);
|
||||||
#else
|
#else
|
||||||
case MISCREG_HPSTATE:
|
case MISCREG_HPSTATE:
|
||||||
//HPSTATE is special because because sometimes in privilege
|
// HPSTATE is special because because sometimes in privilege
|
||||||
//checks for instructions it will read HPSTATE to make sure
|
// checks for instructions it will read HPSTATE to make sure
|
||||||
//the priv. level is ok So, we'll just have to tell it it
|
// the priv. level is ok So, we'll just have to tell it it
|
||||||
//isn't, instead of panicing.
|
// isn't, instead of panicing.
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
|
panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
|
||||||
|
@ -557,10 +557,10 @@ ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
|
||||||
DPRINTF(Timer, "Writing TICK=%#X\n", val);
|
DPRINTF(Timer, "Writing TICK=%#X\n", val);
|
||||||
break;
|
break;
|
||||||
case MISCREG_FPRS:
|
case MISCREG_FPRS:
|
||||||
//Configure the fpu based on the fprs
|
// Configure the fpu based on the fprs
|
||||||
break;
|
break;
|
||||||
case MISCREG_PCR:
|
case MISCREG_PCR:
|
||||||
//Set up performance counting based on pcr value
|
// Set up performance counting based on pcr value
|
||||||
break;
|
break;
|
||||||
case MISCREG_PSTATE:
|
case MISCREG_PSTATE:
|
||||||
pstate = val & PSTATE_MASK;
|
pstate = val & PSTATE_MASK;
|
||||||
|
@ -614,8 +614,8 @@ ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
|
||||||
return;
|
return;
|
||||||
#else
|
#else
|
||||||
case MISCREG_HPSTATE:
|
case MISCREG_HPSTATE:
|
||||||
//HPSTATE is special because normal trap processing saves HPSTATE when
|
// HPSTATE is special because normal trap processing saves HPSTATE when
|
||||||
//it goes into a trap, and restores it when it returns.
|
// it goes into a trap, and restores it when it returns.
|
||||||
return;
|
return;
|
||||||
panic("Accessing Fullsystem register %d to %#x in SE mode\n",
|
panic("Accessing Fullsystem register %d to %#x in SE mode\n",
|
||||||
miscReg, val);
|
miscReg, val);
|
||||||
|
|
|
@ -45,175 +45,175 @@ class ThreadContext;
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
class ISA
|
class ISA
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/* ASR Registers */
|
/* ASR Registers */
|
||||||
//uint64_t y; // Y (used in obsolete multiplication)
|
// uint64_t y; // Y (used in obsolete multiplication)
|
||||||
//uint8_t ccr; // Condition Code Register
|
// uint8_t ccr; // Condition Code Register
|
||||||
uint8_t asi; // Address Space Identifier
|
uint8_t asi; // Address Space Identifier
|
||||||
uint64_t tick; // Hardware clock-tick counter
|
uint64_t tick; // Hardware clock-tick counter
|
||||||
uint8_t fprs; // Floating-Point Register State
|
uint8_t fprs; // Floating-Point Register State
|
||||||
uint64_t gsr; // General Status Register
|
uint64_t gsr; // General Status Register
|
||||||
uint64_t softint;
|
uint64_t softint;
|
||||||
uint64_t tick_cmpr; // Hardware tick compare registers
|
uint64_t tick_cmpr; // Hardware tick compare registers
|
||||||
uint64_t stick; // Hardware clock-tick counter
|
uint64_t stick; // Hardware clock-tick counter
|
||||||
uint64_t stick_cmpr; // Hardware tick compare registers
|
uint64_t stick_cmpr; // Hardware tick compare registers
|
||||||
|
|
||||||
|
|
||||||
/* Privileged Registers */
|
/* Privileged Registers */
|
||||||
uint64_t tpc[MaxTL]; // Trap Program Counter (value from
|
uint64_t tpc[MaxTL]; // Trap Program Counter (value from
|
||||||
// previous trap level)
|
// previous trap level)
|
||||||
uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
|
uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
|
||||||
// previous trap level)
|
// previous trap level)
|
||||||
uint64_t tstate[MaxTL]; // Trap State
|
uint64_t tstate[MaxTL]; // Trap State
|
||||||
uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
|
uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
|
||||||
// on the previous level)
|
// on the previous level)
|
||||||
uint64_t tba; // Trap Base Address
|
uint64_t tba; // Trap Base Address
|
||||||
|
|
||||||
uint16_t pstate; // Process State Register
|
uint16_t pstate; // Process State Register
|
||||||
uint8_t tl; // Trap Level
|
uint8_t tl; // Trap Level
|
||||||
uint8_t pil; // Process Interrupt Register
|
uint8_t pil; // Process Interrupt Register
|
||||||
uint8_t cwp; // Current Window Pointer
|
uint8_t cwp; // Current Window Pointer
|
||||||
//uint8_t cansave; // Savable windows
|
// uint8_t cansave; // Savable windows
|
||||||
//uint8_t canrestore; // Restorable windows
|
// uint8_t canrestore; // Restorable windows
|
||||||
//uint8_t cleanwin; // Clean windows
|
// uint8_t cleanwin; // Clean windows
|
||||||
//uint8_t otherwin; // Other windows
|
// uint8_t otherwin; // Other windows
|
||||||
//uint8_t wstate; // Window State
|
// uint8_t wstate; // Window State
|
||||||
uint8_t gl; // Global level register
|
uint8_t gl; // Global level register
|
||||||
|
|
||||||
/** Hyperprivileged Registers */
|
/** Hyperprivileged Registers */
|
||||||
uint64_t hpstate; // Hyperprivileged State Register
|
uint64_t hpstate; // Hyperprivileged State Register
|
||||||
uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register
|
uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register
|
||||||
uint64_t hintp;
|
uint64_t hintp;
|
||||||
uint64_t htba; // Hyperprivileged Trap Base Address register
|
uint64_t htba; // Hyperprivileged Trap Base Address register
|
||||||
uint64_t hstick_cmpr; // Hardware tick compare registers
|
uint64_t hstick_cmpr; // Hardware tick compare registers
|
||||||
|
|
||||||
uint64_t strandStatusReg;// Per strand status register
|
uint64_t strandStatusReg;// Per strand status register
|
||||||
|
|
||||||
/** Floating point misc registers. */
|
/** Floating point misc registers. */
|
||||||
uint64_t fsr; // Floating-Point State Register
|
uint64_t fsr; // Floating-Point State Register
|
||||||
|
|
||||||
/** MMU Internal Registers */
|
/** MMU Internal Registers */
|
||||||
uint16_t priContext;
|
uint16_t priContext;
|
||||||
uint16_t secContext;
|
uint16_t secContext;
|
||||||
uint16_t partId;
|
uint16_t partId;
|
||||||
uint64_t lsuCtrlReg;
|
uint64_t lsuCtrlReg;
|
||||||
|
|
||||||
uint64_t scratchPad[8];
|
uint64_t scratchPad[8];
|
||||||
|
|
||||||
uint64_t cpu_mondo_head;
|
uint64_t cpu_mondo_head;
|
||||||
uint64_t cpu_mondo_tail;
|
uint64_t cpu_mondo_tail;
|
||||||
uint64_t dev_mondo_head;
|
uint64_t dev_mondo_head;
|
||||||
uint64_t dev_mondo_tail;
|
uint64_t dev_mondo_tail;
|
||||||
uint64_t res_error_head;
|
uint64_t res_error_head;
|
||||||
uint64_t res_error_tail;
|
uint64_t res_error_tail;
|
||||||
uint64_t nres_error_head;
|
uint64_t nres_error_head;
|
||||||
uint64_t nres_error_tail;
|
uint64_t nres_error_tail;
|
||||||
|
|
||||||
// These need to check the int_dis field and if 0 then
|
// These need to check the int_dis field and if 0 then
|
||||||
// set appropriate bit in softint and checkinterrutps on the cpu
|
// set appropriate bit in softint and checkinterrutps on the cpu
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc);
|
void setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc);
|
||||||
MiscReg readFSReg(int miscReg, ThreadContext * tc);
|
MiscReg readFSReg(int miscReg, ThreadContext * tc);
|
||||||
|
|
||||||
// Update interrupt state on softint or pil change
|
// Update interrupt state on softint or pil change
|
||||||
void checkSoftInt(ThreadContext *tc);
|
void checkSoftInt(ThreadContext *tc);
|
||||||
|
|
||||||
/** Process a tick compare event and generate an interrupt on the cpu if
|
/** Process a tick compare event and generate an interrupt on the cpu if
|
||||||
* appropriate. */
|
* appropriate. */
|
||||||
void processTickCompare(ThreadContext *tc);
|
void processTickCompare(ThreadContext *tc);
|
||||||
void processSTickCompare(ThreadContext *tc);
|
void processSTickCompare(ThreadContext *tc);
|
||||||
void processHSTickCompare(ThreadContext *tc);
|
void processHSTickCompare(ThreadContext *tc);
|
||||||
|
|
||||||
typedef CpuEventWrapper<ISA,
|
typedef CpuEventWrapper<ISA,
|
||||||
&ISA::processTickCompare> TickCompareEvent;
|
&ISA::processTickCompare> TickCompareEvent;
|
||||||
TickCompareEvent *tickCompare;
|
TickCompareEvent *tickCompare;
|
||||||
|
|
||||||
typedef CpuEventWrapper<ISA,
|
typedef CpuEventWrapper<ISA,
|
||||||
&ISA::processSTickCompare> STickCompareEvent;
|
&ISA::processSTickCompare> STickCompareEvent;
|
||||||
STickCompareEvent *sTickCompare;
|
STickCompareEvent *sTickCompare;
|
||||||
|
|
||||||
typedef CpuEventWrapper<ISA,
|
typedef CpuEventWrapper<ISA,
|
||||||
&ISA::processHSTickCompare> HSTickCompareEvent;
|
&ISA::processHSTickCompare> HSTickCompareEvent;
|
||||||
HSTickCompareEvent *hSTickCompare;
|
HSTickCompareEvent *hSTickCompare;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const int NumGlobalRegs = 8;
|
static const int NumGlobalRegs = 8;
|
||||||
static const int NumWindowedRegs = 24;
|
static const int NumWindowedRegs = 24;
|
||||||
static const int WindowOverlap = 8;
|
static const int WindowOverlap = 8;
|
||||||
|
|
||||||
static const int TotalGlobals = (MaxGL + 1) * NumGlobalRegs;
|
static const int TotalGlobals = (MaxGL + 1) * NumGlobalRegs;
|
||||||
static const int RegsPerWindow = NumWindowedRegs - WindowOverlap;
|
static const int RegsPerWindow = NumWindowedRegs - WindowOverlap;
|
||||||
static const int TotalWindowed = NWindows * RegsPerWindow;
|
static const int TotalWindowed = NWindows * RegsPerWindow;
|
||||||
|
|
||||||
enum InstIntRegOffsets {
|
enum InstIntRegOffsets {
|
||||||
CurrentGlobalsOffset = 0,
|
CurrentGlobalsOffset = 0,
|
||||||
CurrentWindowOffset = CurrentGlobalsOffset + NumGlobalRegs,
|
CurrentWindowOffset = CurrentGlobalsOffset + NumGlobalRegs,
|
||||||
MicroIntOffset = CurrentWindowOffset + NumWindowedRegs,
|
MicroIntOffset = CurrentWindowOffset + NumWindowedRegs,
|
||||||
NextGlobalsOffset = MicroIntOffset + NumMicroIntRegs,
|
NextGlobalsOffset = MicroIntOffset + NumMicroIntRegs,
|
||||||
NextWindowOffset = NextGlobalsOffset + NumGlobalRegs,
|
NextWindowOffset = NextGlobalsOffset + NumGlobalRegs,
|
||||||
PreviousGlobalsOffset = NextWindowOffset + NumWindowedRegs,
|
PreviousGlobalsOffset = NextWindowOffset + NumWindowedRegs,
|
||||||
PreviousWindowOffset = PreviousGlobalsOffset + NumGlobalRegs,
|
PreviousWindowOffset = PreviousGlobalsOffset + NumGlobalRegs,
|
||||||
TotalInstIntRegs = PreviousWindowOffset + NumWindowedRegs
|
TotalInstIntRegs = PreviousWindowOffset + NumWindowedRegs
|
||||||
};
|
|
||||||
|
|
||||||
RegIndex intRegMap[TotalInstIntRegs];
|
|
||||||
void installWindow(int cwp, int offset);
|
|
||||||
void installGlobals(int gl, int offset);
|
|
||||||
void reloadRegMap();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
void serialize(EventManager *em, std::ostream & os);
|
|
||||||
|
|
||||||
void unserialize(EventManager *em, Checkpoint *cp,
|
|
||||||
const std::string & section);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
bool isHyperPriv() { return (hpstate & (1 << 2)); }
|
|
||||||
bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); }
|
|
||||||
bool isNonPriv() { return !isPriv(); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
MiscReg readMiscRegNoEffect(int miscReg);
|
|
||||||
MiscReg readMiscReg(int miscReg, ThreadContext *tc);
|
|
||||||
|
|
||||||
void setMiscRegNoEffect(int miscReg, const MiscReg val);
|
|
||||||
void setMiscReg(int miscReg, const MiscReg val,
|
|
||||||
ThreadContext *tc);
|
|
||||||
|
|
||||||
int
|
|
||||||
flattenIntIndex(int reg)
|
|
||||||
{
|
|
||||||
assert(reg < TotalInstIntRegs);
|
|
||||||
RegIndex flatIndex = intRegMap[reg];
|
|
||||||
assert(flatIndex < NumIntRegs);
|
|
||||||
return flatIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
flattenFloatIndex(int reg)
|
|
||||||
{
|
|
||||||
return reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISA()
|
|
||||||
{
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
tickCompare = NULL;
|
|
||||||
sTickCompare = NULL;
|
|
||||||
hSTickCompare = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
RegIndex intRegMap[TotalInstIntRegs];
|
||||||
|
void installWindow(int cwp, int offset);
|
||||||
|
void installGlobals(int gl, int offset);
|
||||||
|
void reloadRegMap();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void serialize(EventManager *em, std::ostream & os);
|
||||||
|
|
||||||
|
void unserialize(EventManager *em, Checkpoint *cp,
|
||||||
|
const std::string & section);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool isHyperPriv() { return (hpstate & (1 << 2)); }
|
||||||
|
bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); }
|
||||||
|
bool isNonPriv() { return !isPriv(); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MiscReg readMiscRegNoEffect(int miscReg);
|
||||||
|
MiscReg readMiscReg(int miscReg, ThreadContext *tc);
|
||||||
|
|
||||||
|
void setMiscRegNoEffect(int miscReg, const MiscReg val);
|
||||||
|
void setMiscReg(int miscReg, const MiscReg val,
|
||||||
|
ThreadContext *tc);
|
||||||
|
|
||||||
|
int
|
||||||
|
flattenIntIndex(int reg)
|
||||||
|
{
|
||||||
|
assert(reg < TotalInstIntRegs);
|
||||||
|
RegIndex flatIndex = intRegMap[reg];
|
||||||
|
assert(flatIndex < NumIntRegs);
|
||||||
|
return flatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
flattenFloatIndex(int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISA()
|
||||||
|
{
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
tickCompare = NULL;
|
||||||
|
sTickCompare = NULL;
|
||||||
|
hSTickCompare = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -119,7 +119,8 @@ output header {{
|
||||||
|
|
||||||
bool passesCondition(uint32_t codes, uint32_t condition);
|
bool passesCondition(uint32_t codes, uint32_t condition);
|
||||||
|
|
||||||
inline int64_t sign_ext(uint64_t data, int origWidth)
|
inline int64_t
|
||||||
|
sign_ext(uint64_t data, int origWidth)
|
||||||
{
|
{
|
||||||
int shiftAmount = 64 - origWidth;
|
int shiftAmount = 64 - origWidth;
|
||||||
return (((int64_t)data) << shiftAmount) >> shiftAmount;
|
return (((int64_t)data) << shiftAmount) >> shiftAmount;
|
||||||
|
@ -130,22 +131,22 @@ output decoder {{
|
||||||
|
|
||||||
const char *CondTestAbbrev[] =
|
const char *CondTestAbbrev[] =
|
||||||
{
|
{
|
||||||
"nev", //Never
|
"nev", // Never
|
||||||
"e", //Equal
|
"e", // Equal
|
||||||
"le", //Less or Equal
|
"le", // Less or Equal
|
||||||
"l", //Less
|
"l", // Less
|
||||||
"leu", //Less or Equal Unsigned
|
"leu", // Less or Equal Unsigned
|
||||||
"c", //Carry set
|
"c", // Carry set
|
||||||
"n", //Negative
|
"n", // Negative
|
||||||
"o", //Overflow set
|
"o", // Overflow set
|
||||||
"a", //Always
|
"a", // Always
|
||||||
"ne", //Not Equal
|
"ne", // Not Equal
|
||||||
"g", //Greater
|
"g", // Greater
|
||||||
"ge", //Greater or Equal
|
"ge", // Greater or Equal
|
||||||
"gu", //Greater Unsigned
|
"gu", // Greater Unsigned
|
||||||
"cc", //Carry clear
|
"cc", // Carry clear
|
||||||
"p", //Positive
|
"p", // Positive
|
||||||
"oc" //Overflow Clear
|
"oc" // Overflow Clear
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -252,11 +253,10 @@ output decoder {{
|
||||||
void SparcStaticInst::printRegArray(std::ostream &os,
|
void SparcStaticInst::printRegArray(std::ostream &os,
|
||||||
const RegIndex indexArray[], int num) const
|
const RegIndex indexArray[], int num) const
|
||||||
{
|
{
|
||||||
if(num <= 0)
|
if (num <= 0)
|
||||||
return;
|
return;
|
||||||
printReg(os, indexArray[0]);
|
printReg(os, indexArray[0]);
|
||||||
for(int x = 1; x < num; x++)
|
for (int x = 1; x < num; x++) {
|
||||||
{
|
|
||||||
os << ", ";
|
os << ", ";
|
||||||
printReg(os, indexArray[x]);
|
printReg(os, indexArray[x]);
|
||||||
}
|
}
|
||||||
|
@ -271,14 +271,14 @@ output decoder {{
|
||||||
void
|
void
|
||||||
SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
|
SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
|
||||||
{
|
{
|
||||||
if(_numSrcRegs > reg)
|
if (_numSrcRegs > reg)
|
||||||
printReg(os, _srcRegIdx[reg]);
|
printReg(os, _srcRegIdx[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SparcStaticInst::printDestReg(std::ostream &os, int reg) const
|
SparcStaticInst::printDestReg(std::ostream &os, int reg) const
|
||||||
{
|
{
|
||||||
if(_numDestRegs > reg)
|
if (_numDestRegs > reg)
|
||||||
printReg(os, _destRegIdx[reg]);
|
printReg(os, _destRegIdx[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,25 +291,25 @@ output decoder {{
|
||||||
const int MaxInput = 32;
|
const int MaxInput = 32;
|
||||||
const int MaxMicroReg = 40;
|
const int MaxMicroReg = 40;
|
||||||
if (reg < FP_Base_DepTag) {
|
if (reg < FP_Base_DepTag) {
|
||||||
//If we used a register from the next or previous window,
|
// If we used a register from the next or previous window,
|
||||||
//take out the offset.
|
// take out the offset.
|
||||||
while (reg >= MaxMicroReg)
|
while (reg >= MaxMicroReg)
|
||||||
reg -= MaxMicroReg;
|
reg -= MaxMicroReg;
|
||||||
if (reg == FramePointerReg)
|
if (reg == FramePointerReg)
|
||||||
ccprintf(os, "%%fp");
|
ccprintf(os, "%%fp");
|
||||||
else if (reg == StackPointerReg)
|
else if (reg == StackPointerReg)
|
||||||
ccprintf(os, "%%sp");
|
ccprintf(os, "%%sp");
|
||||||
else if(reg < MaxGlobal)
|
else if (reg < MaxGlobal)
|
||||||
ccprintf(os, "%%g%d", reg);
|
ccprintf(os, "%%g%d", reg);
|
||||||
else if(reg < MaxOutput)
|
else if (reg < MaxOutput)
|
||||||
ccprintf(os, "%%o%d", reg - MaxGlobal);
|
ccprintf(os, "%%o%d", reg - MaxGlobal);
|
||||||
else if(reg < MaxLocal)
|
else if (reg < MaxLocal)
|
||||||
ccprintf(os, "%%l%d", reg - MaxOutput);
|
ccprintf(os, "%%l%d", reg - MaxOutput);
|
||||||
else if(reg < MaxInput)
|
else if (reg < MaxInput)
|
||||||
ccprintf(os, "%%i%d", reg - MaxLocal);
|
ccprintf(os, "%%i%d", reg - MaxLocal);
|
||||||
else if(reg < MaxMicroReg)
|
else if (reg < MaxMicroReg)
|
||||||
ccprintf(os, "%%u%d", reg - MaxInput);
|
ccprintf(os, "%%u%d", reg - MaxInput);
|
||||||
//The fake int regs that are really control regs
|
// The fake int regs that are really control regs
|
||||||
else {
|
else {
|
||||||
switch (reg - MaxMicroReg) {
|
switch (reg - MaxMicroReg) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -435,8 +435,9 @@ output decoder {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SparcStaticInst::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
SparcStaticInst::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -445,21 +446,17 @@ output decoder {{
|
||||||
// just print the first two source regs... if there's
|
// just print the first two source regs... if there's
|
||||||
// a third one, it's a read-modify-write dest (Rc),
|
// a third one, it's a read-modify-write dest (Rc),
|
||||||
// e.g. for CMOVxx
|
// e.g. for CMOVxx
|
||||||
if(_numSrcRegs > 0)
|
if (_numSrcRegs > 0)
|
||||||
{
|
|
||||||
printReg(ss, _srcRegIdx[0]);
|
printReg(ss, _srcRegIdx[0]);
|
||||||
}
|
if (_numSrcRegs > 1) {
|
||||||
if(_numSrcRegs > 1)
|
|
||||||
{
|
|
||||||
ss << ",";
|
ss << ",";
|
||||||
printReg(ss, _srcRegIdx[1]);
|
printReg(ss, _srcRegIdx[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// just print the first dest... if there's a second one,
|
// just print the first dest... if there's a second one,
|
||||||
// it's generally implicit
|
// it's generally implicit
|
||||||
if(_numDestRegs > 0)
|
if (_numDestRegs > 0) {
|
||||||
{
|
if (_numSrcRegs > 0)
|
||||||
if(_numSrcRegs > 0)
|
|
||||||
ss << ",";
|
ss << ",";
|
||||||
printReg(ss, _destRegIdx[0]);
|
printReg(ss, _destRegIdx[0]);
|
||||||
}
|
}
|
||||||
|
@ -467,14 +464,14 @@ output decoder {{
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool passesFpCondition(uint32_t fcc, uint32_t condition)
|
bool
|
||||||
|
passesFpCondition(uint32_t fcc, uint32_t condition)
|
||||||
{
|
{
|
||||||
bool u = (fcc == 3);
|
bool u = (fcc == 3);
|
||||||
bool g = (fcc == 2);
|
bool g = (fcc == 2);
|
||||||
bool l = (fcc == 1);
|
bool l = (fcc == 1);
|
||||||
bool e = (fcc == 0);
|
bool e = (fcc == 0);
|
||||||
switch(condition)
|
switch (condition) {
|
||||||
{
|
|
||||||
case FAlways:
|
case FAlways:
|
||||||
return 1;
|
return 1;
|
||||||
case FNever:
|
case FNever:
|
||||||
|
@ -512,7 +509,8 @@ output decoder {{
|
||||||
"condition code %d", condition);
|
"condition code %d", condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool passesCondition(uint32_t codes, uint32_t condition)
|
bool
|
||||||
|
passesCondition(uint32_t codes, uint32_t condition)
|
||||||
{
|
{
|
||||||
CondCodes condCodes;
|
CondCodes condCodes;
|
||||||
condCodes.bits = 0;
|
condCodes.bits = 0;
|
||||||
|
@ -521,8 +519,7 @@ output decoder {{
|
||||||
condCodes.z = codes & 0x4 ? 1 : 0;
|
condCodes.z = codes & 0x4 ? 1 : 0;
|
||||||
condCodes.n = codes & 0x8 ? 1 : 0;
|
condCodes.n = codes & 0x8 ? 1 : 0;
|
||||||
|
|
||||||
switch(condition)
|
switch (condition) {
|
||||||
{
|
|
||||||
case Always:
|
case Always:
|
||||||
return true;
|
return true;
|
||||||
case Never:
|
case Never:
|
||||||
|
@ -567,17 +564,20 @@ output exec {{
|
||||||
/// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
|
/// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
|
||||||
/// if not. Non-full-system mode: always returns NoFault.
|
/// if not. Non-full-system mode: always returns NoFault.
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
inline Fault
|
||||||
|
checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||||
{
|
{
|
||||||
Fault fault = NoFault; // dummy... this ipr access should not fault
|
Fault fault = NoFault; // dummy... this ipr access should not fault
|
||||||
if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
|
if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
|
||||||
xc->readMiscReg(MISCREG_FPRS) & 0x4)
|
xc->readMiscReg(MISCREG_FPRS) & 0x4) {
|
||||||
return NoFault;
|
return NoFault;
|
||||||
else
|
} else {
|
||||||
return new FpDisabled;
|
return new FpDisabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
inline Fault
|
||||||
|
checkFpEnableFault(%(CPU_exec_context)s *xc)
|
||||||
{
|
{
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,8 @@ def template BasicExecDeclare {{
|
||||||
|
|
||||||
// Definitions of execute methods that panic.
|
// Definitions of execute methods that panic.
|
||||||
def template BasicExecPanic {{
|
def template BasicExecPanic {{
|
||||||
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
Fault
|
||||||
|
execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
||||||
{
|
{
|
||||||
panic("Execute method called when it shouldn't!");
|
panic("Execute method called when it shouldn't!");
|
||||||
M5_DUMMY_RETURN
|
M5_DUMMY_RETURN
|
||||||
|
@ -91,7 +92,8 @@ def template BasicConstructorWithMnemonic {{
|
||||||
|
|
||||||
// Basic instruction class execute method template.
|
// Basic instruction class execute method template.
|
||||||
def template BasicExecute {{
|
def template BasicExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault
|
||||||
|
%(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
@ -101,8 +103,7 @@ def template BasicExecute {{
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(code)s;
|
%(code)s;
|
||||||
|
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
return fault;
|
return fault;
|
||||||
|
|
|
@ -127,28 +127,29 @@ output decoder {{
|
||||||
|
|
||||||
template class BranchNBits<30>;
|
template class BranchNBits<30>;
|
||||||
|
|
||||||
std::string Branch::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
||||||
if(_numDestRegs && _numSrcRegs)
|
if (_numDestRegs && _numSrcRegs)
|
||||||
response << ", ";
|
response << ", ";
|
||||||
printDestReg(response, 0);
|
printDestReg(response, 0);
|
||||||
|
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BranchImm13::generateDisassembly(Addr pc,
|
std::string
|
||||||
|
BranchImm13::generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
||||||
if(_numSrcRegs > 0)
|
if (_numSrcRegs > 0)
|
||||||
response << ", ";
|
response << ", ";
|
||||||
ccprintf(response, "0x%x", imm);
|
ccprintf(response, "0x%x", imm);
|
||||||
if (_numDestRegs > 0)
|
if (_numDestRegs > 0)
|
||||||
|
@ -158,7 +159,8 @@ output decoder {{
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BranchDisp::generateDisassembly(Addr pc,
|
std::string
|
||||||
|
BranchDisp::generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
@ -170,10 +172,10 @@ output decoder {{
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
ccprintf(response, "0x%x", target);
|
ccprintf(response, "0x%x", target);
|
||||||
|
|
||||||
if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr))
|
if (symtab &&
|
||||||
{
|
symtab->findNearestSymbol(target, symbol, symbolAddr)) {
|
||||||
ccprintf(response, " <%s", symbol);
|
ccprintf(response, " <%s", symbol);
|
||||||
if(symbolAddr != target)
|
if (symbolAddr != target)
|
||||||
ccprintf(response, "+%d>", target - symbolAddr);
|
ccprintf(response, "+%d>", target - symbolAddr);
|
||||||
else
|
else
|
||||||
ccprintf(response, ">");
|
ccprintf(response, ">");
|
||||||
|
@ -187,7 +189,7 @@ def template JumpExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
//Attempt to execute the instruction
|
// Attempt to execute the instruction
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
|
@ -196,9 +198,8 @@ def template JumpExecute {{
|
||||||
PCS = PCS;
|
PCS = PCS;
|
||||||
%(code)s;
|
%(code)s;
|
||||||
|
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Write the resulting state to the execution context
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,10 +208,11 @@ def template JumpExecute {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template BranchExecute {{
|
def template BranchExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault
|
||||||
|
%(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
//Attempt to execute the instruction
|
// Attempt to execute the instruction
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
|
@ -222,9 +224,8 @@ def template BranchExecute {{
|
||||||
%(fail)s;
|
%(fail)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Write the resulting state to the execution context
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,34 +26,34 @@
|
||||||
//
|
//
|
||||||
// Authors: Gabe Black
|
// Authors: Gabe Black
|
||||||
|
|
||||||
//Include the basic format
|
// Include the basic format
|
||||||
//Templates from this format are used later
|
// Templates from this format are used later
|
||||||
##include "basic.isa"
|
##include "basic.isa"
|
||||||
|
|
||||||
//Include base classes for microcoding instructions
|
// Include base classes for microcoding instructions
|
||||||
##include "micro.isa"
|
##include "micro.isa"
|
||||||
|
|
||||||
//Include the noop format
|
// Include the noop format
|
||||||
##include "nop.isa"
|
##include "nop.isa"
|
||||||
|
|
||||||
//Include the integerOp and integerOpCc format
|
// Include the integerOp and integerOpCc format
|
||||||
##include "integerop.isa"
|
##include "integerop.isa"
|
||||||
|
|
||||||
//Include the memory formats
|
// Include the memory formats
|
||||||
##include "mem/mem.isa"
|
##include "mem/mem.isa"
|
||||||
|
|
||||||
//Include the trap format
|
// Include the trap format
|
||||||
##include "trap.isa"
|
##include "trap.isa"
|
||||||
|
|
||||||
//Include the unimplemented format
|
// Include the unimplemented format
|
||||||
##include "unimp.isa"
|
##include "unimp.isa"
|
||||||
|
|
||||||
//Include the "unknown" format
|
// Include the "unknown" format
|
||||||
##include "unknown.isa"
|
##include "unknown.isa"
|
||||||
|
|
||||||
//Include the priveleged mode format
|
// Include the priveleged mode format
|
||||||
##include "priv.isa"
|
##include "priv.isa"
|
||||||
|
|
||||||
//Include the branch format
|
// Include the branch format
|
||||||
##include "branch.isa"
|
##include "branch.isa"
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ output header {{
|
||||||
|
|
||||||
def template SetHiDecode {{
|
def template SetHiDecode {{
|
||||||
{
|
{
|
||||||
if(RD == 0 && IMM22 == 0)
|
if (RD == 0 && IMM22 == 0)
|
||||||
return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass));
|
return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass));
|
||||||
else
|
else
|
||||||
return (SparcStaticInst *)(new %(class_name)s(machInst));
|
return (SparcStaticInst *)(new %(class_name)s(machInst));
|
||||||
|
@ -151,11 +151,11 @@ def template SetHiDecode {{
|
||||||
|
|
||||||
output decoder {{
|
output decoder {{
|
||||||
|
|
||||||
bool IntOp::printPseudoOps(std::ostream &os, Addr pc,
|
bool
|
||||||
|
IntOp::printPseudoOps(std::ostream &os, Addr pc,
|
||||||
const SymbolTable *symbab) const
|
const SymbolTable *symbab) const
|
||||||
{
|
{
|
||||||
if(!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
|
if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) {
|
||||||
{
|
|
||||||
printMnemonic(os, "mov");
|
printMnemonic(os, "mov");
|
||||||
printSrcReg(os, 1);
|
printSrcReg(os, 1);
|
||||||
ccprintf(os, ", ");
|
ccprintf(os, ", ");
|
||||||
|
@ -165,25 +165,21 @@ output decoder {{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
|
bool
|
||||||
|
IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
|
||||||
const SymbolTable *symbab) const
|
const SymbolTable *symbab) const
|
||||||
{
|
{
|
||||||
if(!std::strcmp(mnemonic, "or"))
|
if (!std::strcmp(mnemonic, "or")) {
|
||||||
{
|
if (_numSrcRegs > 0 && _srcRegIdx[0] == 0) {
|
||||||
if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
|
if (imm == 0) {
|
||||||
{
|
|
||||||
if(imm == 0)
|
|
||||||
printMnemonic(os, "clr");
|
printMnemonic(os, "clr");
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
printMnemonic(os, "mov");
|
printMnemonic(os, "mov");
|
||||||
ccprintf(os, " 0x%x, ", imm);
|
ccprintf(os, " 0x%x, ", imm);
|
||||||
}
|
}
|
||||||
printDestReg(os, 0);
|
printDestReg(os, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if (imm == 0) {
|
||||||
else if(imm == 0)
|
|
||||||
{
|
|
||||||
printMnemonic(os, "mov");
|
printMnemonic(os, "mov");
|
||||||
printSrcReg(os, 0);
|
printSrcReg(os, 0);
|
||||||
ccprintf(os, ", ");
|
ccprintf(os, ", ");
|
||||||
|
@ -194,41 +190,42 @@ output decoder {{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IntOp::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
if(printPseudoOps(response, pc, symtab))
|
if (printPseudoOps(response, pc, symtab))
|
||||||
return response.str();
|
return response.str();
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
||||||
if(_numDestRegs && _numSrcRegs)
|
if (_numDestRegs && _numSrcRegs)
|
||||||
response << ", ";
|
response << ", ";
|
||||||
printDestReg(response, 0);
|
printDestReg(response, 0);
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IntOpImm::generateDisassembly(Addr pc,
|
std::string
|
||||||
|
IntOpImm::generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
if(printPseudoOps(response, pc, symtab))
|
if (printPseudoOps(response, pc, symtab))
|
||||||
return response.str();
|
return response.str();
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
printRegArray(response, _srcRegIdx, _numSrcRegs);
|
||||||
if(_numSrcRegs > 0)
|
if (_numSrcRegs > 0)
|
||||||
response << ", ";
|
response << ", ";
|
||||||
ccprintf(response, "0x%x", imm);
|
ccprintf(response, "0x%x", imm);
|
||||||
if(_numDestRegs > 0)
|
if (_numDestRegs > 0)
|
||||||
response << ", ";
|
response << ", ";
|
||||||
printDestReg(response, 0);
|
printDestReg(response, 0);
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SetHi::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
SetHi::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
|
@ -249,9 +246,8 @@ def template IntOpExecute {{
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(code)s;
|
%(code)s;
|
||||||
|
|
||||||
//Write the resulting state to the execution context
|
// Write the resulting state to the execution context
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(cc_code)s;
|
%(cc_code)s;
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,8 +100,7 @@ output decoder {{
|
||||||
bool save = flags[IsStore];
|
bool save = flags[IsStore];
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
if(save)
|
if (save) {
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[0]);
|
printReg(response, _srcRegIdx[0]);
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
}
|
}
|
||||||
|
@ -110,8 +109,7 @@ output decoder {{
|
||||||
ccprintf(response, " + ");
|
ccprintf(response, " + ");
|
||||||
printReg(response, _srcRegIdx[!save ? 1 : 2]);
|
printReg(response, _srcRegIdx[!save ? 1 : 2]);
|
||||||
ccprintf(response, " ]");
|
ccprintf(response, " ]");
|
||||||
if(load)
|
if (load) {
|
||||||
{
|
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
printReg(response, _destRegIdx[0]);
|
printReg(response, _destRegIdx[0]);
|
||||||
}
|
}
|
||||||
|
@ -127,19 +125,17 @@ output decoder {{
|
||||||
bool save = flags[IsStore];
|
bool save = flags[IsStore];
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
if(save)
|
if (save) {
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[1]);
|
printReg(response, _srcRegIdx[1]);
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
}
|
}
|
||||||
ccprintf(response, "[ ");
|
ccprintf(response, "[ ");
|
||||||
printReg(response, _srcRegIdx[0]);
|
printReg(response, _srcRegIdx[0]);
|
||||||
if(imm >= 0)
|
if (imm >= 0)
|
||||||
ccprintf(response, " + 0x%x ]", imm);
|
ccprintf(response, " + 0x%x ]", imm);
|
||||||
else
|
else
|
||||||
ccprintf(response, " + -0x%x ]", -imm);
|
ccprintf(response, " + -0x%x ]", -imm);
|
||||||
if(load)
|
if (load) {
|
||||||
{
|
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
printReg(response, _destRegIdx[0]);
|
printReg(response, _destRegIdx[0]);
|
||||||
}
|
}
|
||||||
|
@ -156,14 +152,14 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s : public %(base_class)s
|
class %(class_name)s : public %(base_class)s
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s(ExtMachInst machInst);
|
%(class_name)s(ExtMachInst machInst);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class %(class_name)s_0 : public %(base_class)sMicro
|
class %(class_name)s_0 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_0(ExtMachInst machInst);
|
%(class_name)s_0(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -173,7 +169,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_1 : public %(base_class)sMicro
|
class %(class_name)s_1 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_1(ExtMachInst machInst);
|
%(class_name)s_1(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -183,7 +179,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_2 : public %(base_class)sMicro
|
class %(class_name)s_2 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_2(ExtMachInst machInst);
|
%(class_name)s_2(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -193,7 +189,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_3 : public %(base_class)sMicro
|
class %(class_name)s_3 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_3(ExtMachInst machInst);
|
%(class_name)s_3(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -203,7 +199,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_4 : public %(base_class)sMicro
|
class %(class_name)s_4 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_4(ExtMachInst machInst);
|
%(class_name)s_4(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -213,7 +209,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_5 : public %(base_class)sMicro
|
class %(class_name)s_5 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_5(ExtMachInst machInst);
|
%(class_name)s_5(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -223,7 +219,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_6 : public %(base_class)sMicro
|
class %(class_name)s_6 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_6(ExtMachInst machInst);
|
%(class_name)s_6(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
@ -233,7 +229,7 @@ def template BlockMemDeclare {{
|
||||||
class %(class_name)s_7 : public %(base_class)sMicro
|
class %(class_name)s_7 : public %(base_class)sMicro
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//Constructor
|
// Constructor
|
||||||
%(class_name)s_7(ExtMachInst machInst);
|
%(class_name)s_7(ExtMachInst machInst);
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
// Mem formats
|
// Mem formats
|
||||||
//
|
//
|
||||||
|
|
||||||
//Include mem utility templates and functions
|
// Include mem utility templates and functions
|
||||||
##include "util.isa"
|
##include "util.isa"
|
||||||
|
|
||||||
//Include the basic memory format
|
// Include the basic memory format
|
||||||
##include "basicmem.isa"
|
##include "basicmem.isa"
|
||||||
|
|
||||||
//Include the block memory format
|
// Include the block memory format
|
||||||
##include "blockmem.isa"
|
##include "blockmem.isa"
|
||||||
|
|
||||||
//Include the load/store and cas memory format
|
// Include the load/store and cas memory format
|
||||||
##include "swap.isa"
|
##include "swap.isa"
|
||||||
|
|
|
@ -27,14 +27,14 @@
|
||||||
// Authors: Gabe Black
|
// Authors: Gabe Black
|
||||||
// Ali Saidi
|
// Ali Saidi
|
||||||
|
|
||||||
//This template provides the execute functions for a swap
|
// This template provides the execute functions for a swap
|
||||||
def template SwapExecute {{
|
def template SwapExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
//This is to support the conditional store in cas instructions.
|
// This is to support the conditional store in cas instructions.
|
||||||
//It should be optomized out in all the others
|
// It should be optomized out in all the others
|
||||||
bool storeCond = true;
|
bool storeCond = true;
|
||||||
Addr EA;
|
Addr EA;
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
|
@ -45,25 +45,21 @@ def template SwapExecute {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
||||||
%(fault_check)s;
|
%(fault_check)s;
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(storeCond && fault == NoFault)
|
if (storeCond && fault == NoFault) {
|
||||||
{
|
|
||||||
%(EA_trunc)s
|
%(EA_trunc)s
|
||||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem,
|
fault = xc->write((uint%(mem_acc_size)s_t)Mem,
|
||||||
EA, %(asi_val)s, &mem_data);
|
EA, %(asi_val)s, &mem_data);
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Handle the swapping
|
||||||
//Handle the swapping
|
%(postacc_code)s;
|
||||||
%(postacc_code)s;
|
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Write the resulting state to the execution context
|
||||||
//Write the resulting state to the execution context
|
%(op_wb)s;
|
||||||
%(op_wb)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -86,12 +82,10 @@ def template SwapInitiateAcc {{
|
||||||
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
||||||
%(fault_check)s;
|
%(fault_check)s;
|
||||||
|
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(EA_trunc)s
|
%(EA_trunc)s
|
||||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem,
|
fault = xc->write((uint%(mem_acc_size)s_t)Mem,
|
||||||
EA, %(asi_val)s, &mem_data);
|
EA, %(asi_val)s, &mem_data);
|
||||||
|
@ -111,15 +105,13 @@ def template SwapCompleteAcc {{
|
||||||
|
|
||||||
uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>();
|
uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>();
|
||||||
|
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Handle the swapping
|
||||||
//Handle the swapping
|
%(postacc_code)s;
|
||||||
%(postacc_code)s;
|
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Write the resulting state to the execution context
|
||||||
//Write the resulting state to the execution context
|
%(op_wb)s;
|
||||||
%(op_wb)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
|
|
@ -79,21 +79,18 @@ output decoder {{
|
||||||
bool store = flags[IsStore];
|
bool store = flags[IsStore];
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
if(store)
|
if (store) {
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[0]);
|
printReg(response, _srcRegIdx[0]);
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
}
|
}
|
||||||
ccprintf(response, "[");
|
ccprintf(response, "[");
|
||||||
if(_srcRegIdx[!store ? 0 : 1] != 0)
|
if (_srcRegIdx[!store ? 0 : 1] != 0) {
|
||||||
{
|
|
||||||
printSrcReg(response, !store ? 0 : 1);
|
printSrcReg(response, !store ? 0 : 1);
|
||||||
ccprintf(response, " + ");
|
ccprintf(response, " + ");
|
||||||
}
|
}
|
||||||
printSrcReg(response, !store ? 1 : 2);
|
printSrcReg(response, !store ? 1 : 2);
|
||||||
ccprintf(response, "]");
|
ccprintf(response, "]");
|
||||||
if(load)
|
if (load) {
|
||||||
{
|
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
printReg(response, _destRegIdx[0]);
|
printReg(response, _destRegIdx[0]);
|
||||||
}
|
}
|
||||||
|
@ -109,23 +106,20 @@ output decoder {{
|
||||||
bool save = flags[IsStore];
|
bool save = flags[IsStore];
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
if(save)
|
if (save) {
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[0]);
|
printReg(response, _srcRegIdx[0]);
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
}
|
}
|
||||||
ccprintf(response, "[");
|
ccprintf(response, "[");
|
||||||
if(_srcRegIdx[!save ? 0 : 1] != 0)
|
if (_srcRegIdx[!save ? 0 : 1] != 0) {
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[!save ? 0 : 1]);
|
printReg(response, _srcRegIdx[!save ? 0 : 1]);
|
||||||
ccprintf(response, " + ");
|
ccprintf(response, " + ");
|
||||||
}
|
}
|
||||||
if(imm >= 0)
|
if (imm >= 0)
|
||||||
ccprintf(response, "0x%x]", imm);
|
ccprintf(response, "0x%x]", imm);
|
||||||
else
|
else
|
||||||
ccprintf(response, "-0x%x]", -imm);
|
ccprintf(response, "-0x%x]", -imm);
|
||||||
if(load)
|
if (load) {
|
||||||
{
|
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
printReg(response, _destRegIdx[0]);
|
printReg(response, _destRegIdx[0]);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +128,7 @@ output decoder {{
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//This template provides the execute functions for a load
|
// This template provides the execute functions for a load
|
||||||
def template LoadExecute {{
|
def template LoadExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
|
@ -147,19 +141,16 @@ def template LoadExecute {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
||||||
%(fault_check)s;
|
%(fault_check)s;
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(EA_trunc)s
|
%(EA_trunc)s
|
||||||
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
|
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Write the resulting state to the execution context
|
||||||
//Write the resulting state to the execution context
|
%(op_wb)s;
|
||||||
%(op_wb)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -178,8 +169,7 @@ def template LoadInitiateAcc {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
||||||
%(fault_check)s;
|
%(fault_check)s;
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(EA_trunc)s
|
%(EA_trunc)s
|
||||||
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
|
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
|
||||||
}
|
}
|
||||||
|
@ -196,22 +186,21 @@ def template LoadCompleteAcc {{
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
Mem = pkt->get<typeof(Mem)>();
|
Mem = pkt->get<typeof(Mem)>();
|
||||||
%(code)s;
|
%(code)s;
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//This template provides the execute functions for a store
|
// This template provides the execute functions for a store
|
||||||
def template StoreExecute {{
|
def template StoreExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
//This is to support the conditional store in cas instructions.
|
// This is to support the conditional store in cas instructions.
|
||||||
//It should be optomized out in all the others
|
// It should be optomized out in all the others
|
||||||
bool storeCond = true;
|
bool storeCond = true;
|
||||||
Addr EA;
|
Addr EA;
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
|
@ -220,20 +209,17 @@ def template StoreExecute {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
||||||
%(fault_check)s;
|
%(fault_check)s;
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(storeCond && fault == NoFault)
|
if (storeCond && fault == NoFault) {
|
||||||
{
|
|
||||||
%(EA_trunc)s
|
%(EA_trunc)s
|
||||||
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||||
EA, %(asi_val)s, 0);
|
EA, %(asi_val)s, 0);
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
// Write the resulting state to the execution context
|
||||||
//Write the resulting state to the execution context
|
%(op_wb)s;
|
||||||
%(op_wb)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -254,12 +240,10 @@ def template StoreInitiateAcc {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
|
||||||
%(fault_check)s;
|
%(fault_check)s;
|
||||||
if(fault == NoFault)
|
if (fault == NoFault) {
|
||||||
{
|
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(storeCond && fault == NoFault)
|
if (storeCond && fault == NoFault) {
|
||||||
{
|
|
||||||
%(EA_trunc)s
|
%(EA_trunc)s
|
||||||
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||||
EA, %(asi_val)s, 0);
|
EA, %(asi_val)s, 0);
|
||||||
|
@ -276,17 +260,17 @@ def template StoreCompleteAcc {{
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//This delcares the initiateAcc function in memory operations
|
// This delcares the initiateAcc function in memory operations
|
||||||
def template InitiateAccDeclare {{
|
def template InitiateAccDeclare {{
|
||||||
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//This declares the completeAcc function in memory operations
|
// This declares the completeAcc function in memory operations
|
||||||
def template CompleteAccDeclare {{
|
def template CompleteAccDeclare {{
|
||||||
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
|
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//Here are some code snippets which check for various fault conditions
|
// Here are some code snippets which check for various fault conditions
|
||||||
let {{
|
let {{
|
||||||
LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
|
LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
|
||||||
StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
|
StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
|
||||||
|
@ -294,15 +278,15 @@ let {{
|
||||||
# The LSB can be zero, since it's really the MSB in doubles and quads
|
# The LSB can be zero, since it's really the MSB in doubles and quads
|
||||||
# and we're dealing with doubles
|
# and we're dealing with doubles
|
||||||
BlockAlignmentFaultCheck = '''
|
BlockAlignmentFaultCheck = '''
|
||||||
if(RD & 0xe)
|
if (RD & 0xe)
|
||||||
fault = new IllegalInstruction;
|
fault = new IllegalInstruction;
|
||||||
else if(EA & 0x3f)
|
else if (EA & 0x3f)
|
||||||
fault = new MemAddressNotAligned;
|
fault = new MemAddressNotAligned;
|
||||||
'''
|
'''
|
||||||
TwinAlignmentFaultCheck = '''
|
TwinAlignmentFaultCheck = '''
|
||||||
if(RD & 0x1)
|
if (RD & 0x1)
|
||||||
fault = new IllegalInstruction;
|
fault = new IllegalInstruction;
|
||||||
else if(EA & 0xf)
|
else if (EA & 0xf)
|
||||||
fault = new MemAddressNotAligned;
|
fault = new MemAddressNotAligned;
|
||||||
'''
|
'''
|
||||||
# XXX Need to take care of pstate.hpriv as well. The lower ASIs
|
# XXX Need to take care of pstate.hpriv as well. The lower ASIs
|
||||||
|
@ -310,10 +294,10 @@ let {{
|
||||||
# those that are only available in hpriv
|
# those that are only available in hpriv
|
||||||
AlternateASIPrivFaultCheck = '''
|
AlternateASIPrivFaultCheck = '''
|
||||||
if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) &&
|
if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) &&
|
||||||
!AsiIsUnPriv((ASI)EXT_ASI)) ||
|
!asiIsUnPriv((ASI)EXT_ASI)) ||
|
||||||
(!bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)))
|
(!bits(Hpstate,2,2) && asiIsHPriv((ASI)EXT_ASI)))
|
||||||
fault = new PrivilegedAction;
|
fault = new PrivilegedAction;
|
||||||
else if (AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
|
else if (asiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
|
||||||
fault = new PrivilegedAction;
|
fault = new PrivilegedAction;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -324,18 +308,18 @@ let {{
|
||||||
'''
|
'''
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//A simple function to generate the name of the macro op of a certain
|
// A simple function to generate the name of the macro op of a certain
|
||||||
//instruction at a certain micropc
|
// instruction at a certain micropc
|
||||||
let {{
|
let {{
|
||||||
def makeMicroName(name, microPc):
|
def makeMicroName(name, microPc):
|
||||||
return name + "::" + name + "_" + str(microPc)
|
return name + "::" + name + "_" + str(microPc)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//This function properly generates the execute functions for one of the
|
// This function properly generates the execute functions for one of the
|
||||||
//templates above. This is needed because in one case, ea computation,
|
// templates above. This is needed because in one case, ea computation,
|
||||||
//fault checks and the actual code all occur in the same function,
|
// fault checks and the actual code all occur in the same function,
|
||||||
//and in the other they're distributed across two. Also note that for
|
// and in the other they're distributed across two. Also note that for
|
||||||
//execute functions, the name of the base class doesn't matter.
|
// execute functions, the name of the base class doesn't matter.
|
||||||
let {{
|
let {{
|
||||||
def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
|
def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
|
||||||
microParam["asi_val"] = asi;
|
microParam["asi_val"] = asi;
|
||||||
|
|
|
@ -26,9 +26,10 @@
|
||||||
//
|
//
|
||||||
// Authors: Gabe Black
|
// Authors: Gabe Black
|
||||||
|
|
||||||
//This delcares the initiateAcc function in memory operations
|
// This delcares the initiateAcc function in memory operations
|
||||||
def template MacroInitiateAcc {{
|
def template MacroInitiateAcc {{
|
||||||
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
Fault
|
||||||
|
initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
||||||
{
|
{
|
||||||
panic("Tried to execute a macroop directly!\n");
|
panic("Tried to execute a macroop directly!\n");
|
||||||
return NoFault;
|
return NoFault;
|
||||||
|
@ -36,17 +37,18 @@ def template MacroInitiateAcc {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template MacroCompleteAcc {{
|
def template MacroCompleteAcc {{
|
||||||
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
|
Fault
|
||||||
Trace::InstRecord *) const
|
completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const
|
||||||
{
|
{
|
||||||
panic("Tried to execute a macroop directly!\n");
|
panic("Tried to execute a macroop directly!\n");
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//This template provides the execute functions for a store
|
// This template provides the execute functions for a store
|
||||||
def template MacroExecute {{
|
def template MacroExecute {{
|
||||||
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
Fault
|
||||||
|
execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
|
||||||
{
|
{
|
||||||
panic("Tried to execute a macroop directly!\n");
|
panic("Tried to execute a macroop directly!\n");
|
||||||
return NoFault;
|
return NoFault;
|
||||||
|
@ -60,7 +62,7 @@ output header {{
|
||||||
protected:
|
protected:
|
||||||
const uint32_t numMicroops;
|
const uint32_t numMicroops;
|
||||||
|
|
||||||
//Constructor.
|
// Constructor.
|
||||||
SparcMacroInst(const char *mnem, ExtMachInst _machInst,
|
SparcMacroInst(const char *mnem, ExtMachInst _machInst,
|
||||||
OpClass __opClass, uint32_t _numMicroops)
|
OpClass __opClass, uint32_t _numMicroops)
|
||||||
: SparcStaticInst(mnem, _machInst, __opClass),
|
: SparcStaticInst(mnem, _machInst, __opClass),
|
||||||
|
@ -96,7 +98,7 @@ output header {{
|
||||||
class SparcMicroInst : public SparcStaticInst
|
class SparcMicroInst : public SparcStaticInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
//Constructor.
|
// Constructor.
|
||||||
SparcMicroInst(const char *mnem,
|
SparcMicroInst(const char *mnem,
|
||||||
ExtMachInst _machInst, OpClass __opClass)
|
ExtMachInst _machInst, OpClass __opClass)
|
||||||
: SparcStaticInst(mnem, _machInst, __opClass)
|
: SparcStaticInst(mnem, _machInst, __opClass)
|
||||||
|
@ -117,7 +119,7 @@ output header {{
|
||||||
class SparcDelayedMicroInst : public SparcMicroInst
|
class SparcDelayedMicroInst : public SparcMicroInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
//Constructor.
|
// Constructor.
|
||||||
SparcDelayedMicroInst(const char *mnem,
|
SparcDelayedMicroInst(const char *mnem,
|
||||||
ExtMachInst _machInst, OpClass __opClass)
|
ExtMachInst _machInst, OpClass __opClass)
|
||||||
: SparcMicroInst(mnem, _machInst, __opClass)
|
: SparcMicroInst(mnem, _machInst, __opClass)
|
||||||
|
@ -129,7 +131,8 @@ output header {{
|
||||||
|
|
||||||
output decoder {{
|
output decoder {{
|
||||||
|
|
||||||
std::string SparcMacroInst::generateDisassembly(Addr pc,
|
std::string
|
||||||
|
SparcMacroInst::generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const
|
const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
|
@ -82,7 +82,7 @@ def template NopExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
//Nothing to see here, move along
|
// Nothing to see here, move along
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -50,12 +50,12 @@ output header {{
|
||||||
const SymbolTable *symtab) const;
|
const SymbolTable *symtab) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//This class is for instructions that explicitly read control
|
// This class is for instructions that explicitly read control
|
||||||
//registers. It provides a special generateDisassembly function.
|
// registers. It provides a special generateDisassembly function.
|
||||||
class RdPriv : public Priv
|
class RdPriv : public Priv
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
//Constructor
|
// Constructor
|
||||||
RdPriv(const char *mnem, ExtMachInst _machInst,
|
RdPriv(const char *mnem, ExtMachInst _machInst,
|
||||||
OpClass __opClass, char const * _regName) :
|
OpClass __opClass, char const * _regName) :
|
||||||
Priv(mnem, _machInst, __opClass), regName(_regName)
|
Priv(mnem, _machInst, __opClass), regName(_regName)
|
||||||
|
@ -68,12 +68,12 @@ output header {{
|
||||||
char const * regName;
|
char const * regName;
|
||||||
};
|
};
|
||||||
|
|
||||||
//This class is for instructions that explicitly write control
|
// This class is for instructions that explicitly write control
|
||||||
//registers. It provides a special generateDisassembly function.
|
// registers. It provides a special generateDisassembly function.
|
||||||
class WrPriv : public Priv
|
class WrPriv : public Priv
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
//Constructor
|
// Constructor
|
||||||
WrPriv(const char *mnem, ExtMachInst _machInst,
|
WrPriv(const char *mnem, ExtMachInst _machInst,
|
||||||
OpClass __opClass, char const * _regName) :
|
OpClass __opClass, char const * _regName) :
|
||||||
Priv(mnem, _machInst, __opClass), regName(_regName)
|
Priv(mnem, _machInst, __opClass), regName(_regName)
|
||||||
|
@ -102,12 +102,12 @@ output header {{
|
||||||
int32_t imm;
|
int32_t imm;
|
||||||
};
|
};
|
||||||
|
|
||||||
//This class is for instructions that explicitly write control
|
// This class is for instructions that explicitly write control
|
||||||
//registers. It provides a special generateDisassembly function.
|
// registers. It provides a special generateDisassembly function.
|
||||||
class WrPrivImm : public PrivImm
|
class WrPrivImm : public PrivImm
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
//Constructor
|
// Constructor
|
||||||
WrPrivImm(const char *mnem, ExtMachInst _machInst,
|
WrPrivImm(const char *mnem, ExtMachInst _machInst,
|
||||||
OpClass __opClass, char const * _regName) :
|
OpClass __opClass, char const * _regName) :
|
||||||
PrivImm(mnem, _machInst, __opClass), regName(_regName)
|
PrivImm(mnem, _machInst, __opClass), regName(_regName)
|
||||||
|
@ -122,8 +122,8 @@ output header {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
output decoder {{
|
output decoder {{
|
||||||
std::string Priv::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
Priv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
|
@ -132,8 +132,8 @@ output decoder {{
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RdPriv::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
RdPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
|
@ -145,18 +145,17 @@ output decoder {{
|
||||||
return response.str();
|
return response.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WrPriv::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
WrPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
|
|
||||||
ccprintf(response, " ");
|
ccprintf(response, " ");
|
||||||
//If the first reg is %g0, don't print it.
|
// If the first reg is %g0, don't print it.
|
||||||
//This improves readability
|
// This improves readability
|
||||||
if(_srcRegIdx[0] != 0)
|
if (_srcRegIdx[0] != 0) {
|
||||||
{
|
|
||||||
printSrcReg(response, 0);
|
printSrcReg(response, 0);
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
}
|
}
|
||||||
|
@ -174,10 +173,9 @@ output decoder {{
|
||||||
printMnemonic(response, mnemonic);
|
printMnemonic(response, mnemonic);
|
||||||
|
|
||||||
ccprintf(response, " ");
|
ccprintf(response, " ");
|
||||||
//If the first reg is %g0, don't print it.
|
// If the first reg is %g0, don't print it.
|
||||||
//This improves readability
|
// This improves readability
|
||||||
if(_srcRegIdx[0] != 0)
|
if (_srcRegIdx[0] != 0) {
|
||||||
{
|
|
||||||
printSrcReg(response, 0);
|
printSrcReg(response, 0);
|
||||||
ccprintf(response, ", ");
|
ccprintf(response, ", ");
|
||||||
}
|
}
|
||||||
|
@ -203,11 +201,11 @@ def template PrivExecute {{
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
|
|
||||||
//If the processor isn't in privileged mode, fault out right away
|
// If the processor isn't in privileged mode, fault out right away
|
||||||
if(%(check)s)
|
if (%(check)s)
|
||||||
return new PrivilegedAction;
|
return new PrivilegedAction;
|
||||||
|
|
||||||
if(%(tlCheck)s)
|
if (%(tlCheck)s)
|
||||||
return new IllegalInstruction;
|
return new IllegalInstruction;
|
||||||
|
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
|
|
@ -55,8 +55,8 @@ output header {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
output decoder {{
|
output decoder {{
|
||||||
std::string Trap::generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream response;
|
std::stringstream response;
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@ output decoder {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template TrapExecute {{
|
def template TrapExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault
|
||||||
|
%(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
@ -83,7 +84,8 @@ def template TrapExecute {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template FpUnimplExecute {{
|
def template FpUnimplExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault
|
||||||
|
%(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
@ -113,8 +115,8 @@ output header {{
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc,
|
std::string
|
||||||
const SymbolTable *symtab) const
|
generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
return mnemonic;
|
return mnemonic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//Include the C++ include directives
|
// Include the C++ include directives
|
||||||
##include "includes.isa"
|
##include "includes.isa"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -45,17 +45,17 @@
|
||||||
|
|
||||||
namespace SparcISA;
|
namespace SparcISA;
|
||||||
|
|
||||||
//Include the bitfield definitions
|
// Include the bitfield definitions
|
||||||
##include "bitfields.isa"
|
##include "bitfields.isa"
|
||||||
|
|
||||||
//Include the operand_types and operand definitions
|
// Include the operand_types and operand definitions
|
||||||
##include "operands.isa"
|
##include "operands.isa"
|
||||||
|
|
||||||
//Include the base class for sparc instructions, and some support code
|
// Include the base class for sparc instructions, and some support code
|
||||||
##include "base.isa"
|
##include "base.isa"
|
||||||
|
|
||||||
//Include the definitions for the instruction formats
|
// Include the definitions for the instruction formats
|
||||||
##include "formats/formats.isa"
|
##include "formats/formats.isa"
|
||||||
|
|
||||||
//Include the decoder definition
|
// Include the decoder definition
|
||||||
##include "decoder.isa"
|
##include "decoder.isa"
|
||||||
|
|
|
@ -48,17 +48,20 @@ output header {{
|
||||||
// A function to "decompress" double and quad floating point
|
// A function to "decompress" double and quad floating point
|
||||||
// register numbers stuffed into 5 bit fields. These have their
|
// register numbers stuffed into 5 bit fields. These have their
|
||||||
// MSB put in the LSB position but are otherwise normal.
|
// MSB put in the LSB position but are otherwise normal.
|
||||||
static inline unsigned int dfpr(unsigned int regNum)
|
static inline unsigned int
|
||||||
|
dfpr(unsigned int regNum)
|
||||||
{
|
{
|
||||||
return (regNum & (~1)) | ((regNum & 1) << 5);
|
return (regNum & (~1)) | ((regNum & 1) << 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int dfprl(unsigned int regNum)
|
static inline unsigned int
|
||||||
|
dfprl(unsigned int regNum)
|
||||||
{
|
{
|
||||||
return dfpr(regNum) & (~0x1);
|
return dfpr(regNum) & (~0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int dfprh(unsigned int regNum)
|
static inline unsigned int
|
||||||
|
dfprh(unsigned int regNum)
|
||||||
{
|
{
|
||||||
return dfpr(regNum) | 0x1;
|
return dfpr(regNum) | 0x1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,54 +43,54 @@ namespace BigEndianGuest {}
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
const int MachineBytes = 8;
|
const int MachineBytes = 8;
|
||||||
|
|
||||||
//This makes sure the big endian versions of certain functions are used.
|
// This makes sure the big endian versions of certain functions are used.
|
||||||
using namespace BigEndianGuest;
|
using namespace BigEndianGuest;
|
||||||
|
|
||||||
// SPARC has a delay slot
|
// SPARC has a delay slot
|
||||||
#define ISA_HAS_DELAY_SLOT 1
|
#define ISA_HAS_DELAY_SLOT 1
|
||||||
|
|
||||||
// SPARC NOP (sethi %(hi(0), g0)
|
// SPARC NOP (sethi %(hi(0), g0)
|
||||||
const MachInst NoopMachInst = 0x01000000;
|
const MachInst NoopMachInst = 0x01000000;
|
||||||
|
|
||||||
//8K. This value is implmentation specific; and should probably
|
// 8K. This value is implmentation specific; and should probably
|
||||||
//be somewhere else.
|
// be somewhere else.
|
||||||
const int LogVMPageSize = 13;
|
const int LogVMPageSize = 13;
|
||||||
const int VMPageSize = (1 << LogVMPageSize);
|
const int VMPageSize = (1 << LogVMPageSize);
|
||||||
|
|
||||||
// real address virtual mapping
|
// real address virtual mapping
|
||||||
// sort of like alpha super page, but less frequently used
|
// sort of like alpha super page, but less frequently used
|
||||||
const Addr SegKPMEnd = ULL(0xfffffffc00000000);
|
const Addr SegKPMEnd = ULL(0xfffffffc00000000);
|
||||||
const Addr SegKPMBase = ULL(0xfffffac000000000);
|
const Addr SegKPMBase = ULL(0xfffffac000000000);
|
||||||
|
|
||||||
//Why does both the previous set of constants and this one exist?
|
// Why does both the previous set of constants and this one exist?
|
||||||
const int PageShift = 13;
|
const int PageShift = 13;
|
||||||
const int PageBytes = 1ULL << PageShift;
|
const int PageBytes = 1ULL << PageShift;
|
||||||
|
|
||||||
const int BranchPredAddrShiftAmt = 2;
|
const int BranchPredAddrShiftAmt = 2;
|
||||||
|
|
||||||
StaticInstPtr decodeInst(ExtMachInst);
|
StaticInstPtr decodeInst(ExtMachInst);
|
||||||
|
|
||||||
/////////// TLB Stuff ////////////
|
/////////// TLB Stuff ////////////
|
||||||
const Addr StartVAddrHole = ULL(0x0000800000000000);
|
const Addr StartVAddrHole = ULL(0x0000800000000000);
|
||||||
const Addr EndVAddrHole = ULL(0xFFFF7FFFFFFFFFFF);
|
const Addr EndVAddrHole = ULL(0xFFFF7FFFFFFFFFFF);
|
||||||
const Addr VAddrAMask = ULL(0xFFFFFFFF);
|
const Addr VAddrAMask = ULL(0xFFFFFFFF);
|
||||||
const Addr PAddrImplMask = ULL(0x000000FFFFFFFFFF);
|
const Addr PAddrImplMask = ULL(0x000000FFFFFFFFFF);
|
||||||
const Addr BytesInPageMask = ULL(0x1FFF);
|
const Addr BytesInPageMask = ULL(0x1FFF);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
enum InterruptTypes
|
enum InterruptTypes
|
||||||
{
|
{
|
||||||
IT_TRAP_LEVEL_ZERO,
|
IT_TRAP_LEVEL_ZERO,
|
||||||
IT_HINTP,
|
IT_HINTP,
|
||||||
IT_INT_VEC,
|
IT_INT_VEC,
|
||||||
IT_CPU_MONDO,
|
IT_CPU_MONDO,
|
||||||
IT_DEV_MONDO,
|
IT_DEV_MONDO,
|
||||||
IT_RES_ERROR,
|
IT_RES_ERROR,
|
||||||
IT_SOFT_INT,
|
IT_SOFT_INT,
|
||||||
NumInterruptTypes
|
NumInterruptTypes
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,7 @@ Sparc32LinuxProcess::Sparc32LinuxProcess(LiveProcessParams * params,
|
||||||
|
|
||||||
void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
|
void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
switch(trapNum)
|
switch (trapNum) {
|
||||||
{
|
|
||||||
case 0x10: //Linux 32 bit syscall trap
|
case 0x10: //Linux 32 bit syscall trap
|
||||||
tc->syscall(tc->readIntReg(1));
|
tc->syscall(tc->readIntReg(1));
|
||||||
break;
|
break;
|
||||||
|
@ -84,10 +83,9 @@ Sparc64LinuxProcess::Sparc64LinuxProcess(LiveProcessParams * params,
|
||||||
|
|
||||||
void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
|
void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
switch(trapNum)
|
switch (trapNum) {
|
||||||
{
|
// case 0x10: // Linux 32 bit syscall trap
|
||||||
//case 0x10: //Linux 32 bit syscall trap
|
case 0x6d: // Linux 64 bit syscall trap
|
||||||
case 0x6d: //Linux 64 bit syscall trap
|
|
||||||
tc->syscall(tc->readIntReg(1));
|
tc->syscall(tc->readIntReg(1));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -37,9 +37,9 @@
|
||||||
|
|
||||||
namespace SparcISA {
|
namespace SparcISA {
|
||||||
|
|
||||||
//This contains all of the common elements of a SPARC Linux process which
|
// This contains all of the common elements of a SPARC Linux process which
|
||||||
//are not shared by other operating systems. The rest come from the common
|
// are not shared by other operating systems. The rest come from the common
|
||||||
//SPARC process class.
|
// SPARC process class.
|
||||||
class SparcLinuxProcess
|
class SparcLinuxProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -64,7 +64,8 @@ class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32LiveProcess
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
Sparc32LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
|
Sparc32LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||||
|
|
||||||
SyscallDesc* getDesc(int callnum)
|
SyscallDesc*
|
||||||
|
getDesc(int callnum)
|
||||||
{
|
{
|
||||||
return SparcLinuxProcess::getDesc32(callnum);
|
return SparcLinuxProcess::getDesc32(callnum);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,8 @@ class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64LiveProcess
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
Sparc64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
|
Sparc64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||||
|
|
||||||
SyscallDesc* getDesc(int callnum)
|
SyscallDesc*
|
||||||
|
getDesc(int callnum)
|
||||||
{
|
{
|
||||||
return SparcLinuxProcess::getDesc(callnum);
|
return SparcLinuxProcess::getDesc(callnum);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,32 +56,29 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
|
SyscallReturn
|
||||||
LiveProcess *p, ThreadContext *tc)
|
getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
const IntReg id = htog(100);
|
const IntReg id = htog(100);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
Addr ruid = p->getSyscallArg(tc, index);
|
Addr ruid = p->getSyscallArg(tc, index);
|
||||||
Addr euid = p->getSyscallArg(tc, index);
|
Addr euid = p->getSyscallArg(tc, index);
|
||||||
Addr suid = p->getSyscallArg(tc, index);
|
Addr suid = p->getSyscallArg(tc, index);
|
||||||
//Handle the EFAULT case
|
// Handle the EFAULT case
|
||||||
//Set the ruid
|
// Set the ruid
|
||||||
if(ruid)
|
if (ruid) {
|
||||||
{
|
|
||||||
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
||||||
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
ruidBuff.copyOut(tc->getMemPort());
|
ruidBuff.copyOut(tc->getMemPort());
|
||||||
}
|
}
|
||||||
//Set the euid
|
// Set the euid
|
||||||
if(euid)
|
if (euid) {
|
||||||
{
|
|
||||||
BufferArg euidBuff(euid, sizeof(IntReg));
|
BufferArg euidBuff(euid, sizeof(IntReg));
|
||||||
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
euidBuff.copyOut(tc->getMemPort());
|
euidBuff.copyOut(tc->getMemPort());
|
||||||
}
|
}
|
||||||
//Set the suid
|
// Set the suid
|
||||||
if(suid)
|
if (suid) {
|
||||||
{
|
|
||||||
BufferArg suidBuff(suid, sizeof(IntReg));
|
BufferArg suidBuff(suid, sizeof(IntReg));
|
||||||
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
suidBuff.copyOut(tc->getMemPort());
|
suidBuff.copyOut(tc->getMemPort());
|
||||||
|
@ -91,74 +88,74 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
|
||||||
|
|
||||||
SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
|
/* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
|
||||||
/* 1 */ SyscallDesc("exit", exitFunc), //32 bit
|
/* 1 */ SyscallDesc("exit", exitFunc), // 32 bit
|
||||||
/* 2 */ SyscallDesc("fork", unimplementedFunc),
|
/* 2 */ SyscallDesc("fork", unimplementedFunc),
|
||||||
/* 3 */ SyscallDesc("read", readFunc),
|
/* 3 */ SyscallDesc("read", readFunc),
|
||||||
/* 4 */ SyscallDesc("write", writeFunc),
|
/* 4 */ SyscallDesc("write", writeFunc),
|
||||||
/* 5 */ SyscallDesc("open", openFunc<Sparc32Linux>), //32 bit
|
/* 5 */ SyscallDesc("open", openFunc<Sparc32Linux>), // 32 bit
|
||||||
/* 6 */ SyscallDesc("close", closeFunc),
|
/* 6 */ SyscallDesc("close", closeFunc),
|
||||||
/* 7 */ SyscallDesc("wait4", unimplementedFunc), //32 bit
|
/* 7 */ SyscallDesc("wait4", unimplementedFunc), // 32 bit
|
||||||
/* 8 */ SyscallDesc("creat", unimplementedFunc), //32 bit
|
/* 8 */ SyscallDesc("creat", unimplementedFunc), // 32 bit
|
||||||
/* 9 */ SyscallDesc("link", unimplementedFunc),
|
/* 9 */ SyscallDesc("link", unimplementedFunc),
|
||||||
/* 10 */ SyscallDesc("unlink", unlinkFunc),
|
/* 10 */ SyscallDesc("unlink", unlinkFunc),
|
||||||
/* 11 */ SyscallDesc("execv", unimplementedFunc),
|
/* 11 */ SyscallDesc("execv", unimplementedFunc),
|
||||||
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
|
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
|
||||||
/* 13 */ SyscallDesc("chown", chownFunc), //32 bit
|
/* 13 */ SyscallDesc("chown", chownFunc), // 32 bit
|
||||||
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
|
||||||
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
|
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
|
||||||
/* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit
|
/* 16 */ SyscallDesc("lchown", unimplementedFunc), // 32 bit
|
||||||
/* 17 */ SyscallDesc("brk", brkFunc),
|
/* 17 */ SyscallDesc("brk", brkFunc),
|
||||||
/* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit
|
/* 18 */ SyscallDesc("perfctr", unimplementedFunc), // 32 bit
|
||||||
/* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit
|
/* 19 */ SyscallDesc("lseek", lseekFunc), // 32 bit
|
||||||
/* 20 */ SyscallDesc("getpid", getpidFunc),
|
/* 20 */ SyscallDesc("getpid", getpidFunc),
|
||||||
/* 21 */ SyscallDesc("capget", unimplementedFunc),
|
/* 21 */ SyscallDesc("capget", unimplementedFunc),
|
||||||
/* 22 */ SyscallDesc("capset", unimplementedFunc),
|
/* 22 */ SyscallDesc("capset", unimplementedFunc),
|
||||||
/* 23 */ SyscallDesc("setuid", setuidFunc), //32 bit
|
/* 23 */ SyscallDesc("setuid", setuidFunc), // 32 bit
|
||||||
/* 24 */ SyscallDesc("getuid", getuidFunc), //32 bit
|
/* 24 */ SyscallDesc("getuid", getuidFunc), // 32 bit
|
||||||
/* 25 */ SyscallDesc("time", unimplementedFunc),
|
/* 25 */ SyscallDesc("time", unimplementedFunc),
|
||||||
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
|
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
|
||||||
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
|
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
|
||||||
/* 28 */ SyscallDesc("sigaltstack", unimplementedFunc), //32 bit
|
/* 28 */ SyscallDesc("sigaltstack", unimplementedFunc), // 32 bit
|
||||||
/* 29 */ SyscallDesc("pause", unimplementedFunc), //32 bit
|
/* 29 */ SyscallDesc("pause", unimplementedFunc), // 32 bit
|
||||||
/* 30 */ SyscallDesc("utime", unimplementedFunc),
|
/* 30 */ SyscallDesc("utime", unimplementedFunc),
|
||||||
/* 31 */ SyscallDesc("lchown32", unimplementedFunc),
|
/* 31 */ SyscallDesc("lchown32", unimplementedFunc),
|
||||||
/* 32 */ SyscallDesc("fchown32", unimplementedFunc),
|
/* 32 */ SyscallDesc("fchown32", unimplementedFunc),
|
||||||
/* 33 */ SyscallDesc("access", unimplementedFunc), //32 bit
|
/* 33 */ SyscallDesc("access", unimplementedFunc), // 32 bit
|
||||||
/* 34 */ SyscallDesc("nice", unimplementedFunc), //32 bit
|
/* 34 */ SyscallDesc("nice", unimplementedFunc), // 32 bit
|
||||||
/* 35 */ SyscallDesc("chown32", unimplementedFunc),
|
/* 35 */ SyscallDesc("chown32", unimplementedFunc),
|
||||||
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
||||||
/* 37 */ SyscallDesc("kill", unimplementedFunc), //32 bit
|
/* 37 */ SyscallDesc("kill", unimplementedFunc), // 32 bit
|
||||||
/* 38 */ SyscallDesc("stat", unimplementedFunc),
|
/* 38 */ SyscallDesc("stat", unimplementedFunc),
|
||||||
/* 39 */ SyscallDesc("sendfile", unimplementedFunc), //32 bit
|
/* 39 */ SyscallDesc("sendfile", unimplementedFunc), // 32 bit
|
||||||
/* 40 */ SyscallDesc("lstat", unimplementedFunc),
|
/* 40 */ SyscallDesc("lstat", unimplementedFunc),
|
||||||
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
||||||
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
|
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
|
||||||
/* 43 */ SyscallDesc("times", ignoreFunc),
|
/* 43 */ SyscallDesc("times", ignoreFunc),
|
||||||
/* 44 */ SyscallDesc("getuid32", unimplementedFunc),
|
/* 44 */ SyscallDesc("getuid32", unimplementedFunc),
|
||||||
/* 45 */ SyscallDesc("umount2", unimplementedFunc), //32 bit
|
/* 45 */ SyscallDesc("umount2", unimplementedFunc), // 32 bit
|
||||||
/* 46 */ SyscallDesc("setgid", unimplementedFunc), //32 bit
|
/* 46 */ SyscallDesc("setgid", unimplementedFunc), // 32 bit
|
||||||
/* 47 */ SyscallDesc("getgid", getgidFunc), //32 bit
|
/* 47 */ SyscallDesc("getgid", getgidFunc), // 32 bit
|
||||||
/* 48 */ SyscallDesc("signal", unimplementedFunc), //32 bit
|
/* 48 */ SyscallDesc("signal", unimplementedFunc), // 32 bit
|
||||||
/* 49 */ SyscallDesc("geteuid", geteuidFunc), //32 bit
|
/* 49 */ SyscallDesc("geteuid", geteuidFunc), // 32 bit
|
||||||
/* 50 */ SyscallDesc("getegid", getegidFunc), //32 bit
|
/* 50 */ SyscallDesc("getegid", getegidFunc), // 32 bit
|
||||||
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
||||||
/* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
|
/* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
|
||||||
/* 53 */ SyscallDesc("getgid32", unimplementedFunc),
|
/* 53 */ SyscallDesc("getgid32", unimplementedFunc),
|
||||||
/* 54 */ SyscallDesc("ioctl", unimplementedFunc),
|
/* 54 */ SyscallDesc("ioctl", unimplementedFunc),
|
||||||
/* 55 */ SyscallDesc("reboot", unimplementedFunc), //32 bit
|
/* 55 */ SyscallDesc("reboot", unimplementedFunc), // 32 bit
|
||||||
/* 56 */ SyscallDesc("mmap2", unimplementedFunc), //32 bit
|
/* 56 */ SyscallDesc("mmap2", unimplementedFunc), // 32 bit
|
||||||
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
|
||||||
/* 58 */ SyscallDesc("readlink", readlinkFunc), //32 bit
|
/* 58 */ SyscallDesc("readlink", readlinkFunc), // 32 bit
|
||||||
/* 59 */ SyscallDesc("execve", unimplementedFunc), //32 bit
|
/* 59 */ SyscallDesc("execve", unimplementedFunc), // 32 bit
|
||||||
/* 60 */ SyscallDesc("umask", unimplementedFunc), //32 bit
|
/* 60 */ SyscallDesc("umask", unimplementedFunc), // 32 bit
|
||||||
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
|
||||||
/* 62 */ SyscallDesc("fstat", unimplementedFunc),
|
/* 62 */ SyscallDesc("fstat", unimplementedFunc),
|
||||||
/* 63 */ SyscallDesc("fstat64", fstat64Func<Sparc32Linux>),
|
/* 63 */ SyscallDesc("fstat64", fstat64Func<Sparc32Linux>),
|
||||||
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
|
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
|
||||||
/* 65 */ SyscallDesc("msync", unimplementedFunc), //32 bit
|
/* 65 */ SyscallDesc("msync", unimplementedFunc), // 32 bit
|
||||||
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
|
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
|
||||||
/* 67 */ SyscallDesc("pread64", unimplementedFunc), //32 bit
|
/* 67 */ SyscallDesc("pread64", unimplementedFunc), // 32 bit
|
||||||
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc), //32 bit
|
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc), // 32 bit
|
||||||
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
|
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
|
||||||
/* 70 */ SyscallDesc("getegid32", unimplementedFunc),
|
/* 70 */ SyscallDesc("getegid32", unimplementedFunc),
|
||||||
/* 71 */ SyscallDesc("mmap", mmapFunc<Sparc32Linux>),
|
/* 71 */ SyscallDesc("mmap", mmapFunc<Sparc32Linux>),
|
||||||
|
@ -167,36 +164,36 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
|
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
|
||||||
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
|
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
|
||||||
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
|
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
|
||||||
/* 77 */ SyscallDesc("truncate64", unimplementedFunc), //32 bit
|
/* 77 */ SyscallDesc("truncate64", unimplementedFunc), // 32 bit
|
||||||
/* 78 */ SyscallDesc("mincore", unimplementedFunc),
|
/* 78 */ SyscallDesc("mincore", unimplementedFunc),
|
||||||
/* 79 */ SyscallDesc("getgroups", unimplementedFunc), //32 bit
|
/* 79 */ SyscallDesc("getgroups", unimplementedFunc), // 32 bit
|
||||||
/* 80 */ SyscallDesc("setgroups", unimplementedFunc), //32 bit
|
/* 80 */ SyscallDesc("setgroups", unimplementedFunc), // 32 bit
|
||||||
/* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
|
/* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
|
||||||
/* 82 */ SyscallDesc("setgroups32", unimplementedFunc), //32 bit
|
/* 82 */ SyscallDesc("setgroups32", unimplementedFunc), // 32 bit
|
||||||
/* 83 */ SyscallDesc("setitimer", unimplementedFunc), //32 bit
|
/* 83 */ SyscallDesc("setitimer", unimplementedFunc), // 32 bit
|
||||||
/* 84 */ SyscallDesc("ftruncate64", unimplementedFunc), //32 bit
|
/* 84 */ SyscallDesc("ftruncate64", unimplementedFunc), // 32 bit
|
||||||
/* 85 */ SyscallDesc("swapon", unimplementedFunc), //32 bit
|
/* 85 */ SyscallDesc("swapon", unimplementedFunc), // 32 bit
|
||||||
/* 86 */ SyscallDesc("getitimer", unimplementedFunc), //32 bit
|
/* 86 */ SyscallDesc("getitimer", unimplementedFunc), // 32 bit
|
||||||
/* 87 */ SyscallDesc("setuid32", unimplementedFunc),
|
/* 87 */ SyscallDesc("setuid32", unimplementedFunc),
|
||||||
/* 88 */ SyscallDesc("sethostname", unimplementedFunc), //32 bit
|
/* 88 */ SyscallDesc("sethostname", unimplementedFunc), // 32 bit
|
||||||
/* 89 */ SyscallDesc("setgid32", unimplementedFunc),
|
/* 89 */ SyscallDesc("setgid32", unimplementedFunc),
|
||||||
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
|
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
|
||||||
/* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
|
/* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
|
||||||
/* 92 */ SyscallDesc("fcntl", unimplementedFunc),
|
/* 92 */ SyscallDesc("fcntl", unimplementedFunc),
|
||||||
/* 93 */ SyscallDesc("select", unimplementedFunc), //32 bit
|
/* 93 */ SyscallDesc("select", unimplementedFunc), // 32 bit
|
||||||
/* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
|
/* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
|
||||||
/* 95 */ SyscallDesc("fsync", unimplementedFunc),
|
/* 95 */ SyscallDesc("fsync", unimplementedFunc),
|
||||||
/* 96 */ SyscallDesc("setpriority", unimplementedFunc), //32 bit
|
/* 96 */ SyscallDesc("setpriority", unimplementedFunc), // 32 bit
|
||||||
/* 97 */ SyscallDesc("socket", unimplementedFunc),
|
/* 97 */ SyscallDesc("socket", unimplementedFunc),
|
||||||
/* 98 */ SyscallDesc("connect", unimplementedFunc),
|
/* 98 */ SyscallDesc("connect", unimplementedFunc),
|
||||||
/* 99 */ SyscallDesc("accept", unimplementedFunc),
|
/* 99 */ SyscallDesc("accept", unimplementedFunc),
|
||||||
/* 100 */ SyscallDesc("getpriority", unimplementedFunc), //32 bit
|
/* 100 */ SyscallDesc("getpriority", unimplementedFunc), // 32 bit
|
||||||
/* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc), //32 bit
|
/* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc), // 32 bit
|
||||||
/* 102 */ SyscallDesc("rt_sigaction", ignoreFunc), //32 bit
|
/* 102 */ SyscallDesc("rt_sigaction", ignoreFunc), // 32 bit
|
||||||
/* 103 */ SyscallDesc("rt_sigprocmask", ignoreFunc), //32 bit
|
/* 103 */ SyscallDesc("rt_sigprocmask", ignoreFunc), // 32 bit
|
||||||
/* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc), //32 bit
|
/* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc), // 32 bit
|
||||||
/* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
/* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
||||||
/* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), //32 bit
|
/* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), // 32 bit
|
||||||
/* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
|
/* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
|
||||||
/* 108 */ SyscallDesc("setresuid32", unimplementedFunc),
|
/* 108 */ SyscallDesc("setresuid32", unimplementedFunc),
|
||||||
/* 109 */ SyscallDesc("getresuid32", getresuidFunc),
|
/* 109 */ SyscallDesc("getresuid32", getresuidFunc),
|
||||||
|
@ -205,19 +202,19 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 112 */ SyscallDesc("setregid32", unimplementedFunc),
|
/* 112 */ SyscallDesc("setregid32", unimplementedFunc),
|
||||||
/* 113 */ SyscallDesc("revcmsg", unimplementedFunc),
|
/* 113 */ SyscallDesc("revcmsg", unimplementedFunc),
|
||||||
/* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
|
/* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
|
||||||
/* 115 */ SyscallDesc("getgroups32", unimplementedFunc), //32 bit
|
/* 115 */ SyscallDesc("getgroups32", unimplementedFunc), // 32 bit
|
||||||
/* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<Sparc32Linux>), //32 bit
|
/* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<Sparc32Linux>), // 32 bit
|
||||||
/* 117 */ SyscallDesc("getrusage", unimplementedFunc), //32 bit
|
/* 117 */ SyscallDesc("getrusage", unimplementedFunc), // 32 bit
|
||||||
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
|
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
|
||||||
/* 119 */ SyscallDesc("getcwd", getcwdFunc),
|
/* 119 */ SyscallDesc("getcwd", getcwdFunc),
|
||||||
/* 120 */ SyscallDesc("readv", unimplementedFunc),
|
/* 120 */ SyscallDesc("readv", unimplementedFunc),
|
||||||
/* 121 */ SyscallDesc("writev", unimplementedFunc),
|
/* 121 */ SyscallDesc("writev", unimplementedFunc),
|
||||||
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc), //32 bit
|
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc), // 32 bit
|
||||||
/* 123 */ SyscallDesc("fchown", unimplementedFunc), //32 bit
|
/* 123 */ SyscallDesc("fchown", unimplementedFunc), // 32 bit
|
||||||
/* 124 */ SyscallDesc("fchmod", unimplementedFunc),
|
/* 124 */ SyscallDesc("fchmod", unimplementedFunc),
|
||||||
/* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
|
/* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
|
||||||
/* 126 */ SyscallDesc("setreuid", unimplementedFunc), //32 bit
|
/* 126 */ SyscallDesc("setreuid", unimplementedFunc), // 32 bit
|
||||||
/* 127 */ SyscallDesc("setregid", unimplementedFunc), //32 bit
|
/* 127 */ SyscallDesc("setregid", unimplementedFunc), // 32 bit
|
||||||
/* 128 */ SyscallDesc("rename", renameFunc),
|
/* 128 */ SyscallDesc("rename", renameFunc),
|
||||||
/* 129 */ SyscallDesc("truncate", unimplementedFunc),
|
/* 129 */ SyscallDesc("truncate", unimplementedFunc),
|
||||||
/* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
|
/* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
|
||||||
|
@ -226,18 +223,18 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
|
||||||
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
|
||||||
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
|
||||||
/* 136 */ SyscallDesc("mkdir", mkdirFunc), //32 bit
|
/* 136 */ SyscallDesc("mkdir", mkdirFunc), // 32 bit
|
||||||
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
|
||||||
/* 138 */ SyscallDesc("utimes", unimplementedFunc), //32 bit
|
/* 138 */ SyscallDesc("utimes", unimplementedFunc), // 32 bit
|
||||||
/* 139 */ SyscallDesc("stat64", unimplementedFunc),
|
/* 139 */ SyscallDesc("stat64", unimplementedFunc),
|
||||||
/* 140 */ SyscallDesc("sendfile64", unimplementedFunc), //32 bit
|
/* 140 */ SyscallDesc("sendfile64", unimplementedFunc), // 32 bit
|
||||||
/* 141 */ SyscallDesc("getpeername", unimplementedFunc),
|
/* 141 */ SyscallDesc("getpeername", unimplementedFunc),
|
||||||
/* 142 */ SyscallDesc("futex", unimplementedFunc), //32 bit
|
/* 142 */ SyscallDesc("futex", unimplementedFunc), // 32 bit
|
||||||
/* 143 */ SyscallDesc("gettid", unimplementedFunc),
|
/* 143 */ SyscallDesc("gettid", unimplementedFunc),
|
||||||
/* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
|
/* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
|
||||||
/* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
|
/* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
|
||||||
/* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
|
/* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
|
||||||
/* 147 */ SyscallDesc("prctl", unimplementedFunc), //32 bit
|
/* 147 */ SyscallDesc("prctl", unimplementedFunc), // 32 bit
|
||||||
/* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
|
/* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
|
||||||
/* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
|
/* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
|
||||||
/* 150 */ SyscallDesc("getsockname", unimplementedFunc),
|
/* 150 */ SyscallDesc("getsockname", unimplementedFunc),
|
||||||
|
@ -252,75 +249,75 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 159 */ SyscallDesc("umount", unimplementedFunc),
|
/* 159 */ SyscallDesc("umount", unimplementedFunc),
|
||||||
/* 160 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
/* 160 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
||||||
/* 161 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
/* 161 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
||||||
/* 162 */ SyscallDesc("getdomainname", unimplementedFunc), //32 bit
|
/* 162 */ SyscallDesc("getdomainname", unimplementedFunc), // 32 bit
|
||||||
/* 163 */ SyscallDesc("setdomainname", unimplementedFunc), //32 bit
|
/* 163 */ SyscallDesc("setdomainname", unimplementedFunc), // 32 bit
|
||||||
/* 164 */ SyscallDesc("ni_syscall", unimplementedFunc),
|
/* 164 */ SyscallDesc("ni_syscall", unimplementedFunc),
|
||||||
/* 165 */ SyscallDesc("quotactl", unimplementedFunc),
|
/* 165 */ SyscallDesc("quotactl", unimplementedFunc),
|
||||||
/* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
|
/* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
|
||||||
/* 167 */ SyscallDesc("mount", unimplementedFunc),
|
/* 167 */ SyscallDesc("mount", unimplementedFunc),
|
||||||
/* 168 */ SyscallDesc("ustat", unimplementedFunc),
|
/* 168 */ SyscallDesc("ustat", unimplementedFunc),
|
||||||
/* 169 */ SyscallDesc("setxattr", unimplementedFunc), //32 bit
|
/* 169 */ SyscallDesc("setxattr", unimplementedFunc), // 32 bit
|
||||||
/* 170 */ SyscallDesc("lsetxattr", unimplementedFunc), //32 bit
|
/* 170 */ SyscallDesc("lsetxattr", unimplementedFunc), // 32 bit
|
||||||
/* 171 */ SyscallDesc("fsetxattr", unimplementedFunc), //32 bit
|
/* 171 */ SyscallDesc("fsetxattr", unimplementedFunc), // 32 bit
|
||||||
/* 172 */ SyscallDesc("getxattr", unimplementedFunc),
|
/* 172 */ SyscallDesc("getxattr", unimplementedFunc),
|
||||||
/* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
|
/* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
|
||||||
/* 174 */ SyscallDesc("getdents", unimplementedFunc),
|
/* 174 */ SyscallDesc("getdents", unimplementedFunc),
|
||||||
/* 175 */ SyscallDesc("setsid", unimplementedFunc),
|
/* 175 */ SyscallDesc("setsid", unimplementedFunc),
|
||||||
/* 176 */ SyscallDesc("fchdir", unimplementedFunc),
|
/* 176 */ SyscallDesc("fchdir", unimplementedFunc),
|
||||||
/* 177 */ SyscallDesc("fgetxattr", unimplementedFunc), //32 bit
|
/* 177 */ SyscallDesc("fgetxattr", unimplementedFunc), // 32 bit
|
||||||
/* 178 */ SyscallDesc("listxattr", unimplementedFunc),
|
/* 178 */ SyscallDesc("listxattr", unimplementedFunc),
|
||||||
/* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
|
/* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
|
||||||
/* 180 */ SyscallDesc("flistxattr", unimplementedFunc), //32 bit
|
/* 180 */ SyscallDesc("flistxattr", unimplementedFunc), // 32 bit
|
||||||
/* 181 */ SyscallDesc("removexattr", unimplementedFunc),
|
/* 181 */ SyscallDesc("removexattr", unimplementedFunc),
|
||||||
/* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
|
/* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
|
||||||
/* 183 */ SyscallDesc("sigpending", unimplementedFunc),
|
/* 183 */ SyscallDesc("sigpending", unimplementedFunc),
|
||||||
/* 184 */ SyscallDesc("query_module", unimplementedFunc),
|
/* 184 */ SyscallDesc("query_module", unimplementedFunc),
|
||||||
/* 185 */ SyscallDesc("setpgid", unimplementedFunc), //32 bit
|
/* 185 */ SyscallDesc("setpgid", unimplementedFunc), // 32 bit
|
||||||
/* 186 */ SyscallDesc("fremovexattr", unimplementedFunc), //32 bit
|
/* 186 */ SyscallDesc("fremovexattr", unimplementedFunc), // 32 bit
|
||||||
/* 187 */ SyscallDesc("tkill", unimplementedFunc), //32 bit
|
/* 187 */ SyscallDesc("tkill", unimplementedFunc), // 32 bit
|
||||||
/* 188 */ SyscallDesc("exit_group", exitGroupFunc), //32 bit
|
/* 188 */ SyscallDesc("exit_group", exitGroupFunc), // 32 bit
|
||||||
/* 189 */ SyscallDesc("uname", unameFunc),
|
/* 189 */ SyscallDesc("uname", unameFunc),
|
||||||
/* 190 */ SyscallDesc("init_module", unimplementedFunc), //32 bit
|
/* 190 */ SyscallDesc("init_module", unimplementedFunc), // 32 bit
|
||||||
/* 191 */ SyscallDesc("personality", unimplementedFunc),
|
/* 191 */ SyscallDesc("personality", unimplementedFunc),
|
||||||
/* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
|
/* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
|
||||||
/* 193 */ SyscallDesc("epoll_create", unimplementedFunc), //32 bit
|
/* 193 */ SyscallDesc("epoll_create", unimplementedFunc), // 32 bit
|
||||||
/* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc), //32 bit
|
/* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc), // 32 bit
|
||||||
/* 195 */ SyscallDesc("epoll_wait", unimplementedFunc), //32 bit
|
/* 195 */ SyscallDesc("epoll_wait", unimplementedFunc), // 32 bit
|
||||||
/* 196 */ SyscallDesc("ioprio_set", unimplementedFunc), //32 bit
|
/* 196 */ SyscallDesc("ioprio_set", unimplementedFunc), // 32 bit
|
||||||
/* 197 */ SyscallDesc("getppid", getppidFunc),
|
/* 197 */ SyscallDesc("getppid", getppidFunc),
|
||||||
/* 198 */ SyscallDesc("sigaction", unimplementedFunc), //32 bit
|
/* 198 */ SyscallDesc("sigaction", unimplementedFunc), // 32 bit
|
||||||
/* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
|
/* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
|
||||||
/* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
|
/* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
|
||||||
/* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
/* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
||||||
/* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
|
/* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
|
||||||
/* 203 */ SyscallDesc("uselib", unimplementedFunc),
|
/* 203 */ SyscallDesc("uselib", unimplementedFunc),
|
||||||
/* 204 */ SyscallDesc("readdir", unimplementedFunc),
|
/* 204 */ SyscallDesc("readdir", unimplementedFunc),
|
||||||
/* 205 */ SyscallDesc("readahead", unimplementedFunc), //32 bit
|
/* 205 */ SyscallDesc("readahead", unimplementedFunc), // 32 bit
|
||||||
/* 206 */ SyscallDesc("socketcall", unimplementedFunc), //32 bit
|
/* 206 */ SyscallDesc("socketcall", unimplementedFunc), // 32 bit
|
||||||
/* 207 */ SyscallDesc("syslog", unimplementedFunc), //32 bit
|
/* 207 */ SyscallDesc("syslog", unimplementedFunc), // 32 bit
|
||||||
/* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc), //32 bit
|
/* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc), // 32 bit
|
||||||
/* 209 */ SyscallDesc("fadvise64", unimplementedFunc), //32 bit
|
/* 209 */ SyscallDesc("fadvise64", unimplementedFunc), // 32 bit
|
||||||
/* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc), //32 bit
|
/* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc), // 32 bit
|
||||||
/* 211 */ SyscallDesc("tgkill", unimplementedFunc), //32 bit
|
/* 211 */ SyscallDesc("tgkill", unimplementedFunc), // 32 bit
|
||||||
/* 212 */ SyscallDesc("waitpid", unimplementedFunc), //32 bit
|
/* 212 */ SyscallDesc("waitpid", unimplementedFunc), // 32 bit
|
||||||
/* 213 */ SyscallDesc("swapoff", unimplementedFunc),
|
/* 213 */ SyscallDesc("swapoff", unimplementedFunc),
|
||||||
/* 214 */ SyscallDesc("sysinfo", sysinfoFunc<Sparc32Linux>), //32 bit
|
/* 214 */ SyscallDesc("sysinfo", sysinfoFunc<Sparc32Linux>), // 32 bit
|
||||||
/* 215 */ SyscallDesc("ipc", unimplementedFunc), //32 bit
|
/* 215 */ SyscallDesc("ipc", unimplementedFunc), // 32 bit
|
||||||
/* 216 */ SyscallDesc("sigreturn", unimplementedFunc), //32 bit
|
/* 216 */ SyscallDesc("sigreturn", unimplementedFunc), // 32 bit
|
||||||
/* 217 */ SyscallDesc("clone", cloneFunc),
|
/* 217 */ SyscallDesc("clone", cloneFunc),
|
||||||
/* 218 */ SyscallDesc("ioprio_get", unimplementedFunc), //32 bit
|
/* 218 */ SyscallDesc("ioprio_get", unimplementedFunc), // 32 bit
|
||||||
/* 219 */ SyscallDesc("adjtimex", unimplementedFunc), //32 bit
|
/* 219 */ SyscallDesc("adjtimex", unimplementedFunc), // 32 bit
|
||||||
/* 220 */ SyscallDesc("sigprocmask", unimplementedFunc), //32 bit
|
/* 220 */ SyscallDesc("sigprocmask", unimplementedFunc), // 32 bit
|
||||||
/* 221 */ SyscallDesc("create_module", unimplementedFunc),
|
/* 221 */ SyscallDesc("create_module", unimplementedFunc),
|
||||||
/* 222 */ SyscallDesc("delete_module", unimplementedFunc), //32 bit
|
/* 222 */ SyscallDesc("delete_module", unimplementedFunc), // 32 bit
|
||||||
/* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
|
/* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
|
||||||
/* 224 */ SyscallDesc("getpgid", unimplementedFunc), //32 bit
|
/* 224 */ SyscallDesc("getpgid", unimplementedFunc), // 32 bit
|
||||||
/* 225 */ SyscallDesc("bdflush", unimplementedFunc), //32 bit
|
/* 225 */ SyscallDesc("bdflush", unimplementedFunc), // 32 bit
|
||||||
/* 226 */ SyscallDesc("sysfs", unimplementedFunc), //32 bit
|
/* 226 */ SyscallDesc("sysfs", unimplementedFunc), // 32 bit
|
||||||
/* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
/* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
|
||||||
/* 228 */ SyscallDesc("setfsuid", unimplementedFunc), //32 bit
|
/* 228 */ SyscallDesc("setfsuid", unimplementedFunc), // 32 bit
|
||||||
/* 229 */ SyscallDesc("setfsgid", unimplementedFunc), //32 bit
|
/* 229 */ SyscallDesc("setfsgid", unimplementedFunc), // 32 bit
|
||||||
/* 230 */ SyscallDesc("_newselect", unimplementedFunc), //32 bit
|
/* 230 */ SyscallDesc("_newselect", unimplementedFunc), // 32 bit
|
||||||
/* 231 */ SyscallDesc("time", ignoreFunc),
|
/* 231 */ SyscallDesc("time", ignoreFunc),
|
||||||
/* 232 */ SyscallDesc("oldstat", unimplementedFunc),
|
/* 232 */ SyscallDesc("oldstat", unimplementedFunc),
|
||||||
/* 233 */ SyscallDesc("stime", unimplementedFunc),
|
/* 233 */ SyscallDesc("stime", unimplementedFunc),
|
||||||
|
@ -329,30 +326,30 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 236 */ SyscallDesc("_llseek", _llseekFunc),
|
/* 236 */ SyscallDesc("_llseek", _llseekFunc),
|
||||||
/* 237 */ SyscallDesc("mlock", unimplementedFunc),
|
/* 237 */ SyscallDesc("mlock", unimplementedFunc),
|
||||||
/* 238 */ SyscallDesc("munlock", unimplementedFunc),
|
/* 238 */ SyscallDesc("munlock", unimplementedFunc),
|
||||||
/* 239 */ SyscallDesc("mlockall", unimplementedFunc), //32 bit
|
/* 239 */ SyscallDesc("mlockall", unimplementedFunc), // 32 bit
|
||||||
/* 240 */ SyscallDesc("munlockall", unimplementedFunc),
|
/* 240 */ SyscallDesc("munlockall", unimplementedFunc),
|
||||||
/* 241 */ SyscallDesc("sched_setparam", unimplementedFunc), //32 bit
|
/* 241 */ SyscallDesc("sched_setparam", unimplementedFunc), // 32 bit
|
||||||
/* 242 */ SyscallDesc("sched_getparam", unimplementedFunc), //32 bit
|
/* 242 */ SyscallDesc("sched_getparam", unimplementedFunc), // 32 bit
|
||||||
/* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc), //32 bit
|
/* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc), // 32 bit
|
||||||
/* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc), //32 bit
|
/* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc), // 32 bit
|
||||||
/* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
|
/* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
|
||||||
/* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), //32 bit
|
/* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), // 32 bit
|
||||||
/* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), //32 bit
|
/* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), // 32 bit
|
||||||
/* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), //32 bit
|
/* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), // 32 bit
|
||||||
/* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
|
/* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
|
||||||
/* 250 */ SyscallDesc("mremap", mremapFunc<Sparc32Linux>), //32 bit
|
/* 250 */ SyscallDesc("mremap", mremapFunc<Sparc32Linux>), // 32 bit
|
||||||
/* 251 */ SyscallDesc("_sysctl", unimplementedFunc), //32 bit
|
/* 251 */ SyscallDesc("_sysctl", unimplementedFunc), // 32 bit
|
||||||
/* 252 */ SyscallDesc("getsid", unimplementedFunc), //32 bit
|
/* 252 */ SyscallDesc("getsid", unimplementedFunc), // 32 bit
|
||||||
/* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
|
/* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
|
||||||
/* 254 */ SyscallDesc("nfsservctl", unimplementedFunc), //32 bit
|
/* 254 */ SyscallDesc("nfsservctl", unimplementedFunc), // 32 bit
|
||||||
/* 255 */ SyscallDesc("aplib", unimplementedFunc),
|
/* 255 */ SyscallDesc("aplib", unimplementedFunc),
|
||||||
/* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
|
/* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
|
||||||
/* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
|
/* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
|
||||||
/* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
|
/* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
|
||||||
/* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc), //32 bit
|
/* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc), // 32 bit
|
||||||
/* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
/* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
||||||
/* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
/* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
||||||
/* 262 */ SyscallDesc("timer_settime", unimplementedFunc), //32 bit
|
/* 262 */ SyscallDesc("timer_settime", unimplementedFunc), // 32 bit
|
||||||
/* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
|
/* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
|
||||||
/* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
|
/* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
|
||||||
/* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
|
/* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
|
||||||
|
@ -360,10 +357,10 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
|
||||||
/* 267 */ SyscallDesc("vserver", unimplementedFunc),
|
/* 267 */ SyscallDesc("vserver", unimplementedFunc),
|
||||||
/* 268 */ SyscallDesc("io_setup", unimplementedFunc),
|
/* 268 */ SyscallDesc("io_setup", unimplementedFunc),
|
||||||
/* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
|
/* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
|
||||||
/* 270 */ SyscallDesc("io_submit", unimplementedFunc), //32 bit
|
/* 270 */ SyscallDesc("io_submit", unimplementedFunc), // 32 bit
|
||||||
/* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
|
/* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
|
||||||
/* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
|
/* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
|
||||||
/* 273 */ SyscallDesc("mq_open", unimplementedFunc), //32 bit
|
/* 273 */ SyscallDesc("mq_open", unimplementedFunc), // 32 bit
|
||||||
/* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
|
/* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
|
||||||
/* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
|
/* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
|
||||||
/* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
|
/* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
using ::MicrocodeRom;
|
using ::MicrocodeRom;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __ARCH_SPARC_MICROCODE_ROM_HH__
|
#endif // __ARCH_SPARC_MICROCODE_ROM_HH__
|
||||||
|
|
|
@ -36,124 +36,128 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
enum MiscRegIndex
|
enum MiscRegIndex
|
||||||
{
|
{
|
||||||
/** Ancillary State Registers */
|
/** Ancillary State Registers */
|
||||||
// MISCREG_Y,
|
// MISCREG_Y,
|
||||||
// MISCREG_CCR,
|
// MISCREG_CCR,
|
||||||
MISCREG_ASI,
|
MISCREG_ASI,
|
||||||
MISCREG_TICK,
|
MISCREG_TICK,
|
||||||
MISCREG_FPRS,
|
MISCREG_FPRS,
|
||||||
MISCREG_PCR,
|
MISCREG_PCR,
|
||||||
MISCREG_PIC,
|
MISCREG_PIC,
|
||||||
MISCREG_GSR,
|
MISCREG_GSR,
|
||||||
MISCREG_SOFTINT_SET,
|
MISCREG_SOFTINT_SET,
|
||||||
MISCREG_SOFTINT_CLR,
|
MISCREG_SOFTINT_CLR,
|
||||||
MISCREG_SOFTINT, /* 10 */
|
MISCREG_SOFTINT, /* 10 */
|
||||||
MISCREG_TICK_CMPR,
|
MISCREG_TICK_CMPR,
|
||||||
MISCREG_STICK,
|
MISCREG_STICK,
|
||||||
MISCREG_STICK_CMPR,
|
MISCREG_STICK_CMPR,
|
||||||
|
|
||||||
/** Privilged Registers */
|
/** Privilged Registers */
|
||||||
MISCREG_TPC,
|
MISCREG_TPC,
|
||||||
MISCREG_TNPC,
|
MISCREG_TNPC,
|
||||||
MISCREG_TSTATE,
|
MISCREG_TSTATE,
|
||||||
MISCREG_TT,
|
MISCREG_TT,
|
||||||
MISCREG_PRIVTICK,
|
MISCREG_PRIVTICK,
|
||||||
MISCREG_TBA,
|
MISCREG_TBA,
|
||||||
MISCREG_PSTATE, /* 20 */
|
MISCREG_PSTATE, /* 20 */
|
||||||
MISCREG_TL,
|
MISCREG_TL,
|
||||||
MISCREG_PIL,
|
MISCREG_PIL,
|
||||||
MISCREG_CWP,
|
MISCREG_CWP,
|
||||||
// MISCREG_CANSAVE,
|
// MISCREG_CANSAVE,
|
||||||
// MISCREG_CANRESTORE,
|
// MISCREG_CANRESTORE,
|
||||||
// MISCREG_CLEANWIN,
|
// MISCREG_CLEANWIN,
|
||||||
// MISCREG_OTHERWIN,
|
// MISCREG_OTHERWIN,
|
||||||
// MISCREG_WSTATE,
|
// MISCREG_WSTATE,
|
||||||
MISCREG_GL,
|
MISCREG_GL,
|
||||||
|
|
||||||
/** Hyper privileged registers */
|
/** Hyper privileged registers */
|
||||||
MISCREG_HPSTATE, /* 30 */
|
MISCREG_HPSTATE, /* 30 */
|
||||||
MISCREG_HTSTATE,
|
MISCREG_HTSTATE,
|
||||||
MISCREG_HINTP,
|
MISCREG_HINTP,
|
||||||
MISCREG_HTBA,
|
MISCREG_HTBA,
|
||||||
MISCREG_HVER,
|
MISCREG_HVER,
|
||||||
MISCREG_STRAND_STS_REG,
|
MISCREG_STRAND_STS_REG,
|
||||||
MISCREG_HSTICK_CMPR,
|
MISCREG_HSTICK_CMPR,
|
||||||
|
|
||||||
/** Floating Point Status Register */
|
/** Floating Point Status Register */
|
||||||
MISCREG_FSR,
|
MISCREG_FSR,
|
||||||
|
|
||||||
/** MMU Internal Registers */
|
/** MMU Internal Registers */
|
||||||
MISCREG_MMU_P_CONTEXT,
|
MISCREG_MMU_P_CONTEXT,
|
||||||
MISCREG_MMU_S_CONTEXT, /* 40 */
|
MISCREG_MMU_S_CONTEXT, /* 40 */
|
||||||
MISCREG_MMU_PART_ID,
|
MISCREG_MMU_PART_ID,
|
||||||
MISCREG_MMU_LSU_CTRL,
|
MISCREG_MMU_LSU_CTRL,
|
||||||
|
|
||||||
/** Scratchpad regiscers **/
|
/** Scratchpad regiscers **/
|
||||||
MISCREG_SCRATCHPAD_R0, /* 60 */
|
MISCREG_SCRATCHPAD_R0, /* 60 */
|
||||||
MISCREG_SCRATCHPAD_R1,
|
MISCREG_SCRATCHPAD_R1,
|
||||||
MISCREG_SCRATCHPAD_R2,
|
MISCREG_SCRATCHPAD_R2,
|
||||||
MISCREG_SCRATCHPAD_R3,
|
MISCREG_SCRATCHPAD_R3,
|
||||||
MISCREG_SCRATCHPAD_R4,
|
MISCREG_SCRATCHPAD_R4,
|
||||||
MISCREG_SCRATCHPAD_R5,
|
MISCREG_SCRATCHPAD_R5,
|
||||||
MISCREG_SCRATCHPAD_R6,
|
MISCREG_SCRATCHPAD_R6,
|
||||||
MISCREG_SCRATCHPAD_R7,
|
MISCREG_SCRATCHPAD_R7,
|
||||||
|
|
||||||
/* CPU Queue Registers */
|
/* CPU Queue Registers */
|
||||||
MISCREG_QUEUE_CPU_MONDO_HEAD,
|
MISCREG_QUEUE_CPU_MONDO_HEAD,
|
||||||
MISCREG_QUEUE_CPU_MONDO_TAIL,
|
MISCREG_QUEUE_CPU_MONDO_TAIL,
|
||||||
MISCREG_QUEUE_DEV_MONDO_HEAD, /* 70 */
|
MISCREG_QUEUE_DEV_MONDO_HEAD, /* 70 */
|
||||||
MISCREG_QUEUE_DEV_MONDO_TAIL,
|
MISCREG_QUEUE_DEV_MONDO_TAIL,
|
||||||
MISCREG_QUEUE_RES_ERROR_HEAD,
|
MISCREG_QUEUE_RES_ERROR_HEAD,
|
||||||
MISCREG_QUEUE_RES_ERROR_TAIL,
|
MISCREG_QUEUE_RES_ERROR_TAIL,
|
||||||
MISCREG_QUEUE_NRES_ERROR_HEAD,
|
MISCREG_QUEUE_NRES_ERROR_HEAD,
|
||||||
MISCREG_QUEUE_NRES_ERROR_TAIL,
|
MISCREG_QUEUE_NRES_ERROR_TAIL,
|
||||||
|
|
||||||
/* All the data for the TLB packed up in one register. */
|
/* All the data for the TLB packed up in one register. */
|
||||||
MISCREG_TLB_DATA,
|
MISCREG_TLB_DATA,
|
||||||
MISCREG_NUMMISCREGS
|
MISCREG_NUMMISCREGS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HPSTATE {
|
struct HPSTATE
|
||||||
const static uint64_t id = 0x800; // this impl. dependent (id) field m
|
{
|
||||||
const static uint64_t ibe = 0x400;
|
const static uint64_t id = 0x800; // this impl. dependent (id) field m
|
||||||
const static uint64_t red = 0x20;
|
const static uint64_t ibe = 0x400;
|
||||||
const static uint64_t hpriv = 0x4;
|
const static uint64_t red = 0x20;
|
||||||
const static uint64_t tlz = 0x1;
|
const static uint64_t hpriv = 0x4;
|
||||||
};
|
const static uint64_t tlz = 0x1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PSTATE {
|
struct PSTATE
|
||||||
const static int cle = 0x200;
|
{
|
||||||
const static int tle = 0x100;
|
const static int cle = 0x200;
|
||||||
const static int mm = 0xC0;
|
const static int tle = 0x100;
|
||||||
const static int pef = 0x10;
|
const static int mm = 0xC0;
|
||||||
const static int am = 0x8;
|
const static int pef = 0x10;
|
||||||
const static int priv = 0x4;
|
const static int am = 0x8;
|
||||||
const static int ie = 0x2;
|
const static int priv = 0x4;
|
||||||
};
|
const static int ie = 0x2;
|
||||||
|
};
|
||||||
|
|
||||||
struct STS {
|
struct STS
|
||||||
const static int st_idle = 0x00;
|
{
|
||||||
const static int st_wait = 0x01;
|
const static int st_idle = 0x00;
|
||||||
const static int st_halt = 0x02;
|
const static int st_wait = 0x01;
|
||||||
const static int st_run = 0x05;
|
const static int st_halt = 0x02;
|
||||||
const static int st_spec_run = 0x07;
|
const static int st_run = 0x05;
|
||||||
const static int st_spec_rdy = 0x13;
|
const static int st_spec_run = 0x07;
|
||||||
const static int st_ready = 0x19;
|
const static int st_spec_rdy = 0x13;
|
||||||
const static int active = 0x01;
|
const static int st_ready = 0x19;
|
||||||
const static int speculative = 0x04;
|
const static int active = 0x01;
|
||||||
const static int shft_id = 8;
|
const static int speculative = 0x04;
|
||||||
const static int shft_fsm0 = 31;
|
const static int shft_id = 8;
|
||||||
const static int shft_fsm1 = 26;
|
const static int shft_fsm0 = 31;
|
||||||
const static int shft_fsm2 = 21;
|
const static int shft_fsm1 = 26;
|
||||||
const static int shft_fsm3 = 16;
|
const static int shft_fsm2 = 21;
|
||||||
};
|
const static int shft_fsm3 = 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
||||||
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
|
|
||||||
inline Tick
|
inline Tick
|
||||||
handleIprRead(ThreadContext *xc, Packet *pkt)
|
handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +56,6 @@ handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Tick
|
inline Tick
|
||||||
handleIprWrite(ThreadContext *xc, Packet *pkt)
|
handleIprWrite(ThreadContext *xc, Packet *pkt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,13 +38,13 @@
|
||||||
namespace Trace {
|
namespace Trace {
|
||||||
|
|
||||||
static const char *intRegNames[SparcISA::NumIntArchRegs] = {
|
static const char *intRegNames[SparcISA::NumIntArchRegs] = {
|
||||||
//Global registers
|
// Global registers
|
||||||
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
||||||
//Output registers
|
// Output registers
|
||||||
"o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
|
"o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
|
||||||
//Local registers
|
// Local registers
|
||||||
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
||||||
//Input registers
|
// Input registers
|
||||||
"i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
|
"i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
|
|
||||||
void
|
void
|
||||||
TlbEntry::serialize(std::ostream &os)
|
TlbEntry::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
|
@ -67,8 +68,8 @@ TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PageTableEntry::pageSizes[] = {8*1024, 64*1024, 0, 4*1024*1024, 0,
|
int PageTableEntry::pageSizes[] =
|
||||||
256*1024*1024L};
|
{ 8 * 1024, 64 * 1024, 0, 4 * 1024 * 1024, 0, 256 * 1024 * 1024L} ;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,8 @@ class TteTag
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid() const {assert(populated); return !bits(entry,62,62); }
|
bool valid() const { assert(populated); return !bits(entry,62,62); }
|
||||||
Addr va() const {assert(populated); return bits(entry,41,0); }
|
Addr va() const { assert(populated); return bits(entry,41,0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,8 +86,7 @@ class PageTableEntry
|
||||||
bool populated;
|
bool populated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageTableEntry()
|
PageTableEntry() : entry(0), type(invalid), populated(false)
|
||||||
: entry(0), type(invalid), populated(false)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PageTableEntry(uint64_t e, EntryType t = sun4u)
|
PageTableEntry(uint64_t e, EntryType t = sun4u)
|
||||||
|
@ -96,7 +95,8 @@ class PageTableEntry
|
||||||
populate(entry, type);
|
populate(entry, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void populate(uint64_t e, EntryType t = sun4u)
|
void
|
||||||
|
populate(uint64_t e, EntryType t = sun4u)
|
||||||
{
|
{
|
||||||
entry = e;
|
entry = e;
|
||||||
type = t;
|
type = t;
|
||||||
|
@ -107,18 +107,18 @@ class PageTableEntry
|
||||||
entry4u = entry;
|
entry4u = entry;
|
||||||
else {
|
else {
|
||||||
entry4u = 0;
|
entry4u = 0;
|
||||||
entry4u |= mbits(entry,63,63); //valid
|
entry4u |= mbits(entry,63,63); // valid
|
||||||
entry4u |= bits(entry,1,0) << 61; //size[1:0]
|
entry4u |= bits(entry,1,0) << 61; // size[1:0]
|
||||||
entry4u |= bits(entry,62,62) << 60; //nfo
|
entry4u |= bits(entry,62,62) << 60; // nfo
|
||||||
entry4u |= bits(entry,12,12) << 59; //ie
|
entry4u |= bits(entry,12,12) << 59; // ie
|
||||||
entry4u |= bits(entry,2,2) << 48; //size[2]
|
entry4u |= bits(entry,2,2) << 48; // size[2]
|
||||||
entry4u |= mbits(entry,39,13); //paddr
|
entry4u |= mbits(entry,39,13); // paddr
|
||||||
entry4u |= bits(entry,61,61) << 6;; // locked
|
entry4u |= bits(entry,61,61) << 6;; // locked
|
||||||
entry4u |= bits(entry,10,10) << 5; //cp
|
entry4u |= bits(entry,10,10) << 5; // cp
|
||||||
entry4u |= bits(entry,9,9) << 4; //cv
|
entry4u |= bits(entry,9,9) << 4; // cv
|
||||||
entry4u |= bits(entry,11,11) << 3; //e
|
entry4u |= bits(entry,11,11) << 3; // e
|
||||||
entry4u |= bits(entry,8,8) << 2; //p
|
entry4u |= bits(entry,8,8) << 2; // p
|
||||||
entry4u |= bits(entry,6,6) << 1; //w
|
entry4u |= bits(entry,6,6) << 1; // w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +131,7 @@ class PageTableEntry
|
||||||
static int pageSizes[6];
|
static int pageSizes[6];
|
||||||
|
|
||||||
uint64_t operator()() const { assert(populated); return entry4u; }
|
uint64_t operator()() const { assert(populated); return entry4u; }
|
||||||
|
|
||||||
const PageTableEntry &
|
const PageTableEntry &
|
||||||
operator=(uint64_t e)
|
operator=(uint64_t e)
|
||||||
{
|
{
|
||||||
|
@ -261,7 +262,8 @@ struct TlbEntry
|
||||||
bool used;
|
bool used;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
Addr pageStart()
|
Addr
|
||||||
|
pageStart()
|
||||||
{
|
{
|
||||||
return pte.paddr();
|
return pte.paddr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,68 +42,72 @@ class ThreadContext;
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
class Predecoder
|
|
||||||
|
class Predecoder
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
ThreadContext * tc;
|
||||||
|
// The extended machine instruction being generated
|
||||||
|
ExtMachInst emi;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Predecoder(ThreadContext * _tc) : tc(_tc)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ThreadContext *
|
||||||
|
getTC()
|
||||||
{
|
{
|
||||||
protected:
|
return tc;
|
||||||
ThreadContext * tc;
|
}
|
||||||
//The extended machine instruction being generated
|
|
||||||
ExtMachInst emi;
|
|
||||||
|
|
||||||
public:
|
void
|
||||||
Predecoder(ThreadContext * _tc) : tc(_tc)
|
setTC(ThreadContext * _tc)
|
||||||
{}
|
{
|
||||||
|
tc = _tc;
|
||||||
|
}
|
||||||
|
|
||||||
ThreadContext * getTC()
|
void process() {}
|
||||||
{
|
void reset() {}
|
||||||
return tc;
|
|
||||||
|
// Use this to give data to the predecoder. This should be used
|
||||||
|
// when there is control flow.
|
||||||
|
void
|
||||||
|
moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
|
||||||
|
{
|
||||||
|
emi = inst;
|
||||||
|
// The I bit, bit 13, is used to figure out where the ASI
|
||||||
|
// should come from. Use that in the ExtMachInst. This is
|
||||||
|
// slightly redundant, but it removes the need to put a condition
|
||||||
|
// into all the execute functions
|
||||||
|
if (inst & (1 << 13)) {
|
||||||
|
emi |= (static_cast<ExtMachInst>(
|
||||||
|
tc->readMiscRegNoEffect(MISCREG_ASI))
|
||||||
|
<< (sizeof(MachInst) * 8));
|
||||||
|
} else {
|
||||||
|
emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
|
||||||
|
<< (sizeof(MachInst) * 8));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setTC(ThreadContext * _tc)
|
bool
|
||||||
{
|
needMoreBytes()
|
||||||
tc = _tc;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void process()
|
bool
|
||||||
{
|
extMachInstReady()
|
||||||
}
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void reset()
|
// This returns a constant reference to the ExtMachInst to avoid a copy
|
||||||
{}
|
const ExtMachInst &
|
||||||
|
getExtMachInst(PCState &pcState)
|
||||||
//Use this to give data to the predecoder. This should be used
|
{
|
||||||
//when there is control flow.
|
return emi;
|
||||||
void moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
|
}
|
||||||
{
|
};
|
||||||
emi = inst;
|
|
||||||
//The I bit, bit 13, is used to figure out where the ASI
|
|
||||||
//should come from. Use that in the ExtMachInst. This is
|
|
||||||
//slightly redundant, but it removes the need to put a condition
|
|
||||||
//into all the execute functions
|
|
||||||
if(inst & (1 << 13))
|
|
||||||
emi |= (static_cast<ExtMachInst>(
|
|
||||||
tc->readMiscRegNoEffect(MISCREG_ASI))
|
|
||||||
<< (sizeof(MachInst) * 8));
|
|
||||||
else
|
|
||||||
emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
|
|
||||||
<< (sizeof(MachInst) * 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needMoreBytes()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool extMachInstReady()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This returns a constant reference to the ExtMachInst to avoid a copy
|
|
||||||
const ExtMachInst & getExtMachInst(PCState &pcState)
|
|
||||||
{
|
|
||||||
return emi;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_SPARC_PREDECODER_HH__
|
#endif // __ARCH_SPARC_PREDECODER_HH__
|
||||||
|
|
|
@ -62,44 +62,44 @@ SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,
|
||||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||||
|
|
||||||
//Initialize these to 0s
|
// Initialize these to 0s
|
||||||
fillStart = 0;
|
fillStart = 0;
|
||||||
spillStart = 0;
|
spillStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
|
void
|
||||||
|
SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
PCState pc = tc->pcState();
|
PCState pc = tc->pcState();
|
||||||
switch(trapNum)
|
switch (trapNum) {
|
||||||
{
|
case 0x01: // Software breakpoint
|
||||||
case 0x01: //Software breakpoint
|
|
||||||
warn("Software breakpoint encountered at pc %#x.\n", pc.pc());
|
warn("Software breakpoint encountered at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x02: //Division by zero
|
case 0x02: // Division by zero
|
||||||
warn("Software signaled a division by zero at pc %#x.\n", pc.pc());
|
warn("Software signaled a division by zero at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x03: //Flush window trap
|
case 0x03: // Flush window trap
|
||||||
flushWindows(tc);
|
flushWindows(tc);
|
||||||
break;
|
break;
|
||||||
case 0x04: //Clean windows
|
case 0x04: // Clean windows
|
||||||
warn("Ignoring process request for clean register "
|
warn("Ignoring process request for clean register "
|
||||||
"windows at pc %#x.\n", pc.pc());
|
"windows at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x05: //Range check
|
case 0x05: // Range check
|
||||||
warn("Software signaled a range check at pc %#x.\n", pc.pc());
|
warn("Software signaled a range check at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x06: //Fix alignment
|
case 0x06: // Fix alignment
|
||||||
warn("Ignoring process request for os assisted unaligned accesses "
|
warn("Ignoring process request for os assisted unaligned accesses "
|
||||||
"at pc %#x.\n", pc.pc());
|
"at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x07: //Integer overflow
|
case 0x07: // Integer overflow
|
||||||
warn("Software signaled an integer overflow at pc %#x.\n", pc.pc());
|
warn("Software signaled an integer overflow at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x32: //Get integer condition codes
|
case 0x32: // Get integer condition codes
|
||||||
warn("Ignoring process request to get the integer condition codes "
|
warn("Ignoring process request to get the integer condition codes "
|
||||||
"at pc %#x.\n", pc.pc());
|
"at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
case 0x33: //Set integer condition codes
|
case 0x33: // Set integer condition codes
|
||||||
warn("Ignoring process request to set the integer condition codes "
|
warn("Ignoring process request to set the integer condition codes "
|
||||||
"at pc %#x.\n", pc.pc());
|
"at pc %#x.\n", pc.pc());
|
||||||
break;
|
break;
|
||||||
|
@ -114,9 +114,9 @@ SparcLiveProcess::initState()
|
||||||
LiveProcess::initState();
|
LiveProcess::initState();
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//From the SPARC ABI
|
// From the SPARC ABI
|
||||||
|
|
||||||
//Setup default FP state
|
// Setup default FP state
|
||||||
tc->setMiscRegNoEffect(MISCREG_FSR, 0);
|
tc->setMiscRegNoEffect(MISCREG_FSR, 0);
|
||||||
|
|
||||||
tc->setMiscRegNoEffect(MISCREG_TICK, 0);
|
tc->setMiscRegNoEffect(MISCREG_TICK, 0);
|
||||||
|
@ -125,32 +125,32 @@ SparcLiveProcess::initState()
|
||||||
* Register window management registers
|
* Register window management registers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//No windows contain info from other programs
|
// No windows contain info from other programs
|
||||||
//tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
|
// tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
|
||||||
tc->setIntReg(NumIntArchRegs + 6, 0);
|
tc->setIntReg(NumIntArchRegs + 6, 0);
|
||||||
//There are no windows to pop
|
// There are no windows to pop
|
||||||
//tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
|
// tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
|
||||||
tc->setIntReg(NumIntArchRegs + 4, 0);
|
tc->setIntReg(NumIntArchRegs + 4, 0);
|
||||||
//All windows are available to save into
|
// All windows are available to save into
|
||||||
//tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
|
// tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
|
||||||
tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
|
tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
|
||||||
//All windows are "clean"
|
// All windows are "clean"
|
||||||
//tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
|
// tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
|
||||||
tc->setIntReg(NumIntArchRegs + 5, NWindows);
|
tc->setIntReg(NumIntArchRegs + 5, NWindows);
|
||||||
//Start with register window 0
|
// Start with register window 0
|
||||||
tc->setMiscReg(MISCREG_CWP, 0);
|
tc->setMiscReg(MISCREG_CWP, 0);
|
||||||
//Always use spill and fill traps 0
|
// Always use spill and fill traps 0
|
||||||
//tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
|
// tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
|
||||||
tc->setIntReg(NumIntArchRegs + 7, 0);
|
tc->setIntReg(NumIntArchRegs + 7, 0);
|
||||||
//Set the trap level to 0
|
// Set the trap level to 0
|
||||||
tc->setMiscRegNoEffect(MISCREG_TL, 0);
|
tc->setMiscRegNoEffect(MISCREG_TL, 0);
|
||||||
//Set the ASI register to something fixed
|
// Set the ASI register to something fixed
|
||||||
tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
|
tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* T1 specific registers
|
* T1 specific registers
|
||||||
*/
|
*/
|
||||||
//Turn on the icache, dcache, dtb translation, and itb translation.
|
// Turn on the icache, dcache, dtb translation, and itb translation.
|
||||||
tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
|
tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ Sparc32LiveProcess::initState()
|
||||||
SparcLiveProcess::initState();
|
SparcLiveProcess::initState();
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//The process runs in user mode with 32 bit addresses
|
// The process runs in user mode with 32 bit addresses
|
||||||
tc->setMiscReg(MISCREG_PSTATE, 0x0a);
|
tc->setMiscReg(MISCREG_PSTATE, 0x0a);
|
||||||
|
|
||||||
argsInit(32 / 8, VMPageSize);
|
argsInit(32 / 8, VMPageSize);
|
||||||
|
@ -172,7 +172,7 @@ Sparc64LiveProcess::initState()
|
||||||
SparcLiveProcess::initState();
|
SparcLiveProcess::initState();
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//The process runs in user mode
|
// The process runs in user mode
|
||||||
tc->setMiscReg(MISCREG_PSTATE, 0x02);
|
tc->setMiscReg(MISCREG_PSTATE, 0x02);
|
||||||
|
|
||||||
argsInit(sizeof(IntReg), VMPageSize);
|
argsInit(sizeof(IntReg), VMPageSize);
|
||||||
|
@ -189,13 +189,13 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
std::vector<auxv_t> auxv;
|
std::vector<auxv_t> auxv;
|
||||||
|
|
||||||
string filename;
|
string filename;
|
||||||
if(argv.size() < 1)
|
if (argv.size() < 1)
|
||||||
filename = "";
|
filename = "";
|
||||||
else
|
else
|
||||||
filename = argv[0];
|
filename = argv[0];
|
||||||
|
|
||||||
//Even for a 32 bit process, the ABI says we still need to
|
// Even for a 32 bit process, the ABI says we still need to
|
||||||
//maintain double word alignment of the stack pointer.
|
// maintain double word alignment of the stack pointer.
|
||||||
uint64_t align = 16;
|
uint64_t align = 16;
|
||||||
|
|
||||||
// load object file into target memory
|
// load object file into target memory
|
||||||
|
@ -208,9 +208,9 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
M5_HWCAP_SPARC_SWAP = 4,
|
M5_HWCAP_SPARC_SWAP = 4,
|
||||||
M5_HWCAP_SPARC_MULDIV = 8,
|
M5_HWCAP_SPARC_MULDIV = 8,
|
||||||
M5_HWCAP_SPARC_V9 = 16,
|
M5_HWCAP_SPARC_V9 = 16,
|
||||||
//This one should technically only be set
|
// This one should technically only be set
|
||||||
//if there is a cheetah or cheetah_plus tlb,
|
// if there is a cheetah or cheetah_plus tlb,
|
||||||
//but we'll use it all the time
|
// but we'll use it all the time
|
||||||
M5_HWCAP_SPARC_ULTRA3 = 32
|
M5_HWCAP_SPARC_ULTRA3 = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -222,17 +222,16 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
M5_HWCAP_SPARC_V9 |
|
M5_HWCAP_SPARC_V9 |
|
||||||
M5_HWCAP_SPARC_ULTRA3;
|
M5_HWCAP_SPARC_ULTRA3;
|
||||||
|
|
||||||
//Setup the auxilliary vectors. These will already have endian conversion.
|
// Setup the auxilliary vectors. These will already have endian conversion.
|
||||||
//Auxilliary vectors are loaded only for elf formatted executables.
|
// Auxilliary vectors are loaded only for elf formatted executables.
|
||||||
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
|
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
|
||||||
if(elfObject)
|
if (elfObject) {
|
||||||
{
|
// Bits which describe the system hardware capabilities
|
||||||
//Bits which describe the system hardware capabilities
|
|
||||||
auxv.push_back(auxv_t(M5_AT_HWCAP, hwcap));
|
auxv.push_back(auxv_t(M5_AT_HWCAP, hwcap));
|
||||||
//The system page size
|
// The system page size
|
||||||
auxv.push_back(auxv_t(M5_AT_PAGESZ, SparcISA::VMPageSize));
|
auxv.push_back(auxv_t(M5_AT_PAGESZ, SparcISA::VMPageSize));
|
||||||
//Defined to be 100 in the kernel source.
|
// Defined to be 100 in the kernel source.
|
||||||
//Frequency at which times() increments
|
// Frequency at which times() increments
|
||||||
auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
|
auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
|
||||||
// For statically linked executables, this is the virtual address of the
|
// For statically linked executables, this is the virtual address of the
|
||||||
// program header tables if they appear in the executable image
|
// program header tables if they appear in the executable image
|
||||||
|
@ -241,30 +240,30 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
|
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
|
||||||
// This is the number of program headers from the original elf file.
|
// This is the number of program headers from the original elf file.
|
||||||
auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
|
auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
|
||||||
//This is the address of the elf "interpreter", It should be set
|
// This is the address of the elf "interpreter", It should be set
|
||||||
//to 0 for regular executables. It should be something else
|
// to 0 for regular executables. It should be something else
|
||||||
//(not sure what) for dynamic libraries.
|
// (not sure what) for dynamic libraries.
|
||||||
auxv.push_back(auxv_t(M5_AT_BASE, 0));
|
auxv.push_back(auxv_t(M5_AT_BASE, 0));
|
||||||
//This is hardwired to 0 in the elf loading code in the kernel
|
// This is hardwired to 0 in the elf loading code in the kernel
|
||||||
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
|
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
|
||||||
//The entry point to the program
|
// The entry point to the program
|
||||||
auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
|
auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
|
||||||
//Different user and group IDs
|
// Different user and group IDs
|
||||||
auxv.push_back(auxv_t(M5_AT_UID, uid()));
|
auxv.push_back(auxv_t(M5_AT_UID, uid()));
|
||||||
auxv.push_back(auxv_t(M5_AT_EUID, euid()));
|
auxv.push_back(auxv_t(M5_AT_EUID, euid()));
|
||||||
auxv.push_back(auxv_t(M5_AT_GID, gid()));
|
auxv.push_back(auxv_t(M5_AT_GID, gid()));
|
||||||
auxv.push_back(auxv_t(M5_AT_EGID, egid()));
|
auxv.push_back(auxv_t(M5_AT_EGID, egid()));
|
||||||
//Whether to enable "secure mode" in the executable
|
// Whether to enable "secure mode" in the executable
|
||||||
auxv.push_back(auxv_t(M5_AT_SECURE, 0));
|
auxv.push_back(auxv_t(M5_AT_SECURE, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Figure out how big the initial stack needs to be
|
// Figure out how big the initial stack needs to be
|
||||||
|
|
||||||
// The unaccounted for 8 byte 0 at the top of the stack
|
// The unaccounted for 8 byte 0 at the top of the stack
|
||||||
int sentry_size = 8;
|
int sentry_size = 8;
|
||||||
|
|
||||||
//This is the name of the file which is present on the initial stack
|
// This is the name of the file which is present on the initial stack
|
||||||
//It's purpose is to let the user space linker examine the original file.
|
// It's purpose is to let the user space linker examine the original file.
|
||||||
int file_name_size = filename.size() + 1;
|
int file_name_size = filename.size() + 1;
|
||||||
|
|
||||||
int env_data_size = 0;
|
int env_data_size = 0;
|
||||||
|
@ -276,7 +275,7 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
arg_data_size += argv[i].size() + 1;
|
arg_data_size += argv[i].size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//The info_block.
|
// The info_block.
|
||||||
int base_info_block_size =
|
int base_info_block_size =
|
||||||
sentry_size + file_name_size + env_data_size + arg_data_size;
|
sentry_size + file_name_size + env_data_size + arg_data_size;
|
||||||
|
|
||||||
|
@ -284,7 +283,7 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
|
|
||||||
int info_block_padding = info_block_size - base_info_block_size;
|
int info_block_padding = info_block_size - base_info_block_size;
|
||||||
|
|
||||||
//Each auxilliary vector is two words
|
// Each auxilliary vector is two words
|
||||||
int aux_array_size = intSize * 2 * (auxv.size() + 1);
|
int aux_array_size = intSize * 2 * (auxv.size() + 1);
|
||||||
|
|
||||||
int envp_array_size = intSize * (envp.size() + 1);
|
int envp_array_size = intSize * (envp.size() + 1);
|
||||||
|
@ -293,7 +292,7 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
int argc_size = intSize;
|
int argc_size = intSize;
|
||||||
int window_save_size = intSize * 16;
|
int window_save_size = intSize * 16;
|
||||||
|
|
||||||
//Figure out the size of the contents of the actual initial frame
|
// Figure out the size of the contents of the actual initial frame
|
||||||
int frame_size =
|
int frame_size =
|
||||||
aux_array_size +
|
aux_array_size +
|
||||||
envp_array_size +
|
envp_array_size +
|
||||||
|
@ -301,8 +300,8 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
argc_size +
|
argc_size +
|
||||||
window_save_size;
|
window_save_size;
|
||||||
|
|
||||||
//There needs to be padding after the auxiliary vector data so that the
|
// There needs to be padding after the auxiliary vector data so that the
|
||||||
//very bottom of the stack is aligned properly.
|
// very bottom of the stack is aligned properly.
|
||||||
int aligned_partial_size = roundUp(frame_size, align);
|
int aligned_partial_size = roundUp(frame_size, align);
|
||||||
int aux_padding = aligned_partial_size - frame_size;
|
int aux_padding = aligned_partial_size - frame_size;
|
||||||
|
|
||||||
|
@ -354,24 +353,23 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
IntType argc = argv.size();
|
IntType argc = argv.size();
|
||||||
IntType guestArgc = SparcISA::htog(argc);
|
IntType guestArgc = SparcISA::htog(argc);
|
||||||
|
|
||||||
//Write out the sentry void *
|
// Write out the sentry void *
|
||||||
uint64_t sentry_NULL = 0;
|
uint64_t sentry_NULL = 0;
|
||||||
initVirtMem->writeBlob(sentry_base,
|
initVirtMem->writeBlob(sentry_base,
|
||||||
(uint8_t*)&sentry_NULL, sentry_size);
|
(uint8_t*)&sentry_NULL, sentry_size);
|
||||||
|
|
||||||
//Write the file name
|
// Write the file name
|
||||||
initVirtMem->writeString(file_name_base, filename.c_str());
|
initVirtMem->writeString(file_name_base, filename.c_str());
|
||||||
|
|
||||||
//Copy the aux stuff
|
// Copy the aux stuff
|
||||||
for(int x = 0; x < auxv.size(); x++)
|
for (int x = 0; x < auxv.size(); x++) {
|
||||||
{
|
|
||||||
initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
|
initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
|
||||||
(uint8_t*)&(auxv[x].a_type), intSize);
|
(uint8_t*)&(auxv[x].a_type), intSize);
|
||||||
initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
|
initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
|
||||||
(uint8_t*)&(auxv[x].a_val), intSize);
|
(uint8_t*)&(auxv[x].a_val), intSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Write out the terminating zeroed auxilliary vector
|
// Write out the terminating zeroed auxilliary vector
|
||||||
const IntType zero = 0;
|
const IntType zero = 0;
|
||||||
initVirtMem->writeBlob(auxv_array_base + intSize * 2 * auxv.size(),
|
initVirtMem->writeBlob(auxv_array_base + intSize * 2 * auxv.size(),
|
||||||
(uint8_t*)&zero, intSize);
|
(uint8_t*)&zero, intSize);
|
||||||
|
@ -383,17 +381,17 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
|
|
||||||
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
|
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
|
||||||
|
|
||||||
//Set up space for the trap handlers into the processes address space.
|
// Set up space for the trap handlers into the processes address space.
|
||||||
//Since the stack grows down and there is reserved address space abov
|
// Since the stack grows down and there is reserved address space abov
|
||||||
//it, we can put stuff above it and stay out of the way.
|
// it, we can put stuff above it and stay out of the way.
|
||||||
fillStart = stack_base;
|
fillStart = stack_base;
|
||||||
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
|
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//Set up the thread context to start running the process
|
// Set up the thread context to start running the process
|
||||||
//assert(NumArgumentRegs >= 2);
|
// assert(NumArgumentRegs >= 2);
|
||||||
//tc->setIntReg(ArgumentReg[0], argc);
|
// tc->setIntReg(ArgumentReg[0], argc);
|
||||||
//tc->setIntReg(ArgumentReg[1], argv_array_base);
|
// tc->setIntReg(ArgumentReg[1], argv_array_base);
|
||||||
tc->setIntReg(StackPointerReg, stack_min - StackBias);
|
tc->setIntReg(StackPointerReg, stack_min - StackBias);
|
||||||
|
|
||||||
// %g1 is a pointer to a function that should be run at exit. Since we
|
// %g1 is a pointer to a function that should be run at exit. Since we
|
||||||
|
@ -402,7 +400,7 @@ SparcLiveProcess::argsInit(int pageSize)
|
||||||
|
|
||||||
tc->pcState(objFile->entryPoint());
|
tc->pcState(objFile->entryPoint());
|
||||||
|
|
||||||
//Align the "stack_min" to a page boundary.
|
// Align the "stack_min" to a page boundary.
|
||||||
stack_min = roundDown(stack_min, pageSize);
|
stack_min = roundDown(stack_min, pageSize);
|
||||||
|
|
||||||
// num_processes++;
|
// num_processes++;
|
||||||
|
@ -440,13 +438,12 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
|
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
|
||||||
MiscReg origCWP = CWP;
|
MiscReg origCWP = CWP;
|
||||||
CWP = (CWP + Cansave + 2) % NWindows;
|
CWP = (CWP + Cansave + 2) % NWindows;
|
||||||
while(NWindows - 2 - Cansave != 0)
|
while (NWindows - 2 - Cansave != 0) {
|
||||||
{
|
|
||||||
if (Otherwin) {
|
if (Otherwin) {
|
||||||
panic("Otherwin non-zero.\n");
|
panic("Otherwin non-zero.\n");
|
||||||
} else {
|
} else {
|
||||||
tc->setMiscReg(MISCREG_CWP, CWP);
|
tc->setMiscReg(MISCREG_CWP, CWP);
|
||||||
//Do the stores
|
// Do the stores
|
||||||
IntReg sp = tc->readIntReg(StackPointerReg);
|
IntReg sp = tc->readIntReg(StackPointerReg);
|
||||||
for (int index = 16; index < 32; index++) {
|
for (int index = 16; index < 32; index++) {
|
||||||
uint32_t regVal = tc->readIntReg(index);
|
uint32_t regVal = tc->readIntReg(index);
|
||||||
|
@ -467,7 +464,8 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
tc->setMiscReg(MISCREG_CWP, origCWP);
|
tc->setMiscReg(MISCREG_CWP, origCWP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
|
void
|
||||||
|
Sparc64LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3);
|
IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3);
|
||||||
IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4);
|
IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4);
|
||||||
|
@ -475,13 +473,12 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
|
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
|
||||||
MiscReg origCWP = CWP;
|
MiscReg origCWP = CWP;
|
||||||
CWP = (CWP + Cansave + 2) % NWindows;
|
CWP = (CWP + Cansave + 2) % NWindows;
|
||||||
while(NWindows - 2 - Cansave != 0)
|
while (NWindows - 2 - Cansave != 0) {
|
||||||
{
|
|
||||||
if (Otherwin) {
|
if (Otherwin) {
|
||||||
panic("Otherwin non-zero.\n");
|
panic("Otherwin non-zero.\n");
|
||||||
} else {
|
} else {
|
||||||
tc->setMiscReg(MISCREG_CWP, CWP);
|
tc->setMiscReg(MISCREG_CWP, CWP);
|
||||||
//Do the stores
|
// Do the stores
|
||||||
IntReg sp = tc->readIntReg(StackPointerReg);
|
IntReg sp = tc->readIntReg(StackPointerReg);
|
||||||
for (int index = 16; index < 32; index++) {
|
for (int index = 16; index < 32; index++) {
|
||||||
IntReg regVal = tc->readIntReg(index);
|
IntReg regVal = tc->readIntReg(index);
|
||||||
|
@ -541,7 +538,7 @@ SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
|
||||||
// no error, clear XCC.C
|
// no error, clear XCC.C
|
||||||
tc->setIntReg(NumIntArchRegs + 2,
|
tc->setIntReg(NumIntArchRegs + 2,
|
||||||
tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
|
tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
|
||||||
//tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
|
// tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
|
||||||
IntReg val = return_value.value();
|
IntReg val = return_value.value();
|
||||||
if (bits(tc->readMiscRegNoEffect(
|
if (bits(tc->readMiscRegNoEffect(
|
||||||
SparcISA::MISCREG_PSTATE), 3, 3)) {
|
SparcISA::MISCREG_PSTATE), 3, 3)) {
|
||||||
|
@ -552,7 +549,7 @@ SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
|
||||||
// got an error, set XCC.C
|
// got an error, set XCC.C
|
||||||
tc->setIntReg(NumIntArchRegs + 2,
|
tc->setIntReg(NumIntArchRegs + 2,
|
||||||
tc->readIntReg(NumIntArchRegs + 2) | 0x11);
|
tc->readIntReg(NumIntArchRegs + 2) | 0x11);
|
||||||
//tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
|
// tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
|
||||||
IntReg val = -return_value.value();
|
IntReg val = -return_value.value();
|
||||||
if (bits(tc->readMiscRegNoEffect(
|
if (bits(tc->readMiscRegNoEffect(
|
||||||
SparcISA::MISCREG_PSTATE), 3, 3)) {
|
SparcISA::MISCREG_PSTATE), 3, 3)) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ class SparcLiveProcess : public LiveProcess
|
||||||
|
|
||||||
const Addr StackBias;
|
const Addr StackBias;
|
||||||
|
|
||||||
//The locations of the fill and spill handlers
|
// The locations of the fill and spill handlers
|
||||||
Addr fillStart, spillStart;
|
Addr fillStart, spillStart;
|
||||||
|
|
||||||
SparcLiveProcess(LiveProcessParams * params,
|
SparcLiveProcess(LiveProcessParams * params,
|
||||||
|
@ -59,14 +59,11 @@ class SparcLiveProcess : public LiveProcess
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//Handles traps which request services from the operating system
|
// Handles traps which request services from the operating system
|
||||||
virtual void handleTrap(int trapNum, ThreadContext *tc);
|
virtual void handleTrap(int trapNum, ThreadContext *tc);
|
||||||
|
|
||||||
Addr readFillStart()
|
Addr readFillStart() { return fillStart; }
|
||||||
{ return fillStart; }
|
Addr readSpillStart() { return spillStart; }
|
||||||
|
|
||||||
Addr readSpillStart()
|
|
||||||
{ return spillStart; }
|
|
||||||
|
|
||||||
virtual void flushWindows(ThreadContext *tc) = 0;
|
virtual void flushWindows(ThreadContext *tc) = 0;
|
||||||
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
||||||
|
|
|
@ -39,42 +39,43 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
using SparcISAInst::MaxInstSrcRegs;
|
|
||||||
using SparcISAInst::MaxInstDestRegs;
|
|
||||||
|
|
||||||
typedef uint64_t IntReg;
|
using SparcISAInst::MaxInstSrcRegs;
|
||||||
typedef uint64_t MiscReg;
|
using SparcISAInst::MaxInstDestRegs;
|
||||||
typedef float FloatReg;
|
|
||||||
typedef uint32_t FloatRegBits;
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
IntReg intReg;
|
|
||||||
FloatReg fpreg;
|
|
||||||
MiscReg ctrlreg;
|
|
||||||
} AnyReg;
|
|
||||||
|
|
||||||
typedef uint16_t RegIndex;
|
typedef uint64_t IntReg;
|
||||||
|
typedef uint64_t MiscReg;
|
||||||
|
typedef float FloatReg;
|
||||||
|
typedef uint32_t FloatRegBits;
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
IntReg intReg;
|
||||||
|
FloatReg fpreg;
|
||||||
|
MiscReg ctrlreg;
|
||||||
|
} AnyReg;
|
||||||
|
|
||||||
// These enumerate all the registers for dependence tracking.
|
typedef uint16_t RegIndex;
|
||||||
enum DependenceTags {
|
|
||||||
FP_Base_DepTag = 32*3+9,
|
|
||||||
Ctrl_Base_DepTag = FP_Base_DepTag + 64,
|
|
||||||
Max_DepTag = Ctrl_Base_DepTag + NumMiscRegs
|
|
||||||
};
|
|
||||||
|
|
||||||
// semantically meaningful register indices
|
// These enumerate all the registers for dependence tracking.
|
||||||
const int ZeroReg = 0; // architecturally meaningful
|
enum DependenceTags {
|
||||||
// the rest of these depend on the ABI
|
FP_Base_DepTag = 32*3+9,
|
||||||
const int ReturnAddressReg = 31; // post call, precall is 15
|
Ctrl_Base_DepTag = FP_Base_DepTag + 64,
|
||||||
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
|
Max_DepTag = Ctrl_Base_DepTag + NumMiscRegs
|
||||||
const int StackPointerReg = 14;
|
};
|
||||||
const int FramePointerReg = 30;
|
|
||||||
|
|
||||||
// Some OS syscall use a second register (o1) to return a second value
|
// semantically meaningful register indices
|
||||||
const int SyscallPseudoReturnReg = 9;
|
const int ZeroReg = 0; // architecturally meaningful
|
||||||
|
// the rest of these depend on the ABI
|
||||||
|
const int ReturnAddressReg = 31; // post call, precall is 15
|
||||||
|
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
|
||||||
|
const int StackPointerReg = 14;
|
||||||
|
const int FramePointerReg = 30;
|
||||||
|
|
||||||
const int NumIntArchRegs = 32;
|
// Some OS syscall use a second register (o1) to return a second value
|
||||||
const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
|
const int SyscallPseudoReturnReg = 9;
|
||||||
|
|
||||||
|
const int NumIntArchRegs = 32;
|
||||||
|
const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
|
||||||
|
|
||||||
} // namespace SparcISA
|
} // namespace SparcISA
|
||||||
|
|
||||||
|
|
|
@ -153,16 +153,16 @@ bool
|
||||||
RemoteGDB::acc(Addr va, size_t len)
|
RemoteGDB::acc(Addr va, size_t len)
|
||||||
{
|
{
|
||||||
//@Todo In NetBSD, this function checks if all addresses
|
//@Todo In NetBSD, this function checks if all addresses
|
||||||
//from va to va + len have valid page map entries. Not
|
// from va to va + len have valid page map entries. Not
|
||||||
//sure how this will work for other OSes or in general.
|
// sure how this will work for other OSes or in general.
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
if (va)
|
if (va)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
TlbEntry entry;
|
TlbEntry entry;
|
||||||
//Check to make sure the first byte is mapped into the processes address
|
// Check to make sure the first byte is mapped into the processes address
|
||||||
//space.
|
// space.
|
||||||
if (context->getProcessPtr()->pTable->lookup(va, entry))
|
if (context->getProcessPtr()->pTable->lookup(va, entry))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -187,7 +187,7 @@ RemoteGDB::getregs()
|
||||||
regs = (uint32_t*)gdbregs.regs;
|
regs = (uint32_t*)gdbregs.regs;
|
||||||
regs[Reg32Pc] = htobe((uint32_t)pc.pc());
|
regs[Reg32Pc] = htobe((uint32_t)pc.pc());
|
||||||
regs[Reg32Npc] = htobe((uint32_t)pc.npc());
|
regs[Reg32Npc] = htobe((uint32_t)pc.npc());
|
||||||
for(int x = RegG0; x <= RegI0 + 7; x++)
|
for (int x = RegG0; x <= RegI0 + 7; x++)
|
||||||
regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
|
regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
|
||||||
|
|
||||||
regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
|
regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
|
||||||
|
@ -197,7 +197,7 @@ RemoteGDB::getregs()
|
||||||
} else {
|
} else {
|
||||||
gdbregs.regs[RegPc] = htobe(pc.pc());
|
gdbregs.regs[RegPc] = htobe(pc.pc());
|
||||||
gdbregs.regs[RegNpc] = htobe(pc.npc());
|
gdbregs.regs[RegNpc] = htobe(pc.npc());
|
||||||
for(int x = RegG0; x <= RegI0 + 7; x++)
|
for (int x = RegG0; x <= RegI0 + 7; x++)
|
||||||
gdbregs.regs[x] = htobe(context->readIntReg(x - RegG0));
|
gdbregs.regs[x] = htobe(context->readIntReg(x - RegG0));
|
||||||
|
|
||||||
gdbregs.regs[RegFsr] = htobe(context->readMiscReg(MISCREG_FSR));
|
gdbregs.regs[RegFsr] = htobe(context->readMiscReg(MISCREG_FSR));
|
||||||
|
@ -212,9 +212,9 @@ RemoteGDB::getregs()
|
||||||
|
|
||||||
DPRINTF(GDBRead, "PC=%#x\n", gdbregs.regs[RegPc]);
|
DPRINTF(GDBRead, "PC=%#x\n", gdbregs.regs[RegPc]);
|
||||||
|
|
||||||
//Floating point registers are left at 0 in netbsd
|
// Floating point registers are left at 0 in netbsd
|
||||||
//All registers other than the pc, npc and int regs
|
// All registers other than the pc, npc and int regs
|
||||||
//are ignored as well.
|
// are ignored as well.
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
@ -233,9 +233,9 @@ RemoteGDB::setregs()
|
||||||
pc.upc(0);
|
pc.upc(0);
|
||||||
pc.nupc(1);
|
pc.nupc(1);
|
||||||
context->pcState(pc);
|
context->pcState(pc);
|
||||||
for(int x = RegG0; x <= RegI0 + 7; x++)
|
for (int x = RegG0; x <= RegI0 + 7; x++)
|
||||||
context->setIntReg(x - RegG0, gdbregs.regs[x]);
|
context->setIntReg(x - RegG0, gdbregs.regs[x]);
|
||||||
//Only the integer registers, pc and npc are set in netbsd
|
// Only the integer registers, pc and npc are set in netbsd
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -44,34 +44,36 @@ class PhysicalMemory;
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
class RemoteGDB : public BaseRemoteGDB
|
|
||||||
|
class RemoteGDB : public BaseRemoteGDB
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
enum RegisterConstants
|
||||||
{
|
{
|
||||||
protected:
|
RegG0 = 0, RegO0 = 8, RegL0 = 16, RegI0 = 24,
|
||||||
enum RegisterConstants
|
RegF0 = 32,
|
||||||
{
|
RegPc = 64, RegNpc, RegState, RegFsr, RegFprs, RegY,
|
||||||
RegG0 = 0, RegO0 = 8, RegL0 = 16, RegI0 = 24,
|
/*RegState contains data in same format as tstate */
|
||||||
RegF0 = 32,
|
Reg32Y = 64, Reg32Psr = 65, Reg32Tbr = 66, Reg32Pc = 67,
|
||||||
RegPc = 64, RegNpc, RegState, RegFsr, RegFprs, RegY,
|
Reg32Npc = 68, Reg32Fsr = 69, Reg32Csr = 70,
|
||||||
/*RegState contains data in same format as tstate */
|
NumGDBRegs
|
||||||
Reg32Y = 64, Reg32Psr = 65, Reg32Tbr = 66, Reg32Pc = 67,
|
|
||||||
Reg32Npc = 68, Reg32Fsr = 69, Reg32Csr = 70,
|
|
||||||
NumGDBRegs
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
RemoteGDB(System *system, ThreadContext *context);
|
|
||||||
|
|
||||||
bool acc(Addr addr, size_t len);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void getregs();
|
|
||||||
void setregs();
|
|
||||||
|
|
||||||
void clearSingleStep();
|
|
||||||
void setSingleStep();
|
|
||||||
|
|
||||||
Addr nextBkpt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
RemoteGDB(System *system, ThreadContext *context);
|
||||||
|
|
||||||
|
bool acc(Addr addr, size_t len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void getregs();
|
||||||
|
void setregs();
|
||||||
|
|
||||||
|
void clearSingleStep();
|
||||||
|
void setSingleStep();
|
||||||
|
|
||||||
|
Addr nextBkpt;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __ARCH_SPARC_REMOTE_GDB_H__ */
|
#endif /* __ARCH_SPARC_REMOTE_GDB_H__ */
|
||||||
|
|
|
@ -33,25 +33,23 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
// Max trap levels
|
// Max trap levels
|
||||||
const int MaxPTL = 2;
|
const int MaxPTL = 2;
|
||||||
const int MaxTL = 6;
|
const int MaxTL = 6;
|
||||||
const int MaxGL = 3;
|
const int MaxGL = 3;
|
||||||
const int MaxPGL = 2;
|
const int MaxPGL = 2;
|
||||||
|
|
||||||
// Number of register windows, can legally be 3 to 32
|
// Number of register windows, can legally be 3 to 32
|
||||||
const int NWindows = 8;
|
const int NWindows = 8;
|
||||||
//const int NumMicroIntRegs = 1;
|
// const int NumMicroIntRegs = 1;
|
||||||
const int NumMicroIntRegs = 9;
|
const int NumMicroIntRegs = 9;
|
||||||
|
|
||||||
// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
|
// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
|
||||||
// const int NumMicroIntRegs = 1;
|
// const int NumMicroIntRegs = 1;
|
||||||
// const int NumIntRegs =
|
// const int NumIntRegs = NumRegularIntRegs + NumMicroIntRegs;
|
||||||
// NumRegularIntRegs +
|
const int NumFloatRegs = 64;
|
||||||
// NumMicroIntRegs;
|
const int NumFloatArchRegs = NumFloatRegs;
|
||||||
const int NumFloatRegs = 64;
|
// const int NumMiscRegs = 40;
|
||||||
const int NumFloatArchRegs = NumFloatRegs;
|
|
||||||
// const int NumMiscRegs = 40;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
|
#endif // __ARCH_SPARC_SPARC_TRAITS_HH__
|
||||||
|
|
|
@ -39,23 +39,26 @@
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
class StackTrace
|
|
||||||
|
class StackTrace
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<Addr> stack;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool
|
||||||
|
trace(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
private:
|
panic("StackTrace::trace not implemented for SPARC.\n");
|
||||||
std::vector<Addr> stack;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
const std::vector<Addr> &getstack() const { return stack; }
|
||||||
bool trace(ThreadContext *tc, StaticInstPtr inst)
|
|
||||||
{
|
|
||||||
panic("StackTrace::trace not implemented for SPARC.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<Addr> &getstack() const { return stack; }
|
public:
|
||||||
|
void dprintf() {}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
|
||||||
void dprintf() {}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __ARCH_SPARC_STACKTRACE_HH__
|
#endif // __ARCH_SPARC_STACKTRACE_HH__
|
||||||
|
|
|
@ -111,26 +111,30 @@ class SparcSystem : public System
|
||||||
|
|
||||||
/** Add a function-based event to reset binary. */
|
/** Add a function-based event to reset binary. */
|
||||||
template <class T>
|
template <class T>
|
||||||
T *addResetFuncEvent(const char *lbl)
|
T *
|
||||||
|
addResetFuncEvent(const char *lbl)
|
||||||
{
|
{
|
||||||
return addFuncEvent<T>(resetSymtab, lbl);
|
return addFuncEvent<T>(resetSymtab, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a function-based event to the hypervisor. */
|
/** Add a function-based event to the hypervisor. */
|
||||||
template <class T>
|
template <class T>
|
||||||
T *addHypervisorFuncEvent(const char *lbl)
|
T *
|
||||||
|
addHypervisorFuncEvent(const char *lbl)
|
||||||
{
|
{
|
||||||
return addFuncEvent<T>(hypervisorSymtab, lbl);
|
return addFuncEvent<T>(hypervisorSymtab, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a function-based event to the openboot. */
|
/** Add a function-based event to the openboot. */
|
||||||
template <class T>
|
template <class T>
|
||||||
T *addOpenbootFuncEvent(const char *lbl)
|
T *
|
||||||
|
addOpenbootFuncEvent(const char *lbl)
|
||||||
{
|
{
|
||||||
return addFuncEvent<T>(openbootSymtab, lbl);
|
return addFuncEvent<T>(openbootSymtab, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Addr fixFuncEventAddr(Addr addr)
|
virtual Addr
|
||||||
|
fixFuncEventAddr(Addr addr)
|
||||||
{
|
{
|
||||||
//XXX This may eventually have to do something useful.
|
//XXX This may eventually have to do something useful.
|
||||||
return addr;
|
return addr;
|
||||||
|
|
|
@ -131,21 +131,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
i = lookupTable.find(tr);
|
|
||||||
if (i != lookupTable.end()) {
|
|
||||||
i->second->valid = false;
|
|
||||||
if (i->second->used) {
|
|
||||||
i->second->used = false;
|
|
||||||
usedEntries--;
|
|
||||||
}
|
|
||||||
freeList.push_front(i->second);
|
|
||||||
DPRINTF(TLB, "TLB: Found conflicting entry %#X , deleting it\n",
|
|
||||||
i->second);
|
|
||||||
lookupTable.erase(i);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (entry != -1) {
|
if (entry != -1) {
|
||||||
assert(entry < size && entry >= 0);
|
assert(entry < size && entry >= 0);
|
||||||
new_entry = &tlb[entry];
|
new_entry = &tlb[entry];
|
||||||
|
@ -164,13 +149,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
|
||||||
lastReplaced = x;
|
lastReplaced = x;
|
||||||
new_entry = &tlb[x];
|
new_entry = &tlb[x];
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
for (x = 0; x < size; x++) {
|
|
||||||
if (!tlb[x].valid || !tlb[x].used) {
|
|
||||||
new_entry = &tlb[x];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
insertAllLocked:
|
insertAllLocked:
|
||||||
|
@ -642,24 +620,24 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We need to check for priv level/asi priv
|
// We need to check for priv level/asi priv
|
||||||
if (!priv && !hpriv && !AsiIsUnPriv(asi)) {
|
if (!priv && !hpriv && !asiIsUnPriv(asi)) {
|
||||||
// It appears that context should be Nucleus in these cases?
|
// It appears that context should be Nucleus in these cases?
|
||||||
writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
|
writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||||
return new PrivilegedAction;
|
return new PrivilegedAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hpriv && AsiIsHPriv(asi)) {
|
if (!hpriv && asiIsHPriv(asi)) {
|
||||||
writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
|
writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||||
return new DataAccessException;
|
return new DataAccessException;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AsiIsPrimary(asi)) {
|
if (asiIsPrimary(asi)) {
|
||||||
context = pri_context;
|
context = pri_context;
|
||||||
ct = Primary;
|
ct = Primary;
|
||||||
} else if (AsiIsSecondary(asi)) {
|
} else if (asiIsSecondary(asi)) {
|
||||||
context = sec_context;
|
context = sec_context;
|
||||||
ct = Secondary;
|
ct = Secondary;
|
||||||
} else if (AsiIsNucleus(asi)) {
|
} else if (asiIsNucleus(asi)) {
|
||||||
ct = Nucleus;
|
ct = Nucleus;
|
||||||
context = 0;
|
context = 0;
|
||||||
} else { // ????
|
} else { // ????
|
||||||
|
@ -669,34 +647,34 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!implicit && asi != ASI_P && asi != ASI_S) {
|
if (!implicit && asi != ASI_P && asi != ASI_S) {
|
||||||
if (AsiIsLittle(asi))
|
if (asiIsLittle(asi))
|
||||||
panic("Little Endian ASIs not supported\n");
|
panic("Little Endian ASIs not supported\n");
|
||||||
|
|
||||||
//XXX It's unclear from looking at the documentation how a no fault
|
//XXX It's unclear from looking at the documentation how a no fault
|
||||||
//load differs from a regular one, other than what happens concerning
|
// load differs from a regular one, other than what happens concerning
|
||||||
//nfo and e bits in the TTE
|
// nfo and e bits in the TTE
|
||||||
// if (AsiIsNoFault(asi))
|
// if (asiIsNoFault(asi))
|
||||||
// panic("No Fault ASIs not supported\n");
|
// panic("No Fault ASIs not supported\n");
|
||||||
|
|
||||||
if (AsiIsPartialStore(asi))
|
if (asiIsPartialStore(asi))
|
||||||
panic("Partial Store ASIs not supported\n");
|
panic("Partial Store ASIs not supported\n");
|
||||||
|
|
||||||
if (AsiIsCmt(asi))
|
if (asiIsCmt(asi))
|
||||||
panic("Cmt ASI registers not implmented\n");
|
panic("Cmt ASI registers not implmented\n");
|
||||||
|
|
||||||
if (AsiIsInterrupt(asi))
|
if (asiIsInterrupt(asi))
|
||||||
goto handleIntRegAccess;
|
goto handleIntRegAccess;
|
||||||
if (AsiIsMmu(asi))
|
if (asiIsMmu(asi))
|
||||||
goto handleMmuRegAccess;
|
goto handleMmuRegAccess;
|
||||||
if (AsiIsScratchPad(asi))
|
if (asiIsScratchPad(asi))
|
||||||
goto handleScratchRegAccess;
|
goto handleScratchRegAccess;
|
||||||
if (AsiIsQueue(asi))
|
if (asiIsQueue(asi))
|
||||||
goto handleQueueRegAccess;
|
goto handleQueueRegAccess;
|
||||||
if (AsiIsSparcError(asi))
|
if (asiIsSparcError(asi))
|
||||||
goto handleSparcErrorRegAccess;
|
goto handleSparcErrorRegAccess;
|
||||||
|
|
||||||
if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) &&
|
if (!asiIsReal(asi) && !asiIsNucleus(asi) && !asiIsAsIfUser(asi) &&
|
||||||
!AsiIsTwin(asi) && !AsiIsBlock(asi) && !AsiIsNoFault(asi))
|
!asiIsTwin(asi) && !asiIsBlock(asi) && !asiIsNoFault(asi))
|
||||||
panic("Accessing ASI %#X. Should we?\n", asi);
|
panic("Accessing ASI %#X. Should we?\n", asi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,12 +692,12 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||||
return new DataAccessException;
|
return new DataAccessException;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) {
|
if ((!lsu_dm && !hpriv && !red) || asiIsReal(asi)) {
|
||||||
real = true;
|
real = true;
|
||||||
context = 0;
|
context = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
|
if (hpriv && (implicit || (!asiIsAsIfUser(asi) && !asiIsReal(asi)))) {
|
||||||
req->setPaddr(vaddr & PAddrImplMask);
|
req->setPaddr(vaddr & PAddrImplMask);
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
@ -752,13 +730,13 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||||
return new FastDataAccessProtection;
|
return new FastDataAccessProtection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->pte.nofault() && !AsiIsNoFault(asi)) {
|
if (e->pte.nofault() && !asiIsNoFault(asi)) {
|
||||||
writeTagAccess(vaddr, context);
|
writeTagAccess(vaddr, context);
|
||||||
writeSfsr(vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
|
writeSfsr(vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
|
||||||
return new DataAccessException;
|
return new DataAccessException;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->pte.sideffect() && AsiIsNoFault(asi)) {
|
if (e->pte.sideffect() && asiIsNoFault(asi)) {
|
||||||
writeTagAccess(vaddr, context);
|
writeTagAccess(vaddr, context);
|
||||||
writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi);
|
writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi);
|
||||||
return new DataAccessException;
|
return new DataAccessException;
|
||||||
|
@ -1207,13 +1185,13 @@ TLB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||||
ignore = true;
|
ignore = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(bits(va,7,6)) {
|
switch (bits(va,7,6)) {
|
||||||
case 0: // demap page
|
case 0: // demap page
|
||||||
if (!ignore)
|
if (!ignore)
|
||||||
tc->getITBPtr()->demapPage(mbits(va,63,13), part_id,
|
tc->getITBPtr()->demapPage(mbits(va,63,13), part_id,
|
||||||
bits(va,9,9), ctx_id);
|
bits(va,9,9), ctx_id);
|
||||||
break;
|
break;
|
||||||
case 1: //demap context
|
case 1: // demap context
|
||||||
if (!ignore)
|
if (!ignore)
|
||||||
tc->getITBPtr()->demapContext(part_id, ctx_id);
|
tc->getITBPtr()->demapContext(part_id, ctx_id);
|
||||||
break;
|
break;
|
||||||
|
@ -1258,12 +1236,12 @@ TLB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||||
ignore = true;
|
ignore = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(bits(va,7,6)) {
|
switch (bits(va,7,6)) {
|
||||||
case 0: // demap page
|
case 0: // demap page
|
||||||
if (!ignore)
|
if (!ignore)
|
||||||
demapPage(mbits(va,63,13), part_id, bits(va,9,9), ctx_id);
|
demapPage(mbits(va,63,13), part_id, bits(va,9,9), ctx_id);
|
||||||
break;
|
break;
|
||||||
case 1: //demap context
|
case 1: // demap context
|
||||||
if (!ignore)
|
if (!ignore)
|
||||||
demapContext(part_id, ctx_id);
|
demapContext(part_id, ctx_id);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -49,12 +49,12 @@ namespace SparcISA
|
||||||
class TLB : public BaseTLB
|
class TLB : public BaseTLB
|
||||||
{
|
{
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
//These faults need to be able to populate the tlb in SE mode.
|
// These faults need to be able to populate the tlb in SE mode.
|
||||||
friend class FastInstructionAccessMMUMiss;
|
friend class FastInstructionAccessMMUMiss;
|
||||||
friend class FastDataAccessMMUMiss;
|
friend class FastDataAccessMMUMiss;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//TLB state
|
// TLB state
|
||||||
protected:
|
protected:
|
||||||
// Only used when this is the data TLB.
|
// Only used when this is the data TLB.
|
||||||
uint64_t sfar;
|
uint64_t sfar;
|
||||||
|
@ -156,7 +156,8 @@ class TLB : public BaseTLB
|
||||||
typedef SparcTLBParams Params;
|
typedef SparcTLBParams Params;
|
||||||
TLB(const Params *p);
|
TLB(const Params *p);
|
||||||
|
|
||||||
void demapPage(Addr vaddr, uint64_t asn)
|
void
|
||||||
|
demapPage(Addr vaddr, uint64_t asn)
|
||||||
{
|
{
|
||||||
panic("demapPage(Addr) is not implemented.\n");
|
panic("demapPage(Addr) is not implemented.\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ class TlbMap
|
||||||
public:
|
public:
|
||||||
typedef RangeMap::iterator iterator;
|
typedef RangeMap::iterator iterator;
|
||||||
|
|
||||||
iterator find(const TlbRange &r)
|
iterator
|
||||||
|
find(const TlbRange &r)
|
||||||
{
|
{
|
||||||
iterator i;
|
iterator i;
|
||||||
|
|
||||||
|
@ -79,7 +80,8 @@ class TlbMap
|
||||||
return tree.end();
|
return tree.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intersect(const TlbRange &r)
|
bool
|
||||||
|
intersect(const TlbRange &r)
|
||||||
{
|
{
|
||||||
iterator i;
|
iterator i;
|
||||||
i = find(r);
|
i = find(r);
|
||||||
|
@ -89,7 +91,8 @@ class TlbMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
iterator insert(TlbRange &r, TlbEntry *d)
|
iterator
|
||||||
|
insert(TlbRange &r, TlbEntry *d)
|
||||||
{
|
{
|
||||||
if (intersect(r))
|
if (intersect(r))
|
||||||
return tree.end();
|
return tree.end();
|
||||||
|
@ -97,47 +100,56 @@ class TlbMap
|
||||||
return tree.insert(std::make_pair<TlbRange,TlbEntry*>(r, d)).first;
|
return tree.insert(std::make_pair<TlbRange,TlbEntry*>(r, d)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t erase(TlbRange k)
|
size_t
|
||||||
|
erase(TlbRange k)
|
||||||
{
|
{
|
||||||
return tree.erase(k);
|
return tree.erase(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase(iterator p)
|
void
|
||||||
|
erase(iterator p)
|
||||||
{
|
{
|
||||||
tree.erase(p);
|
tree.erase(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase(iterator p, iterator q)
|
void
|
||||||
|
erase(iterator p, iterator q)
|
||||||
{
|
{
|
||||||
tree.erase(p,q);
|
tree.erase(p,q);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void
|
||||||
|
clear()
|
||||||
{
|
{
|
||||||
tree.erase(tree.begin(), tree.end());
|
tree.erase(tree.begin(), tree.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin()
|
iterator
|
||||||
|
begin()
|
||||||
{
|
{
|
||||||
return tree.begin();
|
return tree.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end()
|
iterator
|
||||||
|
end()
|
||||||
{
|
{
|
||||||
return tree.end();
|
return tree.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size()
|
size_t
|
||||||
|
size()
|
||||||
{
|
{
|
||||||
return tree.size();
|
return tree.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty()
|
bool
|
||||||
|
empty()
|
||||||
{
|
{
|
||||||
return tree.empty();
|
return tree.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void print()
|
void
|
||||||
|
print()
|
||||||
{
|
{
|
||||||
iterator i;
|
iterator i;
|
||||||
i = tree.begin();
|
i = tree.begin();
|
||||||
|
|
|
@ -37,16 +37,19 @@
|
||||||
|
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
typedef uint32_t MachInst;
|
|
||||||
typedef uint64_t ExtMachInst;
|
|
||||||
|
|
||||||
typedef GenericISA::DelaySlotUPCState<MachInst> PCState;
|
typedef uint32_t MachInst;
|
||||||
|
typedef uint64_t ExtMachInst;
|
||||||
|
|
||||||
typedef Twin64_t LargestRead;
|
typedef GenericISA::DelaySlotUPCState<MachInst> PCState;
|
||||||
|
|
||||||
|
typedef Twin64_t LargestRead;
|
||||||
|
|
||||||
|
struct CoreSpecific
|
||||||
|
{
|
||||||
|
int core_type;
|
||||||
|
};
|
||||||
|
|
||||||
struct CoreSpecific {
|
|
||||||
int core_type;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,7 +63,7 @@ ISA::checkSoftInt(ThreadContext *tc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//These functions map register indices to names
|
// These functions map register indices to names
|
||||||
static inline string
|
static inline string
|
||||||
getMiscRegName(RegIndex index)
|
getMiscRegName(RegIndex index)
|
||||||
{
|
{
|
||||||
|
@ -267,7 +267,7 @@ ISA::readFSReg(int miscReg, ThreadContext * tc)
|
||||||
return ULL(0x3e) << 48 |
|
return ULL(0x3e) << 48 |
|
||||||
ULL(0x23) << 32 |
|
ULL(0x23) << 32 |
|
||||||
ULL(0x20) << 24 |
|
ULL(0x20) << 24 |
|
||||||
//MaxGL << 16 | XXX For some reason legion doesn't set GL
|
// MaxGL << 16 | XXX For some reason legion doesn't set GL
|
||||||
MaxTL << 8 |
|
MaxTL << 8 |
|
||||||
(NWindows -1) << 0;
|
(NWindows -1) << 0;
|
||||||
|
|
||||||
|
@ -334,8 +334,9 @@ ISA::processSTickCompare(ThreadContext *tc)
|
||||||
if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
|
if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
|
||||||
setMiscReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
|
setMiscReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1));
|
cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -361,7 +362,8 @@ ISA::processHSTickCompare(ThreadContext *tc)
|
||||||
setMiscReg(MISCREG_HINTP, 1, tc);
|
setMiscReg(MISCREG_HINTP, 1, tc);
|
||||||
}
|
}
|
||||||
// Need to do something to cause interrupt to happen here !!! @todo
|
// Need to do something to cause interrupt to happen here !!! @todo
|
||||||
} else
|
} else {
|
||||||
cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1));
|
cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,12 @@
|
||||||
namespace SparcISA {
|
namespace SparcISA {
|
||||||
|
|
||||||
|
|
||||||
//The caller uses %o0-%05 for the first 6 arguments even if their floating
|
// The caller uses %o0-%05 for the first 6 arguments even if their floating
|
||||||
//point. Double precision floating point values take two registers/args.
|
// point. Double precision floating point values take two registers/args.
|
||||||
//Quads, structs, and unions are passed as pointers. All arguments beyond
|
// Quads, structs, and unions are passed as pointers. All arguments beyond
|
||||||
//the sixth are passed on the stack past the 16 word window save area,
|
// the sixth are passed on the stack past the 16 word window save area,
|
||||||
//space for the struct/union return pointer, and space reserved for the
|
// space for the struct/union return pointer, and space reserved for the
|
||||||
//first 6 arguments which the caller may use but doesn't have to.
|
// first 6 arguments which the caller may use but doesn't have to.
|
||||||
uint64_t
|
uint64_t
|
||||||
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
{
|
{
|
||||||
|
@ -72,15 +72,18 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
uint8_t tl = src->readMiscRegNoEffect(MISCREG_TL);
|
uint8_t tl = src->readMiscRegNoEffect(MISCREG_TL);
|
||||||
|
|
||||||
// Read all the trap level dependent registers and save them off
|
// Read all the trap level dependent registers and save them off
|
||||||
for(int i = 1; i <= MaxTL; i++)
|
for (int i = 1; i <= MaxTL; i++) {
|
||||||
{
|
|
||||||
src->setMiscRegNoEffect(MISCREG_TL, i);
|
src->setMiscRegNoEffect(MISCREG_TL, i);
|
||||||
dest->setMiscRegNoEffect(MISCREG_TL, i);
|
dest->setMiscRegNoEffect(MISCREG_TL, i);
|
||||||
|
|
||||||
dest->setMiscRegNoEffect(MISCREG_TT, src->readMiscRegNoEffect(MISCREG_TT));
|
dest->setMiscRegNoEffect(MISCREG_TT,
|
||||||
dest->setMiscRegNoEffect(MISCREG_TPC, src->readMiscRegNoEffect(MISCREG_TPC));
|
src->readMiscRegNoEffect(MISCREG_TT));
|
||||||
dest->setMiscRegNoEffect(MISCREG_TNPC, src->readMiscRegNoEffect(MISCREG_TNPC));
|
dest->setMiscRegNoEffect(MISCREG_TPC,
|
||||||
dest->setMiscRegNoEffect(MISCREG_TSTATE, src->readMiscRegNoEffect(MISCREG_TSTATE));
|
src->readMiscRegNoEffect(MISCREG_TPC));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_TNPC,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_TNPC));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_TSTATE,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_TSTATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save off the traplevel
|
// Save off the traplevel
|
||||||
|
@ -89,42 +92,65 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
|
|
||||||
|
|
||||||
// ASRs
|
// ASRs
|
||||||
// dest->setMiscRegNoEffect(MISCREG_Y, src->readMiscRegNoEffect(MISCREG_Y));
|
// dest->setMiscRegNoEffect(MISCREG_Y,
|
||||||
// dest->setMiscRegNoEffect(MISCREG_CCR, src->readMiscRegNoEffect(MISCREG_CCR));
|
// src->readMiscRegNoEffect(MISCREG_Y));
|
||||||
dest->setMiscRegNoEffect(MISCREG_ASI, src->readMiscRegNoEffect(MISCREG_ASI));
|
// dest->setMiscRegNoEffect(MISCREG_CCR,
|
||||||
dest->setMiscRegNoEffect(MISCREG_TICK, src->readMiscRegNoEffect(MISCREG_TICK));
|
// src->readMiscRegNoEffect(MISCREG_CCR));
|
||||||
dest->setMiscRegNoEffect(MISCREG_FPRS, src->readMiscRegNoEffect(MISCREG_FPRS));
|
dest->setMiscRegNoEffect(MISCREG_ASI,
|
||||||
dest->setMiscRegNoEffect(MISCREG_SOFTINT, src->readMiscRegNoEffect(MISCREG_SOFTINT));
|
src->readMiscRegNoEffect(MISCREG_ASI));
|
||||||
dest->setMiscRegNoEffect(MISCREG_TICK_CMPR, src->readMiscRegNoEffect(MISCREG_TICK_CMPR));
|
dest->setMiscRegNoEffect(MISCREG_TICK,
|
||||||
dest->setMiscRegNoEffect(MISCREG_STICK, src->readMiscRegNoEffect(MISCREG_STICK));
|
src->readMiscRegNoEffect(MISCREG_TICK));
|
||||||
dest->setMiscRegNoEffect(MISCREG_STICK_CMPR, src->readMiscRegNoEffect(MISCREG_STICK_CMPR));
|
dest->setMiscRegNoEffect(MISCREG_FPRS,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_FPRS));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_SOFTINT,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_SOFTINT));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_TICK_CMPR,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_TICK_CMPR));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_STICK,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_STICK));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_STICK_CMPR,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_STICK_CMPR));
|
||||||
|
|
||||||
// Priv Registers
|
// Priv Registers
|
||||||
dest->setMiscRegNoEffect(MISCREG_TICK, src->readMiscRegNoEffect(MISCREG_TICK));
|
dest->setMiscRegNoEffect(MISCREG_TICK,
|
||||||
dest->setMiscRegNoEffect(MISCREG_TBA, src->readMiscRegNoEffect(MISCREG_TBA));
|
src->readMiscRegNoEffect(MISCREG_TICK));
|
||||||
dest->setMiscRegNoEffect(MISCREG_PSTATE, src->readMiscRegNoEffect(MISCREG_PSTATE));
|
dest->setMiscRegNoEffect(MISCREG_TBA,
|
||||||
dest->setMiscRegNoEffect(MISCREG_PIL, src->readMiscRegNoEffect(MISCREG_PIL));
|
src->readMiscRegNoEffect(MISCREG_TBA));
|
||||||
dest->setMiscReg(MISCREG_CWP, src->readMiscRegNoEffect(MISCREG_CWP));
|
dest->setMiscRegNoEffect(MISCREG_PSTATE,
|
||||||
// dest->setMiscRegNoEffect(MISCREG_CANSAVE, src->readMiscRegNoEffect(MISCREG_CANSAVE));
|
src->readMiscRegNoEffect(MISCREG_PSTATE));
|
||||||
// dest->setMiscRegNoEffect(MISCREG_CANRESTORE, src->readMiscRegNoEffect(MISCREG_CANRESTORE));
|
dest->setMiscRegNoEffect(MISCREG_PIL,
|
||||||
// dest->setMiscRegNoEffect(MISCREG_OTHERWIN, src->readMiscRegNoEffect(MISCREG_OTHERWIN));
|
src->readMiscRegNoEffect(MISCREG_PIL));
|
||||||
// dest->setMiscRegNoEffect(MISCREG_CLEANWIN, src->readMiscRegNoEffect(MISCREG_CLEANWIN));
|
dest->setMiscReg(MISCREG_CWP,
|
||||||
// dest->setMiscRegNoEffect(MISCREG_WSTATE, src->readMiscRegNoEffect(MISCREG_WSTATE));
|
src->readMiscRegNoEffect(MISCREG_CWP));
|
||||||
|
// dest->setMiscRegNoEffect(MISCREG_CANSAVE,
|
||||||
|
// src->readMiscRegNoEffect(MISCREG_CANSAVE));
|
||||||
|
// dest->setMiscRegNoEffect(MISCREG_CANRESTORE,
|
||||||
|
// src->readMiscRegNoEffect(MISCREG_CANRESTORE));
|
||||||
|
// dest->setMiscRegNoEffect(MISCREG_OTHERWIN,
|
||||||
|
// src->readMiscRegNoEffect(MISCREG_OTHERWIN));
|
||||||
|
// dest->setMiscRegNoEffect(MISCREG_CLEANWIN,
|
||||||
|
// src->readMiscRegNoEffect(MISCREG_CLEANWIN));
|
||||||
|
// dest->setMiscRegNoEffect(MISCREG_WSTATE,
|
||||||
|
// src->readMiscRegNoEffect(MISCREG_WSTATE));
|
||||||
dest->setMiscReg(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
|
dest->setMiscReg(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
|
||||||
|
|
||||||
// Hyperprivilged registers
|
// Hyperprivilged registers
|
||||||
dest->setMiscRegNoEffect(MISCREG_HPSTATE, src->readMiscRegNoEffect(MISCREG_HPSTATE));
|
dest->setMiscRegNoEffect(MISCREG_HPSTATE,
|
||||||
dest->setMiscRegNoEffect(MISCREG_HINTP, src->readMiscRegNoEffect(MISCREG_HINTP));
|
src->readMiscRegNoEffect(MISCREG_HPSTATE));
|
||||||
dest->setMiscRegNoEffect(MISCREG_HTBA, src->readMiscRegNoEffect(MISCREG_HTBA));
|
dest->setMiscRegNoEffect(MISCREG_HINTP,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_HINTP));
|
||||||
|
dest->setMiscRegNoEffect(MISCREG_HTBA,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_HTBA));
|
||||||
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
||||||
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
||||||
dest->setMiscRegNoEffect(MISCREG_HSTICK_CMPR,
|
dest->setMiscRegNoEffect(MISCREG_HSTICK_CMPR,
|
||||||
src->readMiscRegNoEffect(MISCREG_HSTICK_CMPR));
|
src->readMiscRegNoEffect(MISCREG_HSTICK_CMPR));
|
||||||
|
|
||||||
// FSR
|
// FSR
|
||||||
dest->setMiscRegNoEffect(MISCREG_FSR, src->readMiscRegNoEffect(MISCREG_FSR));
|
dest->setMiscRegNoEffect(MISCREG_FSR,
|
||||||
|
src->readMiscRegNoEffect(MISCREG_FSR));
|
||||||
|
|
||||||
//Strand Status Register
|
// Strand Status Register
|
||||||
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
||||||
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
||||||
|
|
||||||
|
@ -178,10 +204,10 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
void
|
void
|
||||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
{
|
{
|
||||||
//First loop through the integer registers.
|
// First loop through the integer registers.
|
||||||
int old_gl = src->readMiscRegNoEffect(MISCREG_GL);
|
int old_gl = src->readMiscRegNoEffect(MISCREG_GL);
|
||||||
int old_cwp = src->readMiscRegNoEffect(MISCREG_CWP);
|
int old_cwp = src->readMiscRegNoEffect(MISCREG_CWP);
|
||||||
//Globals
|
// Globals
|
||||||
for (int x = 0; x < MaxGL; ++x) {
|
for (int x = 0; x < MaxGL; ++x) {
|
||||||
src->setMiscReg(MISCREG_GL, x);
|
src->setMiscReg(MISCREG_GL, x);
|
||||||
dest->setMiscReg(MISCREG_GL, x);
|
dest->setMiscReg(MISCREG_GL, x);
|
||||||
|
@ -189,18 +215,18 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||||
for (int y = 1; y < 8; y++)
|
for (int y = 1; y < 8; y++)
|
||||||
dest->setIntReg(y, src->readIntReg(y));
|
dest->setIntReg(y, src->readIntReg(y));
|
||||||
}
|
}
|
||||||
//Locals and ins. Outs are all also ins.
|
// Locals and ins. Outs are all also ins.
|
||||||
for (int x = 0; x < NWindows; ++x) {
|
for (int x = 0; x < NWindows; ++x) {
|
||||||
src->setMiscReg(MISCREG_CWP, x);
|
src->setMiscReg(MISCREG_CWP, x);
|
||||||
dest->setMiscReg(MISCREG_CWP, x);
|
dest->setMiscReg(MISCREG_CWP, x);
|
||||||
for (int y = 16; y < 32; y++)
|
for (int y = 16; y < 32; y++)
|
||||||
dest->setIntReg(y, src->readIntReg(y));
|
dest->setIntReg(y, src->readIntReg(y));
|
||||||
}
|
}
|
||||||
//Microcode reg and pseudo int regs (misc regs in the integer regfile).
|
// Microcode reg and pseudo int regs (misc regs in the integer regfile).
|
||||||
for (int y = NumIntArchRegs; y < NumIntArchRegs + NumMicroIntRegs; ++y)
|
for (int y = NumIntArchRegs; y < NumIntArchRegs + NumMicroIntRegs; ++y)
|
||||||
dest->setIntReg(y, src->readIntReg(y));
|
dest->setIntReg(y, src->readIntReg(y));
|
||||||
|
|
||||||
//Restore src's GL, CWP
|
// Restore src's GL, CWP
|
||||||
src->setMiscReg(MISCREG_GL, old_gl);
|
src->setMiscReg(MISCREG_GL, old_gl);
|
||||||
src->setMiscReg(MISCREG_CWP, old_cwp);
|
src->setMiscReg(MISCREG_CWP, old_cwp);
|
||||||
|
|
||||||
|
@ -234,4 +260,4 @@ initCPU(ThreadContext *tc, int cpuId)
|
||||||
por->invoke(tc);
|
por->invoke(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace SPARC_ISA
|
} // namespace SPARC_ISA
|
||||||
|
|
|
@ -43,57 +43,56 @@
|
||||||
namespace SparcISA
|
namespace SparcISA
|
||||||
{
|
{
|
||||||
|
|
||||||
inline PCState
|
inline PCState
|
||||||
buildRetPC(const PCState &curPC, const PCState &callPC)
|
buildRetPC(const PCState &curPC, const PCState &callPC)
|
||||||
{
|
{
|
||||||
PCState ret = callPC;
|
PCState ret = callPC;
|
||||||
ret.uEnd();
|
ret.uEnd();
|
||||||
ret.pc(curPC.npc());
|
ret.pc(curPC.npc());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
|
||||||
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
inUserMode(ThreadContext *tc)
|
inUserMode(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
return !((tc->readMiscRegNoEffect(MISCREG_PSTATE) & (1 << 2)) ||
|
return !((tc->readMiscRegNoEffect(MISCREG_PSTATE) & (1 << 2)) ||
|
||||||
(tc->readMiscRegNoEffect(MISCREG_HPSTATE) & (1 << 2)));
|
(tc->readMiscRegNoEffect(MISCREG_HPSTATE) & (1 << 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to insure ISA semantics about 0 registers.
|
* Function to insure ISA semantics about 0 registers.
|
||||||
* @param tc The thread context.
|
* @param tc The thread context.
|
||||||
*/
|
*/
|
||||||
template <class TC>
|
template <class TC>
|
||||||
void zeroRegisters(TC *tc);
|
void zeroRegisters(TC *tc);
|
||||||
|
|
||||||
void initCPU(ThreadContext *tc, int cpuId);
|
void initCPU(ThreadContext *tc, int cpuId);
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
startupCPU(ThreadContext *tc, int cpuId)
|
startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
// Other CPUs will get activated by IPIs
|
// Other CPUs will get activated by IPIs
|
||||||
if (cpuId == 0)
|
if (cpuId == 0)
|
||||||
tc->activate(0);
|
|
||||||
#else
|
|
||||||
tc->activate(0);
|
tc->activate(0);
|
||||||
|
#else
|
||||||
|
tc->activate(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void skipFunction(ThreadContext *tc);
|
void skipFunction(ThreadContext *tc);
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
advancePC(PCState &pc, const StaticInstPtr inst)
|
advancePC(PCState &pc, const StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
inst->advancePC(pc);
|
inst->advancePC(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SparcISA
|
} // namespace SparcISA
|
||||||
|
|
||||||
|
|
|
@ -71,14 +71,14 @@ vtophys(ThreadContext *tc, Addr addr)
|
||||||
uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
|
uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
|
||||||
|
|
||||||
bool hpriv = bits(tlbdata,0,0);
|
bool hpriv = bits(tlbdata,0,0);
|
||||||
//bool priv = bits(tlbdata,2,2);
|
// bool priv = bits(tlbdata,2,2);
|
||||||
bool addr_mask = bits(tlbdata,3,3);
|
bool addr_mask = bits(tlbdata,3,3);
|
||||||
bool data_real = !bits(tlbdata,5,5);
|
bool data_real = !bits(tlbdata,5,5);
|
||||||
bool inst_real = !bits(tlbdata,4,4);
|
bool inst_real = !bits(tlbdata,4,4);
|
||||||
bool ctx_zero = bits(tlbdata,18,16) > 0;
|
bool ctx_zero = bits(tlbdata,18,16) > 0;
|
||||||
int part_id = bits(tlbdata,15,8);
|
int part_id = bits(tlbdata,15,8);
|
||||||
int pri_context = bits(tlbdata,47,32);
|
int pri_context = bits(tlbdata,47,32);
|
||||||
//int sec_context = bits(tlbdata,63,48);
|
// int sec_context = bits(tlbdata,63,48);
|
||||||
|
|
||||||
FunctionalPort *mem = tc->getPhysPort();
|
FunctionalPort *mem = tc->getPhysPort();
|
||||||
TLB* itb = tc->getITBPtr();
|
TLB* itb = tc->getITBPtr();
|
||||||
|
|
Loading…
Reference in a new issue