summaryrefslogtreecommitdiff
path: root/src/dev/arm/gic_pl390.cc
diff options
context:
space:
mode:
authorCurtis Dunham <Curtis.Dunham@arm.com>2017-03-09 17:30:59 +0000
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-04-03 16:51:46 +0000
commit60075068ea6340e89a4b0cd4bd79c6ee3de44893 (patch)
tree391663eba868150dfb0baa3c823c1852af99fcdb /src/dev/arm/gic_pl390.cc
parent2f14baaabca315e078597e3441bf8cf3dc703264 (diff)
downloadgem5-60075068ea6340e89a4b0cd4bd79c6ee3de44893.tar.xz
arm, dev: add basic support for GICC_BPR register
The Binary Point Register (BPR) specifies which bits belong to the group priority field (which are used for preemption) and which to the subpriority field (which are ignored for preemption). Change-Id: If51e669d23b49047b69b82ab363dd01a936cc93b Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2443 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Weiping Liao <weipingliao@google.com>
Diffstat (limited to 'src/dev/arm/gic_pl390.cc')
-rw-r--r--src/dev/arm/gic_pl390.cc26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/dev/arm/gic_pl390.cc b/src/dev/arm/gic_pl390.cc
index e7f3e32ef..c114604ab 100644
--- a/src/dev/arm/gic_pl390.cc
+++ b/src/dev/arm/gic_pl390.cc
@@ -83,7 +83,7 @@ Pl390::Pl390(const Params *p)
iccrpr[x] = 0xff;
cpuEnabled[x] = false;
cpuPriority[x] = 0xff;
- cpuBpr[x] = 0;
+ cpuBpr[x] = GICC_BPR_MINIMUM;
// Initialize cpu highest int
cpuHighestInt[x] = SPURIOUS_INT;
postIntEvent[x] = new PostIntEvent(*this, x);
@@ -538,9 +538,13 @@ Pl390::writeCpu(ContextID ctx, Addr daddr, uint32_t data)
case GICC_PMR:
cpuPriority[ctx] = data;
break;
- case GICC_BPR:
- cpuBpr[ctx] = data;
+ case GICC_BPR: {
+ auto bpr = data & 0x7;
+ if (bpr < GICC_BPR_MINIMUM)
+ bpr = GICC_BPR_MINIMUM;
+ cpuBpr[ctx] = bpr;
break;
+ }
case GICC_EOIR: {
const IAR iar = data;
if (iar.ack_id < SGI_MAX) {
@@ -666,6 +670,17 @@ Pl390::genSwiMask(int cpu)
return ULL(0x0101010101010101) << cpu;
}
+uint8_t
+Pl390::getCpuPriority(unsigned cpu)
+{
+ // see Table 3-2 in IHI0048B.b (GICv2)
+ // mask some low-order priority bits per BPR value
+ // NB: the GIC prioritization scheme is upside down:
+ // lower values are higher priority; masking off bits
+ // actually creates a higher priority, not lower.
+ return cpuPriority[cpu] & (0xff00 >> (7 - cpuBpr[cpu]));
+}
+
void
Pl390::updateIntState(int hint)
{
@@ -676,7 +691,7 @@ Pl390::updateIntState(int hint)
/*@todo use hint to do less work. */
int highest_int = SPURIOUS_INT;
// Priorities below that set in GICC_PMR can be ignored
- uint8_t highest_pri = cpuPriority[cpu];
+ uint8_t highest_pri = getCpuPriority(cpu);
// Check SGIs
for (int swi = 0; swi < SGI_MAX; swi++) {
@@ -733,7 +748,8 @@ Pl390::updateIntState(int hint)
/* @todo make this work for more than one cpu, need to handle 1:N, N:N
* models */
- if (enabled && cpuEnabled[cpu] && (highest_pri < cpuPriority[cpu]) &&
+ if (enabled && cpuEnabled[cpu] &&
+ (highest_pri < getCpuPriority(cpu)) &&
!(getActiveInt(cpu, intNumToWord(highest_int))
& (1 << intNumToBit(highest_int)))) {