diff options
Diffstat (limited to 'src/arch/arm/isa.cc')
-rw-r--r-- | src/arch/arm/isa.cc | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index e76ff452d..c2250e38a 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -39,8 +39,10 @@ */ #include "arch/arm/isa.hh" +#include "arch/arm/pmu.hh" #include "arch/arm/system.hh" #include "cpu/checker/cpu.hh" +#include "cpu/base.hh" #include "debug/Arm.hh" #include "debug/MiscRegs.hh" #include "params/ArmISA.hh" @@ -122,12 +124,21 @@ const struct ISA::MiscRegInitializerEntry ISA::ISA(Params *p) - : SimObject(p), system(NULL), lookUpMiscReg(NUM_MISCREGS, {0,0}) + : SimObject(p), + system(NULL), + pmu(p->pmu), + lookUpMiscReg(NUM_MISCREGS, {0,0}) { SCTLR sctlr; sctlr = 0; miscRegs[MISCREG_SCTLR_RST] = sctlr; + // Hook up a dummy device if we haven't been configured with a + // real PMU. By using a dummy device, we don't need to check that + // the PMU exist every time we try to access a PMU register. + if (!pmu) + pmu = &dummyDevice; + system = dynamic_cast<ArmSystem *>(p->system); DPRINTFN("ISA system set to: %p %p\n", system, p->system); @@ -356,7 +367,10 @@ ISA::clear64(const ArmISAParams *p) // Initialize configurable id registers miscRegs[MISCREG_ID_AA64AFR0_EL1] = p->id_aa64afr0_el1; miscRegs[MISCREG_ID_AA64AFR1_EL1] = p->id_aa64afr1_el1; - miscRegs[MISCREG_ID_AA64DFR0_EL1] = p->id_aa64dfr0_el1; + miscRegs[MISCREG_ID_AA64DFR0_EL1] = + (p->id_aa64dfr0_el1 & 0xfffffffffffff0ffULL) | + (p->pmu ? 0x0000000000000100ULL : 0); // Enable PMUv3 + miscRegs[MISCREG_ID_AA64DFR1_EL1] = p->id_aa64dfr1_el1; miscRegs[MISCREG_ID_AA64ISAR0_EL1] = p->id_aa64isar0_el1; miscRegs[MISCREG_ID_AA64ISAR1_EL1] = p->id_aa64isar1_el1; @@ -365,6 +379,11 @@ ISA::clear64(const ArmISAParams *p) miscRegs[MISCREG_ID_AA64PFR0_EL1] = p->id_aa64pfr0_el1; miscRegs[MISCREG_ID_AA64PFR1_EL1] = p->id_aa64pfr1_el1; + miscRegs[MISCREG_ID_DFR0_EL1] = + (p->pmu ? 0x03000000ULL : 0); // Enable PMUv3 + + miscRegs[MISCREG_ID_DFR0] = miscRegs[MISCREG_ID_DFR0_EL1]; + // Enforce consistency with system-level settings... // EL3 @@ -491,7 +510,6 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) // top bit defined as RES1 return readMiscRegNoEffect(misc_reg) | 0x80000000; case MISCREG_ID_AFR0: // not implemented, so alias MIDR - case MISCREG_ID_DFR0: // not implemented, so alias MIDR case MISCREG_REVIDR: // not implemented, so alias MIDR case MISCREG_MIDR: cpsr = readMiscRegNoEffect(MISCREG_CPSR); @@ -549,12 +567,13 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) case MISCREG_ACTLR: warn("Not doing anything for miscreg ACTLR\n"); break; - case MISCREG_PMCR: - case MISCREG_PMCCNTR: - case MISCREG_PMSELR: - warn("Not doing anything for read to miscreg %s\n", - miscRegName[misc_reg]); - break; + + case MISCREG_PMXEVTYPER_PMCCFILTR: + case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0: + case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0: + case MISCREG_PMCR ... MISCREG_PMOVSSET: + return pmu->readMiscReg(misc_reg); + case MISCREG_CPSR_Q: panic("shouldn't be reading this register seperately\n"); case MISCREG_FPSCR_QC: @@ -640,9 +659,9 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) } case MISCREG_DBGDIDR: /* For now just implement the version number. - * Return 0 as we don't support debug architecture yet. + * ARMv7, v7.1 Debug architecture (0b0101 --> 0x5) */ - return 0; + return 0x5 << 16; case MISCREG_DBGDSCRint: return 0; case MISCREG_ISR: @@ -1112,6 +1131,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) case MISCREG_MIDR: case MISCREG_ID_PFR0: case MISCREG_ID_PFR1: + case MISCREG_ID_DFR0: case MISCREG_ID_MMFR0: case MISCREG_ID_MMFR1: case MISCREG_ID_MMFR2: @@ -1443,24 +1463,15 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) case MISCREG_ACTLR: warn("Not doing anything for write of miscreg ACTLR\n"); break; - case MISCREG_PMCR: - { - // Performance counters not implemented. Instead, interpret - // a reset command to this register to reset the simulator - // statistics. - // PMCR_E | PMCR_P | PMCR_C - const int ResetAndEnableCounters = 0x7; - if (newVal == ResetAndEnableCounters) { - inform("Resetting all simobject stats\n"); - Stats::schedStatEvent(false, true); - break; - } - } - case MISCREG_PMCCNTR: - case MISCREG_PMSELR: - warn("Not doing anything for write to miscreg %s\n", - miscRegName[misc_reg]); + + case MISCREG_PMXEVTYPER_PMCCFILTR: + case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0: + case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0: + case MISCREG_PMCR ... MISCREG_PMOVSSET: + pmu->setMiscReg(misc_reg, newVal); break; + + case MISCREG_HSTR: // TJDBX, now redifined to be RES0 { HSTR hstrMask = 0; |