From 1fc48cc45471be63a6c7cb4eb2e3a2c13f8f9bf3 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Thu, 22 Feb 2018 18:45:30 +0000 Subject: dev, arm: Add support for HYP & secure timers Change-Id: I1a4849283f9bd5b1856e1378f7cefc33fc14eebd Signed-off-by: Andreas Sandberg Reviewed-by: Curtis Dunham Reviewed-on: https://gem5-review.googlesource.com/10023 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini --- src/dev/arm/generic_timer.cc | 112 +++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 40 deletions(-) (limited to 'src/dev/arm/generic_timer.cc') diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc index 73e4f9143..1d5e8bb00 100644 --- a/src/dev/arm/generic_timer.cc +++ b/src/dev/arm/generic_timer.cc @@ -69,6 +69,7 @@ void SystemCounter::serialize(CheckpointOut &cp) const { SERIALIZE_SCALAR(_regCntkctl); + SERIALIZE_SCALAR(_regCnthctl); SERIALIZE_SCALAR(_freq); SERIALIZE_SCALAR(_period); SERIALIZE_SCALAR(_resetTick); @@ -81,6 +82,8 @@ SystemCounter::unserialize(CheckpointIn &cp) // if it isn't present. if (!UNSERIALIZE_OPT_SCALAR(_regCntkctl)) _regCntkctl = 0; + if (!UNSERIALIZE_OPT_SCALAR(_regCnthctl)) + _regCnthctl = 0; UNSERIALIZE_SCALAR(_freq); UNSERIALIZE_SCALAR(_period); UNSERIALIZE_SCALAR(_resetTick); @@ -242,8 +245,10 @@ GenericTimer::GenericTimer(GenericTimerParams *p) : ClockedObject(p), system(*p->system), gic(p->gic), - irqPhys(p->int_phys), - irqVirt(p->int_virt) + irqPhysS(p->int_phys_s), + irqPhysNS(p->int_phys_ns), + irqVirt(p->int_virt), + irqHyp(p->int_hyp) { fatal_if(!p->system, "No system specified, can't instantiate timer.\n"); system.setGenericTimer(this); @@ -261,8 +266,10 @@ GenericTimer::serialize(CheckpointOut &cp) const // This should really be phys_timerN, but we are stuck with // arch_timer for backwards compatibility. - core.phys.serializeSection(cp, csprintf("arch_timer%d", i)); + core.physNS.serializeSection(cp, csprintf("arch_timer%d", i)); + core.physS.serializeSection(cp, csprintf("phys_s_timer%d", i)); core.virt.serializeSection(cp, csprintf("virt_timer%d", i)); + core.hyp.serializeSection(cp, csprintf("hyp_timer%d", i)); } } @@ -286,8 +293,10 @@ GenericTimer::unserialize(CheckpointIn &cp) CoreTimers &core(getTimers(i)); // This should really be phys_timerN, but we are stuck with // arch_timer for backwards compatibility. - core.phys.unserializeSection(cp, csprintf("arch_timer%d", i)); + core.physNS.unserializeSection(cp, csprintf("arch_timer%d", i)); + core.physS.unserializeSection(cp, csprintf("phys_s_timer%d", i)); core.virt.unserializeSection(cp, csprintf("virt_timer%d", i)); + core.hyp.unserializeSection(cp, csprintf("hyp_timer%d", i)); } } @@ -310,7 +319,8 @@ GenericTimer::createTimers(unsigned cpus) timers.resize(cpus); for (unsigned i = old_cpu_count; i < cpus; ++i) { timers[i].reset( - new CoreTimers(*this, system, i, irqPhys, irqVirt)); + new CoreTimers(*this, system, i, + irqPhysS, irqPhysNS, irqVirt, irqHyp)); } } @@ -331,23 +341,25 @@ GenericTimer::setMiscReg(int reg, unsigned cpu, MiscReg val) systemCounter.setKernelControl(val); return; - // Physical timer - case MISCREG_CNTP_CVAL: + case MISCREG_CNTHCTL: + case MISCREG_CNTHCTL_EL2: + systemCounter.setHypControl(val); + return; + + // Physical timer (NS) case MISCREG_CNTP_CVAL_NS: case MISCREG_CNTP_CVAL_EL0: - core.phys.setCompareValue(val); + core.physNS.setCompareValue(val); return; - case MISCREG_CNTP_TVAL: case MISCREG_CNTP_TVAL_NS: case MISCREG_CNTP_TVAL_EL0: - core.phys.setTimerValue(val); + core.physNS.setTimerValue(val); return; - case MISCREG_CNTP_CTL: case MISCREG_CNTP_CTL_NS: case MISCREG_CNTP_CTL_EL0: - core.phys.setControl(val); + core.physNS.setControl(val); return; // Count registers @@ -380,24 +392,36 @@ GenericTimer::setMiscReg(int reg, unsigned cpu, MiscReg val) core.virt.setControl(val); return; - // PL1 phys. timer, secure + // Physical timer (S) case MISCREG_CNTP_CTL_S: + case MISCREG_CNTPS_CTL_EL1: + core.physS.setControl(val); + return; + + case MISCREG_CNTP_CVAL_S: case MISCREG_CNTPS_CVAL_EL1: + core.physS.setCompareValue(val); + return; + + case MISCREG_CNTP_TVAL_S: case MISCREG_CNTPS_TVAL_EL1: - case MISCREG_CNTPS_CTL_EL1: - M5_FALLTHROUGH; + core.physS.setTimerValue(val); + return; + + // Hyp phys. timer, non-secure + case MISCREG_CNTHP_CTL: + case MISCREG_CNTHP_CTL_EL2: + core.hyp.setControl(val); + return; - // PL2 phys. timer, non-secure - case MISCREG_CNTHCTL: - case MISCREG_CNTHCTL_EL2: case MISCREG_CNTHP_CVAL: case MISCREG_CNTHP_CVAL_EL2: + core.hyp.setCompareValue(val); + return; + case MISCREG_CNTHP_TVAL: case MISCREG_CNTHP_TVAL_EL2: - case MISCREG_CNTHP_CTL: - case MISCREG_CNTHP_CTL_EL2: - warn("Writing to unimplemented register: %s\n", - miscRegName[reg]); + core.hyp.setTimerValue(val); return; default: @@ -421,23 +445,26 @@ GenericTimer::readMiscReg(int reg, unsigned cpu) case MISCREG_CNTKCTL_EL1: return systemCounter.getKernelControl(); + case MISCREG_CNTHCTL: + case MISCREG_CNTHCTL_EL2: + return systemCounter.getHypControl(); + // Physical timer - case MISCREG_CNTP_CVAL: + case MISCREG_CNTP_CVAL_NS: case MISCREG_CNTP_CVAL_EL0: - return core.phys.compareValue(); + return core.physNS.compareValue(); - case MISCREG_CNTP_TVAL: + case MISCREG_CNTP_TVAL_NS: case MISCREG_CNTP_TVAL_EL0: - return core.phys.timerValue(); + return core.physNS.timerValue(); - case MISCREG_CNTP_CTL: case MISCREG_CNTP_CTL_EL0: case MISCREG_CNTP_CTL_NS: - return core.phys.control(); + return core.physNS.control(); case MISCREG_CNTPCT: case MISCREG_CNTPCT_EL0: - return core.phys.value(); + return core.physNS.value(); // Virtual timer @@ -463,24 +490,29 @@ GenericTimer::readMiscReg(int reg, unsigned cpu) // PL1 phys. timer, secure case MISCREG_CNTP_CTL_S: + case MISCREG_CNTPS_CTL_EL1: + return core.physS.control(); + + case MISCREG_CNTP_CVAL_S: case MISCREG_CNTPS_CVAL_EL1: + return core.physS.compareValue(); + + case MISCREG_CNTP_TVAL_S: case MISCREG_CNTPS_TVAL_EL1: - case MISCREG_CNTPS_CTL_EL1: - M5_FALLTHROUGH; + return core.physS.timerValue(); + + // HYP phys. timer (NS) + case MISCREG_CNTHP_CTL: + case MISCREG_CNTHP_CTL_EL2: + return core.hyp.control(); - // PL2 phys. timer, non-secure - case MISCREG_CNTHCTL: - case MISCREG_CNTHCTL_EL2: case MISCREG_CNTHP_CVAL: case MISCREG_CNTHP_CVAL_EL2: + return core.hyp.compareValue(); + case MISCREG_CNTHP_TVAL: case MISCREG_CNTHP_TVAL_EL2: - case MISCREG_CNTHP_CTL: - case MISCREG_CNTHP_CTL_EL2: - warn("Reading from unimplemented register: %s\n", - miscRegName[reg]); - return 0; - + return core.hyp.timerValue(); default: warn("Reading from unknown register: %s\n", miscRegName[reg]); -- cgit v1.2.3