summaryrefslogtreecommitdiff
path: root/src/dev/arm/generic_timer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/arm/generic_timer.cc')
-rw-r--r--src/dev/arm/generic_timer.cc112
1 files changed, 72 insertions, 40 deletions
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]);