Hello Curtis Dunham,

I'd like you to do a code review. Please visit

    https://gem5-review.googlesource.com/10023

to review the following change.


Change subject: dev, arm: Add support for HYP & secure timers
......................................................................

dev, arm: Add support for HYP & secure timers

Change-Id: I1a4849283f9bd5b1856e1378f7cefc33fc14eebd
Signed-off-by: Andreas Sandberg <andreas.sandb...@arm.com>
Reviewed-by: Curtis Dunham <curtis.dun...@arm.com>
---
M src/arch/arm/miscregs.cc
M src/dev/arm/RealView.py
M src/dev/arm/generic_timer.cc
M src/dev/arm/generic_timer.hh
4 files changed, 131 insertions(+), 85 deletions(-)



diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index 81ce43e..3e2bcc4 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -3170,7 +3170,6 @@
       .privSecure(!aarch32EL3)
       .monSecure(0);
     InitReg(MISCREG_CNTP_TVAL_S)
-      .unimplemented()
       .bankedChild()
       .secure().user(1);
     InitReg(MISCREG_CNTP_CTL)
@@ -3181,7 +3180,6 @@
       .privSecure(!aarch32EL3)
       .monSecure(0);
     InitReg(MISCREG_CNTP_CTL_S)
-      .unimplemented()
       .bankedChild()
       .secure().user(1);
     InitReg(MISCREG_CNTV_TVAL)
@@ -3189,13 +3187,10 @@
     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()
@@ -3250,7 +3245,6 @@
       .privSecure(!aarch32EL3)
       .monSecure(0);
     InitReg(MISCREG_CNTP_CVAL_S)
-      .unimplemented()
       .bankedChild()
       .secure().user(1);
     InitReg(MISCREG_CNTV_CVAL)
@@ -3258,7 +3252,6 @@
     InitReg(MISCREG_CNTVOFF)
       .hyp().monNonSecure();
     InitReg(MISCREG_CNTHP_CVAL)
-      .unimplemented()
       .hypWrite().monNonSecureRead();
     InitReg(MISCREG_CPUMERRSR)
       .unimplemented()
@@ -3915,31 +3908,23 @@
       .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)
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
index 9b91f46..308de18 100644
--- a/src/dev/arm/RealView.py
+++ b/src/dev/arm/RealView.py
@@ -418,10 +418,10 @@
     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")
@@ -429,9 +429,12 @@
         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))

@@ -900,7 +903,8 @@
         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)
@@ -1118,7 +1122,8 @@
         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)
diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc
index 73e4f91..1d5e8bb 100644
--- a/src/dev/arm/generic_timer.cc
+++ b/src/dev/arm/generic_timer.cc
@@ -69,6 +69,7 @@
 SystemCounter::serialize(CheckpointOut &cp) const
 {
     SERIALIZE_SCALAR(_regCntkctl);
+    SERIALIZE_SCALAR(_regCnthctl);
     SERIALIZE_SCALAR(_freq);
     SERIALIZE_SCALAR(_period);
     SERIALIZE_SCALAR(_resetTick);
@@ -81,6 +82,8 @@
     // 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 @@
     : 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 @@

         // 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 @@
         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 @@
     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 @@
         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 @@
         core.virt.setControl(val);
         return;

-      // PL1 phys. timer, secure
+      // Physical timer (S)
       case MISCREG_CNTP_CTL_S:
-      case MISCREG_CNTPS_CVAL_EL1:
-      case MISCREG_CNTPS_TVAL_EL1:
       case MISCREG_CNTPS_CTL_EL1:
-        M5_FALLTHROUGH;
+        core.physS.setControl(val);
+        return;

-      // PL2 phys. timer, non-secure
-      case MISCREG_CNTHCTL:
-      case MISCREG_CNTHCTL_EL2:
-      case MISCREG_CNTHP_CVAL:
-      case MISCREG_CNTHP_CVAL_EL2:
-      case MISCREG_CNTHP_TVAL:
-      case MISCREG_CNTHP_TVAL_EL2:
+      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:
+        core.physS.setTimerValue(val);
+        return;
+
+      // Hyp phys. timer, non-secure
       case MISCREG_CNTHP_CTL:
       case MISCREG_CNTHP_CTL_EL2:
-        warn("Writing to unimplemented register: %s\n",
-             miscRegName[reg]);
+        core.hyp.setControl(val);
+        return;
+
+      case MISCREG_CNTHP_CVAL:
+      case MISCREG_CNTHP_CVAL_EL2:
+        core.hyp.setCompareValue(val);
+        return;
+
+      case MISCREG_CNTHP_TVAL:
+      case MISCREG_CNTHP_TVAL_EL2:
+        core.hyp.setTimerValue(val);
         return;

       default:
@@ -421,23 +445,26 @@
       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 @@

       // PL1 phys. timer, secure
       case MISCREG_CNTP_CTL_S:
-      case MISCREG_CNTPS_CVAL_EL1:
-      case MISCREG_CNTPS_TVAL_EL1:
       case MISCREG_CNTPS_CTL_EL1:
-        M5_FALLTHROUGH;
+        return core.physS.control();

-      // PL2 phys. timer, non-secure
-      case MISCREG_CNTHCTL:
-      case MISCREG_CNTHCTL_EL2:
-      case MISCREG_CNTHP_CVAL:
-      case MISCREG_CNTHP_CVAL_EL2:
-      case MISCREG_CNTHP_TVAL:
-      case MISCREG_CNTHP_TVAL_EL2:
+      case MISCREG_CNTP_CVAL_S:
+      case MISCREG_CNTPS_CVAL_EL1:
+        return core.physS.compareValue();
+
+      case MISCREG_CNTP_TVAL_S:
+      case MISCREG_CNTPS_TVAL_EL1:
+        return core.physS.timerValue();
+
+      // HYP phys. timer (NS)
       case MISCREG_CNTHP_CTL:
       case MISCREG_CNTHP_CTL_EL2:
-        warn("Reading from unimplemented register: %s\n",
-             miscRegName[reg]);
-        return 0;
+        return core.hyp.control();

+      case MISCREG_CNTHP_CVAL:
+      case MISCREG_CNTHP_CVAL_EL2:
+        return core.hyp.compareValue();
+
+      case MISCREG_CNTHP_TVAL:
+      case MISCREG_CNTHP_TVAL_EL2:
+        return core.hyp.timerValue();

       default:
         warn("Reading from unknown register: %s\n", miscRegName[reg]);
diff --git a/src/dev/arm/generic_timer.hh b/src/dev/arm/generic_timer.hh
index c9cfb74..2c57765 100644
--- a/src/dev/arm/generic_timer.hh
+++ b/src/dev/arm/generic_timer.hh
@@ -69,7 +69,10 @@
     /// 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();
@@ -94,6 +97,9 @@
     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;

@@ -241,24 +247,37 @@
   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
@@ -281,11 +300,16 @@
     /// 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

--
To view, visit https://gem5-review.googlesource.com/10023
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I1a4849283f9bd5b1856e1378f7cefc33fc14eebd
Gerrit-Change-Number: 10023
Gerrit-PatchSet: 1
Gerrit-Owner: Andreas Sandberg <andreas.sandb...@arm.com>
Gerrit-Reviewer: Curtis Dunham <curtis.dun...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to