dev-arm: Initialize GICD_TYPER once at construction time

Change-Id: Ib4dfdf7005709c22b4ba95099b1192f6edd6ff06
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20635
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/dev/arm/gic_v3_distributor.cc b/src/dev/arm/gic_v3_distributor.cc
index d007fb3..4f80d02 100644
--- a/src/dev/arm/gic_v3_distributor.cc
+++ b/src/dev/arm/gic_v3_distributor.cc
@@ -44,6 +44,7 @@
 
 #include <algorithm>
 
+#include "base/intmath.hh"
 #include "debug/GIC.hh"
 #include "dev/arm/gic_v3.hh"
 #include "dev/arm/gic_v3_cpu_interface.hh"
@@ -77,6 +78,7 @@
       irqGrpmod(it_lines),
       irqNsacr(it_lines),
       irqAffinityRouting(it_lines),
+      gicdTyper(0),
       gicdPidr0(0x92),
       gicdPidr1(0xb4),
       gicdPidr2(0x3b),
@@ -84,6 +86,37 @@
       gicdPidr4(0x44)
 {
     panic_if(it_lines > Gicv3::INTID_SECURE, "Invalid value for it_lines!");
+    /*
+     * RSS           [26]    == 1
+     * (The implementation does supports targeted SGIs with affinity
+     * level 0 values of 0 - 255)
+     * No1N          [25]    == 1
+     * (1 of N SPI interrupts are not supported)
+     * A3V           [24]    == 1
+     * (Supports nonzero values of Affinity level 3)
+     * IDbits        [23:19] == 0xf
+     * (The number of interrupt identifier bits supported, minus one)
+     * DVIS          [18]    == 0
+     * (The implementation does not support Direct Virtual LPI
+     * injection)
+     * LPIS          [17]    == 1
+     * (The implementation does not support LPIs)
+     * MBIS          [16]    == 1
+     * (The implementation supports message-based interrupts
+     * by writing to Distributor registers)
+     * SecurityExtn  [10]    == X
+     * (The GIC implementation supports two Security states)
+     * CPUNumber     [7:5]   == 0
+     * (since for us ARE is always 1 [(ARE = 0) == Gicv2 legacy])
+     * ITLinesNumber [4:0]   == N
+     * (MaxSPIIntId = 32 (N + 1) - 1)
+     */
+    int max_spi_int_id = itLines - 1;
+    int it_lines_number = divCeil(max_spi_int_id + 1, 32) - 1;
+    gicdTyper = (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) |
+        (1 << 17) | (1 << 16) |
+        ((gic->getSystem()->haveSecurity() ? 1 : 0) << 10) |
+        (it_lines_number << 0);
 }
 
 void
@@ -461,39 +494,7 @@
         }
 
       case GICD_TYPER: // Interrupt Controller Type Register
-        /*
-         * RSS           [26]    == 1
-         * (The implementation does supports targeted SGIs with affinity
-         * level 0 values of 0 - 255)
-         * No1N          [25]    == 1
-         * (1 of N SPI interrupts are not supported)
-         * A3V           [24]    == 1
-         * (Supports nonzero values of Affinity level 3)
-         * IDbits        [23:19] == 0xf
-         * (The number of interrupt identifier bits supported, minus one)
-         * DVIS          [18]    == 0
-         * (The implementation does not support Direct Virtual LPI
-         * injection)
-         * LPIS          [17]    == 1
-         * (The implementation does not support LPIs)
-         * MBIS          [16]    == 1
-         * (The implementation supports message-based interrupts
-         * by writing to Distributor registers)
-         * SecurityExtn  [10]    == X
-         * (The GIC implementation supports two Security states)
-         * CPUNumber     [7:5]   == 0
-         * (since for us ARE is always 1 [(ARE = 0) == Gicv2 legacy])
-         * ITLinesNumber [4:0]   == N
-         * (MaxSPIIntId = 32 (N + 1) - 1)
-         */
-        {
-            int max_spi_int_id = itLines - 1;
-            int it_lines_number = ceil((max_spi_int_id + 1) / 32.0) - 1;
-            return (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) |
-                (1 << 17) | (1 << 16) |
-                (gic->getSystem()->haveSecurity() << 10) |
-                (it_lines_number << 0);
-        }
+        return gicdTyper;
 
       case GICD_IIDR: // Implementer Identification Register
         //return 0x43b; // ARM JEP106 code (r0p0 GIC-500)
diff --git a/src/dev/arm/gic_v3_distributor.hh b/src/dev/arm/gic_v3_distributor.hh
index 61381ef..01201fd 100644
--- a/src/dev/arm/gic_v3_distributor.hh
+++ b/src/dev/arm/gic_v3_distributor.hh
@@ -160,6 +160,7 @@
     std::vector <uint8_t> irqNsacr;
     std::vector <IROUTER> irqAffinityRouting;
 
+    uint32_t gicdTyper;
     uint32_t gicdPidr0;
     uint32_t gicdPidr1;
     uint32_t gicdPidr2;