.privSecure(!aarch32EL3)
.monSecure(0);
InitReg(MISCREG_CNTP_TVAL_S)
- .unimplemented()
.bankedChild()
.secure().user(1);
InitReg(MISCREG_CNTP_CTL)
.privSecure(!aarch32EL3)
.monSecure(0);
InitReg(MISCREG_CNTP_CTL_S)
- .unimplemented()
.bankedChild()
.secure().user(1);
InitReg(MISCREG_CNTV_TVAL)
InitReg(MISCREG_CNTV_CTL)
.allPrivileges();
InitReg(MISCREG_CNTHCTL)
- .unimplemented()
.hypWrite().monNonSecureRead();
InitReg(MISCREG_CNTHP_TVAL)
- .unimplemented()
.hypWrite().monNonSecureRead();
InitReg(MISCREG_CNTHP_CTL)
- .unimplemented()
.hypWrite().monNonSecureRead();
InitReg(MISCREG_IL1DATA0)
.unimplemented()
.privSecure(!aarch32EL3)
.monSecure(0);
InitReg(MISCREG_CNTP_CVAL_S)
- .unimplemented()
.bankedChild()
.secure().user(1);
InitReg(MISCREG_CNTV_CVAL)
InitReg(MISCREG_CNTVOFF)
.hyp().monNonSecure();
InitReg(MISCREG_CNTHP_CVAL)
- .unimplemented()
.hypWrite().monNonSecureRead();
InitReg(MISCREG_CPUMERRSR)
.unimplemented()
.hyp().mon()
.mapsTo(MISCREG_CNTVOFF); /* 64b */
InitReg(MISCREG_CNTHCTL_EL2)
- .unimplemented()
- .warnNotFail()
- .mon().monNonSecureWrite(0).hypWrite()
+ .mon().hyp()
.mapsTo(MISCREG_CNTHCTL);
InitReg(MISCREG_CNTHP_TVAL_EL2)
- .unimplemented()
- .mon().monNonSecureWrite(0).hypWrite()
+ .mon().hyp()
.mapsTo(MISCREG_CNTHP_TVAL);
InitReg(MISCREG_CNTHP_CTL_EL2)
- .unimplemented()
- .mon().monNonSecureWrite(0).hypWrite()
+ .mon().hyp()
.mapsTo(MISCREG_CNTHP_CTL);
InitReg(MISCREG_CNTHP_CVAL_EL2)
- .unimplemented()
- .mon().monNonSecureWrite(0).hypWrite()
+ .mon().hyp()
.mapsTo(MISCREG_CNTHP_CVAL); /* 64b */
InitReg(MISCREG_CNTPS_TVAL_EL1)
- .unimplemented()
- .mon().monNonSecureWrite(0).hypWrite();
+ .mon().privSecure();
InitReg(MISCREG_CNTPS_CTL_EL1)
- .unimplemented()
- .mon().monNonSecureWrite(0).hypWrite();
+ .mon().privSecure();
InitReg(MISCREG_CNTPS_CVAL_EL1)
- .unimplemented()
- .mon().monNonSecureWrite(0).hypWrite();
+ .mon().privSecure();
InitReg(MISCREG_IL1DATA0_EL1)
.allPrivileges().exceptUserMode();
InitReg(MISCREG_IL1DATA1_EL1)
cxx_header = "dev/arm/generic_timer.hh"
system = Param.ArmSystem(Parent.any, "system")
gic = Param.BaseGic(Parent.any, "GIC to use for interrupting")
- # @todo: for now only two timers per CPU is supported, which is the
- # normal behaviour when security extensions are disabled.
- int_phys = Param.UInt32("Physical timer interrupt number")
+ int_phys_s = Param.UInt32("Physical (S) timer interrupt number")
+ int_phys_ns = Param.UInt32("Physical (NS) timer interrupt number")
int_virt = Param.UInt32("Virtual timer interrupt number")
+ int_hyp = Param.UInt32("Hypervisor timer interrupt number")
def generateDeviceTree(self, state):
node = FdtNode("timer")
node.appendCompatible(["arm,cortex-a15-timer",
"arm,armv7-timer",
"arm,armv8-timer"])
- node.append(FdtPropertyWords("interrupts",
- [1, int(self.int_phys) - 16, 0xf08,
- 1, int(self.int_virt) - 16, 0xf08]))
+ node.append(FdtPropertyWords("interrupts", [
+ 1, int(self.int_phys_s) - 16, 0xf08,
+ 1, int(self.int_phys_ns) - 16, 0xf08,
+ 1, int(self.int_virt) - 16, 0xf08,
+ 1, int(self.int_hyp) - 16, 0xf08,
+ ]))
clock = state.phandle(self.clk_domain.unproxy(self))
node.append(FdtPropertyWords("clocks", clock))
conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
pci_pio_base=0)
- generic_timer = GenericTimer(int_phys=29, int_virt=27)
+ generic_timer = GenericTimer(int_phys_s=29, int_phys_ns=30,
+ int_virt=27, int_hyp=26)
timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
clcd = Pl111(pio_addr=0x1c1f0000, int_num=46)
Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
]
- generic_timer = GenericTimer(int_phys=29, int_virt=27)
+ generic_timer = GenericTimer(int_phys_s=29, int_phys_ns=30,
+ int_virt=27, int_hyp=26)
hdlcd = HDLcd(pxl_clk=dcc.osc_pxl,
pio_addr=0x2b000000, int_num=95)
SystemCounter::serialize(CheckpointOut &cp) const
{
SERIALIZE_SCALAR(_regCntkctl);
+ SERIALIZE_SCALAR(_regCnthctl);
SERIALIZE_SCALAR(_freq);
SERIALIZE_SCALAR(_period);
SERIALIZE_SCALAR(_resetTick);
// 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);
: 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);
// 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));
}
}
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));
}
}
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));
}
}
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
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:
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
// 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]);
/// Tick when the counter was reset.
Tick _resetTick;
+ /// Kernel event stream control register
uint32_t _regCntkctl;
+ /// Hypervisor event stream control register
+ uint32_t _regCnthctl;
public:
SystemCounter();
void setKernelControl(uint32_t val) { _regCntkctl = val; }
uint32_t getKernelControl() { return _regCntkctl; }
+ void setHypControl(uint32_t val) { _regCnthctl = val; }
+ uint32_t getHypControl() { return _regCnthctl; }
+
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
protected:
struct CoreTimers {
CoreTimers(GenericTimer &parent, ArmSystem &system, unsigned cpu,
- unsigned _irqPhys, unsigned _irqVirt)
- : irqPhys(*parent.gic, _irqPhys, cpu),
+ unsigned _irqPhysS, unsigned _irqPhysNS,
+ unsigned _irqVirt, unsigned _irqHyp)
+ : irqPhysS(*parent.gic, _irqPhysS, cpu),
+ irqPhysNS(*parent.gic, _irqPhysNS, cpu),
irqVirt(*parent.gic, _irqVirt, cpu),
+ irqHyp(*parent.gic, _irqHyp, cpu),
+ physS(csprintf("%s.phys_s_timer%d", parent.name(), cpu),
+ system, parent, parent.systemCounter,
+ irqPhysS),
// This should really be phys_timerN, but we are stuck with
// arch_timer for backwards compatibility.
- phys(csprintf("%s.arch_timer%d", parent.name(), cpu),
- system, parent, parent.systemCounter,
- irqPhys),
+ physNS(csprintf("%s.arch_timer%d", parent.name(), cpu),
+ system, parent, parent.systemCounter,
+ irqPhysNS),
virt(csprintf("%s.virt_timer%d", parent.name(), cpu),
system, parent, parent.systemCounter,
- irqVirt)
+ irqVirt),
+ hyp(csprintf("%s.hyp_timer%d", parent.name(), cpu),
+ system, parent, parent.systemCounter,
+ irqHyp)
{}
- ArchTimer::Interrupt irqPhys;
+ ArchTimer::Interrupt irqPhysS;
+ ArchTimer::Interrupt irqPhysNS;
ArchTimer::Interrupt irqVirt;
+ ArchTimer::Interrupt irqHyp;
- ArchTimerKvm phys;
+ ArchTimerKvm physS;
+ ArchTimerKvm physNS;
ArchTimerKvm virt;
+ ArchTimerKvm hyp;
private:
// Disable copying
/// Pointer to the GIC, needed to trigger timer interrupts.
BaseGic *const gic;
- /// Physical timer interrupt
- const unsigned irqPhys;
+ /// Physical timer interrupt (S)
+ const unsigned irqPhysS;
+ /// Physical timer interrupt (NS)
+ const unsigned irqPhysNS;
/// Virtual timer interrupt
const unsigned irqVirt;
+
+ /// Hypervisor timer interrupt
+ const unsigned irqHyp;
};
class GenericTimerISA : public ArmISA::BaseISADevice