[gem5-dev] Change in gem5/gem5[develop]: dev-arm: Implement Level Sensitive PPIs in GICv2

2020-07-11 Thread Giacomo Travaglini (Gerrit) via gem5-dev
Giacomo Travaglini has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/31056 )


Change subject: dev-arm: Implement Level Sensitive PPIs in GICv2
..

dev-arm: Implement Level Sensitive PPIs in GICv2

JIRA: https://gem5.atlassian.net/browse/GEM5-667

Change-Id: I9ae40f08f4a1de95469ff5ed6788354abafc
Signed-off-by: Giacomo Travaglini 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31056
Reviewed-by: Hsuan Hsu 
Reviewed-by: Andreas Sandberg 
Maintainer: Andreas Sandberg 
Tested-by: kokoro 
---
M src/dev/arm/gic_v2.cc
M src/dev/arm/gic_v2.hh
2 files changed, 38 insertions(+), 13 deletions(-)

Approvals:
  Andreas Sandberg: Looks good to me, approved; Looks good to me, approved
  Hsuan Hsu: Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/dev/arm/gic_v2.cc b/src/dev/arm/gic_v2.cc
index 302da2f..1a6954d 100644
--- a/src/dev/arm/gic_v2.cc
+++ b/src/dev/arm/gic_v2.cc
@@ -343,7 +343,9 @@
 uint32_t int_num = 1 << (cpuHighestInt[ctx] - SGI_MAX);
 cpuPpiActive[ctx] |= int_num;
 updateRunPri();
-cpuPpiPending[ctx] &= ~int_num;
+if (!isLevelSensitive(ctx, active_int)) {
+cpuPpiPending[ctx] &= ~int_num;
+}

 } else {
 uint32_t int_num = 1 << intNumToBit(cpuHighestInt[ctx]);
@@ -518,7 +520,10 @@

 if (GICD_ICFGR.contains(daddr)) {
 uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2;
-getIntConfig(ctx, ix) = data;
+// Since the GICD_ICFGR0 is RO (WI), we are discarding the write
+// if ix = 0
+if (ix != 0)
+getIntConfig(ctx, ix) = data;
 if (data & NN_CONFIG_MASK)
 warn("GIC N:N mode selected and not supported at this time\n");
 return;
@@ -897,10 +902,16 @@
 void
 GicV2::clearPPInt(uint32_t num, uint32_t cpu)
 {
-DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
-num, cpu);
-cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
-updateIntState(intNumToWord(num));
+if (isLevelSensitive(cpu, num)) {
+DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
+num, cpu);
+cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
+updateIntState(intNumToWord(num));
+} else {
+/* Nothing to do :
+ * Edge-triggered interrupt remain pending until software
+ * writes GICD_ICPENDR or reads GICC_IAR */
+}
 }

 void
@@ -989,7 +1000,7 @@
 SERIALIZE_ARRAY(iccrpr, CPU_MAX);
 SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
 SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
-SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
+SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2 - 2);
 SERIALIZE_ARRAY(cpuControl, CPU_MAX);
 SERIALIZE_ARRAY(cpuPriority, CPU_MAX);
 SERIALIZE_ARRAY(cpuBpr, CPU_MAX);
@@ -1016,6 +1027,7 @@
 SERIALIZE_SCALAR(pendingInt);
 SERIALIZE_SCALAR(activeInt);
 SERIALIZE_SCALAR(intGroup);
+SERIALIZE_ARRAY(intConfig, 2);
 SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
 }

@@ -1033,7 +1045,7 @@
 UNSERIALIZE_ARRAY(iccrpr, CPU_MAX);
 UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
 UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
-UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
+UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2 - 2);
 UNSERIALIZE_ARRAY(cpuControl, CPU_MAX);
 UNSERIALIZE_ARRAY(cpuPriority, CPU_MAX);
 UNSERIALIZE_ARRAY(cpuBpr, CPU_MAX);
@@ -1075,6 +1087,7 @@
 UNSERIALIZE_SCALAR(pendingInt);
 UNSERIALIZE_SCALAR(activeInt);
 UNSERIALIZE_SCALAR(intGroup);
+UNSERIALIZE_ARRAY(intConfig, 2);
 UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
 }

diff --git a/src/dev/arm/gic_v2.hh b/src/dev/arm/gic_v2.hh
index aefa938..54c95f9 100644
--- a/src/dev/arm/gic_v2.hh
+++ b/src/dev/arm/gic_v2.hh
@@ -192,6 +192,10 @@
  * interrupt group bits for first 32 interrupts, 1b per interrupt  
*/

 uint32_t intGroup;

+/** GICD_ICFGR0, GICD_ICFGR1
+ * interrupt config bits for first 32 interrupts, 2b per interrupt  
*/

+uint32_t intConfig[2];
+
 /** GICD_IPRIORITYR{0..7}
  * interrupt priority for SGIs and PPIs */
 uint8_t intPriority[SGI_MAX + PPI_MAX];
@@ -201,7 +205,7 @@

 BankedRegs() :
 intEnabled(0), pendingInt(0), activeInt(0),
-intGroup(0), intPriority {0}
+intGroup(0), intConfig {0}, intPriority {0}
   {}
 };
 std::vector bankedRegs;
@@ -281,18 +285,26 @@
 }
 }

-/** 2 bit per interrupt signaling if it's level or edge sensitive
+/**
+ * GICD_ICFGR{2...63}
+ * 2 bit per interrupt signaling if it's level or edge sensitive
  * and if it is 1:N or N:N */
-uint32_t intConfig[INT_BITS_MAX*2];
+uint32_t intConfig[INT_BITS_MAX*2 - 2];


[gem5-dev] Change in gem5/gem5[develop]: dev-arm: Implement Level Sensitive PPIs in GICv2

2020-07-08 Thread Giacomo Travaglini (Gerrit) via gem5-dev
Giacomo Travaglini has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/31056 )



Change subject: dev-arm: Implement Level Sensitive PPIs in GICv2
..

dev-arm: Implement Level Sensitive PPIs in GICv2

JIRA: https://gem5.atlassian.net/browse/GEM5-667

Change-Id: I9ae40f08f4a1de95469ff5ed6788354abafc
Signed-off-by: Giacomo Travaglini 
---
M src/dev/arm/gic_v2.cc
M src/dev/arm/gic_v2.hh
2 files changed, 38 insertions(+), 13 deletions(-)



diff --git a/src/dev/arm/gic_v2.cc b/src/dev/arm/gic_v2.cc
index 302da2f..1a6954d 100644
--- a/src/dev/arm/gic_v2.cc
+++ b/src/dev/arm/gic_v2.cc
@@ -343,7 +343,9 @@
 uint32_t int_num = 1 << (cpuHighestInt[ctx] - SGI_MAX);
 cpuPpiActive[ctx] |= int_num;
 updateRunPri();
-cpuPpiPending[ctx] &= ~int_num;
+if (!isLevelSensitive(ctx, active_int)) {
+cpuPpiPending[ctx] &= ~int_num;
+}

 } else {
 uint32_t int_num = 1 << intNumToBit(cpuHighestInt[ctx]);
@@ -518,7 +520,10 @@

 if (GICD_ICFGR.contains(daddr)) {
 uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2;
-getIntConfig(ctx, ix) = data;
+// Since the GICD_ICFGR0 is RO (WI), we are discarding the write
+// if ix = 0
+if (ix != 0)
+getIntConfig(ctx, ix) = data;
 if (data & NN_CONFIG_MASK)
 warn("GIC N:N mode selected and not supported at this time\n");
 return;
@@ -897,10 +902,16 @@
 void
 GicV2::clearPPInt(uint32_t num, uint32_t cpu)
 {
-DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
-num, cpu);
-cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
-updateIntState(intNumToWord(num));
+if (isLevelSensitive(cpu, num)) {
+DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
+num, cpu);
+cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
+updateIntState(intNumToWord(num));
+} else {
+/* Nothing to do :
+ * Edge-triggered interrupt remain pending until software
+ * writes GICD_ICPENDR or reads GICC_IAR */
+}
 }

 void
@@ -989,7 +1000,7 @@
 SERIALIZE_ARRAY(iccrpr, CPU_MAX);
 SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
 SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
-SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
+SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2 - 2);
 SERIALIZE_ARRAY(cpuControl, CPU_MAX);
 SERIALIZE_ARRAY(cpuPriority, CPU_MAX);
 SERIALIZE_ARRAY(cpuBpr, CPU_MAX);
@@ -1016,6 +1027,7 @@
 SERIALIZE_SCALAR(pendingInt);
 SERIALIZE_SCALAR(activeInt);
 SERIALIZE_SCALAR(intGroup);
+SERIALIZE_ARRAY(intConfig, 2);
 SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
 }

@@ -1033,7 +1045,7 @@
 UNSERIALIZE_ARRAY(iccrpr, CPU_MAX);
 UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
 UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
-UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
+UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2 - 2);
 UNSERIALIZE_ARRAY(cpuControl, CPU_MAX);
 UNSERIALIZE_ARRAY(cpuPriority, CPU_MAX);
 UNSERIALIZE_ARRAY(cpuBpr, CPU_MAX);
@@ -1075,6 +1087,7 @@
 UNSERIALIZE_SCALAR(pendingInt);
 UNSERIALIZE_SCALAR(activeInt);
 UNSERIALIZE_SCALAR(intGroup);
+UNSERIALIZE_ARRAY(intConfig, 2);
 UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
 }

diff --git a/src/dev/arm/gic_v2.hh b/src/dev/arm/gic_v2.hh
index aefa938..54c95f9 100644
--- a/src/dev/arm/gic_v2.hh
+++ b/src/dev/arm/gic_v2.hh
@@ -192,6 +192,10 @@
  * interrupt group bits for first 32 interrupts, 1b per interrupt  
*/

 uint32_t intGroup;

+/** GICD_ICFGR0, GICD_ICFGR1
+ * interrupt config bits for first 32 interrupts, 2b per interrupt  
*/

+uint32_t intConfig[2];
+
 /** GICD_IPRIORITYR{0..7}
  * interrupt priority for SGIs and PPIs */
 uint8_t intPriority[SGI_MAX + PPI_MAX];
@@ -201,7 +205,7 @@

 BankedRegs() :
 intEnabled(0), pendingInt(0), activeInt(0),
-intGroup(0), intPriority {0}
+intGroup(0), intConfig {0}, intPriority {0}
   {}
 };
 std::vector bankedRegs;
@@ -281,18 +285,26 @@
 }
 }

-/** 2 bit per interrupt signaling if it's level or edge sensitive
+/**
+ * GICD_ICFGR{2...63}
+ * 2 bit per interrupt signaling if it's level or edge sensitive
  * and if it is 1:N or N:N */
-uint32_t intConfig[INT_BITS_MAX*2];
+uint32_t intConfig[INT_BITS_MAX*2 - 2];

-/** GICD_ICFGRn
+/**
+ * Reads the GICD_ICFGRn register.
  * @param ctx context id (PE specific)
  * @param ix interrupt word index
  * @returns the interrupt config word
  */
 uint32_t& getIntConfig(ContextID ctx, uint32_t ix) {
 assert(ix < INT_BITS_MAX*2);
-return