From f26867a0758d1ec80d1916459e3f9bfeea44754f Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 20 Nov 2023 15:36:03 -0800 Subject: [PATCH 01/13] mem-cache: Revert "Prefetchers Improvements" Reverts PR https://github.com/gem5/gem5/pull/564 Reverts commits: * 047a494c2be9ef2b1a6d493d60a152e53ce92171 * 2abd65c2707695dad735c4e383b1ce7c61158314 * 38045d7a252c46f5f57692e5eff5b18dd4fd2547 * 6416304e07a6bcbcf338d20f8852923f050afa70 * 8598764a0345ec4326061d94f917597b65e25c8f Change-Id: Id523acc1778c3f827637302a6465f5a9e539d6b5 --- src/mem/cache/Cache.py | 4 ++-- src/mem/cache/prefetch/Prefetcher.py | 9 +-------- src/mem/cache/prefetch/base.cc | 3 +-- src/mem/cache/prefetch/queued.cc | 4 ++-- src/mem/cache/prefetch/stride.cc | 19 +++++++++---------- src/mem/cache/prefetch/stride.hh | 4 +--- 6 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py index 501bb92682..d853a08cd9 100644 --- a/src/mem/cache/Cache.py +++ b/src/mem/cache/Cache.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2013, 2015, 2018, 2022 Arm Limited +# Copyright (c) 2012-2013, 2015, 2018 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -112,7 +112,7 @@ class BaseCache(ClockedObject): "Notify the hardware prefetcher on every access (not just misses)", ) prefetch_on_pf_hit = Param.Bool( - True, "Notify the hardware prefetcher on hit on prefetched lines" + False, "Notify the hardware prefetcher on hit on prefetched lines" ) tags = Param.BaseTags(BaseSetAssoc(), "Tag store") diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py index c15ef6539c..ecc67f4857 100644 --- a/src/mem/cache/prefetch/Prefetcher.py +++ b/src/mem/cache/prefetch/Prefetcher.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012, 2014, 2019, 2022 Arm Limited +# Copyright (c) 2012, 2014, 2019 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -192,13 +192,6 @@ class StridePrefetcher(QueuedPrefetcher): use_requestor_id = Param.Bool(True, "Use requestor id based history") degree = Param.Int(4, "Number of prefetches to generate") - distance = Param.Unsigned( - 0, - "How far ahead of the demand stream to start prefetching. " - "Skip this number of strides ahead of the first identified prefetch, " - "then generate `degree` prefetches at `stride` intervals. " - "A value of zero indicates no skip.", - ) table_assoc = Param.Int(4, "Associativity of the PC table") table_entries = Param.MemorySize("64", "Number of entries of the PC table") diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index 25c37df323..e3e4b24cf2 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2022 Arm Limited + * Copyright (c) 2013-2014 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -245,7 +245,6 @@ Base::probeNotify(const PacketPtr &pkt, bool miss) // operations or for writes that we are coaslescing. if (pkt->cmd.isSWPrefetch()) return; if (pkt->req->isCacheMaintenance()) return; - if (pkt->isCleanEviction()) return; if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return; if (!pkt->req->hasPaddr()) { panic("Request must have a physical address"); diff --git a/src/mem/cache/prefetch/queued.cc b/src/mem/cache/prefetch/queued.cc index c67c315dad..1ab34d2e9b 100644 --- a/src/mem/cache/prefetch/queued.cc +++ b/src/mem/cache/prefetch/queued.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, 2022 Arm Limited + * Copyright (c) 2014-2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -178,7 +178,7 @@ Queued::notify(const PacketPtr &pkt, const PrefetchInfo &pfi) if (queueSquash) { auto itr = pfq.begin(); while (itr != pfq.end()) { - if (blockAddress(itr->pfInfo.getAddr()) == blk_addr && + if (itr->pfInfo.getAddr() == blk_addr && itr->pfInfo.isSecure() == is_secure) { DPRINTF(HWPrefetch, "Removing pf candidate addr: %#x " "(cl: %#x), demand request going to the same addr\n", diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc index 4b709400c5..0a77b28a1c 100644 --- a/src/mem/cache/prefetch/stride.cc +++ b/src/mem/cache/prefetch/stride.cc @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 Inria - * Copyright (c) 2012-2013, 2015, 2022-2023 Arm Limited + * Copyright (c) 2012-2013, 2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -84,7 +84,6 @@ Stride::Stride(const StridePrefetcherParams &p) threshConf(p.confidence_threshold/100.0), useRequestorId(p.use_requestor_id), degree(p.degree), - distance(p.distance), pcTableInfo(p.table_assoc, p.table_entries, p.table_indexing_policy, p.table_replacement_policy) { @@ -168,16 +167,16 @@ Stride::calculatePrefetch(const PrefetchInfo &pfi, return; } - // Round strides up to atleast 1 cacheline - int prefetch_stride = new_stride; - if (abs(new_stride) < blkSize) { - prefetch_stride = (new_stride < 0) ? -blkSize : blkSize; - } - - Addr new_addr = pf_addr + distance * prefetch_stride; // Generate up to degree prefetches for (int d = 1; d <= degree; d++) { - addresses.push_back(AddrPriority(new_addr += prefetch_stride, 0)); + // Round strides up to atleast 1 cacheline + int prefetch_stride = new_stride; + if (abs(new_stride) < blkSize) { + prefetch_stride = (new_stride < 0) ? -blkSize : blkSize; + } + + Addr new_addr = pf_addr + d * prefetch_stride; + addresses.push_back(AddrPriority(new_addr, 0)); } } else { // Miss in table diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index 35ba4eed4e..7e55abea21 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 Inria - * Copyright (c) 2012-2013, 2015, 2022 Arm Limited + * Copyright (c) 2012-2013, 2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -105,8 +105,6 @@ class Stride : public Queued const int degree; - const int distance; - /** * Information used to create a new PC table. All of them behave equally. */ From 90b711e879f2031502102a3ed87beebaefa25731 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 13 Oct 2023 12:19:07 +0100 Subject: [PATCH 02/13] arch-arm: Define an ISR type register Change-Id: I358050a507fb76654e87165720dfb3b2ea6ca838 Signed-off-by: Giacomo Travaglini --- src/arch/arm/interrupts.hh | 2 +- src/arch/arm/regs/misc_types.hh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index c2a2d13a8d..25799a66ee 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -203,7 +203,7 @@ class Interrupts : public BaseInterrupts getISR(HCR hcr, CPSR cpsr, SCR scr) { bool useHcrMux; - CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR + ISR isr = 0; useHcrMux = (cpsr.mode != MODE_HYP) && !isSecure(tc); isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi) diff --git a/src/arch/arm/regs/misc_types.hh b/src/arch/arm/regs/misc_types.hh index 0e6bdc8fe3..3bc06ac97c 100644 --- a/src/arch/arm/regs/misc_types.hh +++ b/src/arch/arm/regs/misc_types.hh @@ -75,6 +75,12 @@ namespace ArmISA Bitfield<0> sp; // AArch64 EndBitUnion(CPSR) + BitUnion32(ISR) + Bitfield<8> a; + Bitfield<7> i; + Bitfield<6> f; + EndBitUnion(ISR) + BitUnion32(ISAR5) Bitfield<31, 28> vcma; Bitfield<27, 24> rdm; From 3d4133936665df7465936225165e07df7d7c83c0 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 16 Oct 2023 17:16:40 +0100 Subject: [PATCH 03/13] arch-arm: Fix ISR_EL1 register read in secure mode Vitual interrupts are enabled in secure mode as well after the introduction of FEAT_SEL2. Replacing the secure mode check with the EL2Enabled one Change-Id: Id685a05d5adfa87b2a366f6be42bf344168927d4 Signed-off-by: Giacomo Travaglini --- src/arch/arm/interrupts.hh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index 25799a66ee..436b064eb7 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013, 2016 ARM Limited + * Copyright (c) 2010, 2012-2013, 2016, 2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -202,15 +202,14 @@ class Interrupts : public BaseInterrupts uint32_t getISR(HCR hcr, CPSR cpsr, SCR scr) { - bool useHcrMux; + bool use_hcr_mux = currEL(cpsr) < EL2 && EL2Enabled(tc); ISR isr = 0; - useHcrMux = (cpsr.mode != MODE_HYP) && !isSecure(tc); - isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi) - : interrupts[INT_IRQ]; - isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf) - : interrupts[INT_FIQ]; - isr.a = (useHcrMux & hcr.amo) ? hcr.va : interrupts[INT_ABT]; + isr.i = (use_hcr_mux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi) + : interrupts[INT_IRQ]; + isr.f = (use_hcr_mux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf) + : interrupts[INT_FIQ]; + isr.a = (use_hcr_mux & hcr.amo) ? hcr.va : interrupts[INT_ABT]; return isr; } From bb323923f259323321545fc5716a00be5e9b6480 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 17 Oct 2023 10:52:21 +0100 Subject: [PATCH 04/13] arch-arm: Simplify get/checkInterrupts with takeVirtualInt With this patch we align virtual interrupts with respect to the physical ones by introducing a matching takeVirtualInt method. Change-Id: Ib7835a21b85e4330ba9f051bc8fed691d6e1382e Signed-off-by: Giacomo Travaglini --- src/arch/arm/interrupts.cc | 43 +++++++++++++++++++++++ src/arch/arm/interrupts.hh | 72 ++++++++++---------------------------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc index c2f1009147..1d1dc327fd 100644 --- a/src/arch/arm/interrupts.cc +++ b/src/arch/arm/interrupts.cc @@ -285,4 +285,47 @@ ArmISA::Interrupts::takeInt(InterruptTypes int_type) const } +bool +ArmISA::Interrupts::takeVirtualInt(InterruptTypes int_type) const +{ + CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); + HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); + + bool no_vhe = !HaveExt(tc, ArmExtension::FEAT_VHE); + bool amo, fmo, imo; + bool cpsr_mask_bit, hcr_mask_override_bit; + + if (hcr.tge == 1){ + amo = (no_vhe || hcr.e2h == 0); + fmo = (no_vhe || hcr.e2h == 0); + imo = (no_vhe || hcr.e2h == 0); + } else { + amo = hcr.amo; + fmo = hcr.fmo; + imo = hcr.imo; + } + + bool is_hyp_mode = currEL(tc) == EL2; + bool is_secure = ArmISA::isSecure(tc); + + switch(int_type) { + case INT_VIRT_FIQ: + cpsr_mask_bit = cpsr.f; + hcr_mask_override_bit = fmo; + break; + case INT_VIRT_IRQ: + cpsr_mask_bit = cpsr.i; + hcr_mask_override_bit = imo; + break; + case INT_VIRT_ABT: + cpsr_mask_bit = cpsr.a; + hcr_mask_override_bit = amo; + break; + default: + panic("Unhandled interrupt type!"); + } + return !cpsr_mask_bit && hcr_mask_override_bit && + !is_secure && !is_hyp_mode; +} + } // namespace gem5 diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index 436b064eb7..71325bee63 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -65,7 +65,11 @@ enum InterruptTypes INT_SEV, // Special interrupt for recieving SEV's INT_VIRT_IRQ, INT_VIRT_FIQ, - NumInterruptTypes + NumInterruptTypes, + // Cannot be raised by an external signal + // (for now) from the IC so we don't instantiate a + // interrupt entry in the state array + INT_VIRT_ABT }; class Interrupts : public BaseInterrupts @@ -132,6 +136,8 @@ class Interrupts : public BaseInterrupts bool takeInt32(InterruptTypes int_type) const; bool takeInt64(InterruptTypes int_type) const; + bool takeVirtualInt(InterruptTypes int_type) const; + bool checkInterrupts() const override { @@ -140,40 +146,19 @@ class Interrupts : public BaseInterrupts if (!(intStatus || hcr.va || hcr.vi || hcr.vf)) return false; - CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); - - bool no_vhe = !HaveExt(tc, ArmExtension::FEAT_VHE); - bool amo, fmo, imo; - if (hcr.tge == 1){ - amo = (no_vhe || hcr.e2h == 0); - fmo = (no_vhe || hcr.e2h == 0); - imo = (no_vhe || hcr.e2h == 0); - } else { - amo = hcr.amo; - fmo = hcr.fmo; - imo = hcr.imo; - } - - bool isHypMode = currEL(tc) == EL2; - bool isSecure = ArmISA::isSecure(tc); - bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode; - bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode; - bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode; - - if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) || - (hcr.va && allowVAbort)) ) - return false; - bool take_irq = takeInt(INT_IRQ); bool take_fiq = takeInt(INT_FIQ); bool take_ea = takeInt(INT_ABT); + bool take_virq = takeVirtualInt(INT_VIRT_IRQ); + bool take_vfiq = takeVirtualInt(INT_VIRT_FIQ); + bool take_vabt = takeVirtualInt(INT_VIRT_ABT); return ((interrupts[INT_IRQ] && take_irq) || (interrupts[INT_FIQ] && take_fiq) || (interrupts[INT_ABT] && take_ea) || - ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) || - ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) || - (hcr.va && allowVAbort) || + ((interrupts[INT_VIRT_IRQ] || hcr.vi) && take_virq) || + ((interrupts[INT_VIRT_FIQ] || hcr.vf) && take_vfiq) || + (hcr.va && take_vabt) || (interrupts[INT_RST]) || (interrupts[INT_SEV]) ); @@ -238,44 +223,25 @@ class Interrupts : public BaseInterrupts assert(checkInterrupts()); HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); - - bool no_vhe = !HaveExt(tc, ArmExtension::FEAT_VHE); - bool amo, fmo, imo; - if (hcr.tge == 1){ - amo = (no_vhe || hcr.e2h == 0); - fmo = (no_vhe || hcr.e2h == 0); - imo = (no_vhe || hcr.e2h == 0); - } else { - amo = hcr.amo; - fmo = hcr.fmo; - imo = hcr.imo; - } - - // Calculate a few temp vars so we can work out if there's a pending - // virtual interrupt, and if its allowed to happen - // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13 - bool isHypMode = currEL(tc) == EL2; - bool isSecure = ArmISA::isSecure(tc); - bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode; - bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode; - bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode; bool take_irq = takeInt(INT_IRQ); bool take_fiq = takeInt(INT_FIQ); bool take_ea = takeInt(INT_ABT); + bool take_virq = takeVirtualInt(INT_VIRT_IRQ); + bool take_vfiq = takeVirtualInt(INT_VIRT_FIQ); + bool take_vabt = takeVirtualInt(INT_VIRT_ABT); if (interrupts[INT_IRQ] && take_irq) return std::make_shared(); - if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq) + if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && take_virq) return std::make_shared(); if (interrupts[INT_FIQ] && take_fiq) return std::make_shared(); - if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq) + if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && take_vfiq) return std::make_shared(); if (interrupts[INT_ABT] && take_ea) return std::make_shared(); - if (hcr.va && allowVAbort) + if (hcr.va && take_vabt) return std::make_shared( 0, TlbEntry::DomainType::NoAccess, false, ArmFault::AsynchronousExternalAbort); From 49d07578de18e26ac7a49da05189ce54026caafe Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 17 Oct 2023 10:59:54 +0100 Subject: [PATCH 05/13] arch-arm: Call take(Virtual)Int only when needed There is no need to call the methods for every kind of interrupt. A pending one should short-circuit the remaining checks Change-Id: I2c9eb680a7baa4644745b8cbe48183ff6f8e3102 Signed-off-by: Giacomo Travaglini --- src/arch/arm/interrupts.hh | 44 +++++++++++++++----------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index 71325bee63..df6ffaa30c 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -146,20 +146,15 @@ class Interrupts : public BaseInterrupts if (!(intStatus || hcr.va || hcr.vi || hcr.vf)) return false; - bool take_irq = takeInt(INT_IRQ); - bool take_fiq = takeInt(INT_FIQ); - bool take_ea = takeInt(INT_ABT); - bool take_virq = takeVirtualInt(INT_VIRT_IRQ); - bool take_vfiq = takeVirtualInt(INT_VIRT_FIQ); - bool take_vabt = takeVirtualInt(INT_VIRT_ABT); - - return ((interrupts[INT_IRQ] && take_irq) || - (interrupts[INT_FIQ] && take_fiq) || - (interrupts[INT_ABT] && take_ea) || - ((interrupts[INT_VIRT_IRQ] || hcr.vi) && take_virq) || - ((interrupts[INT_VIRT_FIQ] || hcr.vf) && take_vfiq) || - (hcr.va && take_vabt) || - (interrupts[INT_RST]) || + return ((interrupts[INT_IRQ] && takeInt(INT_IRQ)) || + (interrupts[INT_FIQ] && takeInt(INT_FIQ)) || + (interrupts[INT_ABT] && takeInt(INT_ABT)) || + ((interrupts[INT_VIRT_IRQ] || hcr.vi) && + takeVirtualInt(INT_VIRT_IRQ)) || + ((interrupts[INT_VIRT_FIQ] || hcr.vf) && + takeVirtualInt(INT_VIRT_FIQ)) || + (hcr.va && takeVirtualInt(INT_VIRT_ABT)) || + (interrupts[INT_RST]) || (interrupts[INT_SEV]) ); } @@ -224,24 +219,19 @@ class Interrupts : public BaseInterrupts HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - bool take_irq = takeInt(INT_IRQ); - bool take_fiq = takeInt(INT_FIQ); - bool take_ea = takeInt(INT_ABT); - bool take_virq = takeVirtualInt(INT_VIRT_IRQ); - bool take_vfiq = takeVirtualInt(INT_VIRT_FIQ); - bool take_vabt = takeVirtualInt(INT_VIRT_ABT); - - if (interrupts[INT_IRQ] && take_irq) + if (interrupts[INT_IRQ] && takeInt(INT_IRQ)) return std::make_shared(); - if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && take_virq) + if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && + takeVirtualInt(INT_VIRT_IRQ)) return std::make_shared(); - if (interrupts[INT_FIQ] && take_fiq) + if (interrupts[INT_FIQ] && takeInt(INT_FIQ)) return std::make_shared(); - if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && take_vfiq) + if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && + takeVirtualInt(INT_VIRT_FIQ)) return std::make_shared(); - if (interrupts[INT_ABT] && take_ea) + if (interrupts[INT_ABT] && takeInt(INT_ABT)) return std::make_shared(); - if (hcr.va && take_vabt) + if (hcr.va && takeVirtualInt(INT_VIRT_ABT)) return std::make_shared( 0, TlbEntry::DomainType::NoAccess, false, ArmFault::AsynchronousExternalAbort); From b8fabc15d99d5058171554eaf4283edc491f79c0 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 17 Oct 2023 11:29:57 +0100 Subject: [PATCH 06/13] arch-arm: Revamp takeVirtualInt to take FEAT_SEL2 into account Similarly to the physical version [1], we rewrite the masking logic to account for FEAT_SEL2. The interrupt table is taken from the Arm architecture reference manual (version DDI 0487H.a, section D1.3.6, table R_BKHXL) [1]: https://github.com/gem5/gem5/pull/430 Change-Id: Icb6eb1944d8241293b3ef3c349b20f3981bcc558 Signed-off-by: Giacomo Travaglini --- src/arch/arm/interrupts.cc | 81 ++++++++++++++++++++++++++++++++++++++ src/arch/arm/interrupts.hh | 2 + 2 files changed, 83 insertions(+) diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc index 1d1dc327fd..8e8ee39da4 100644 --- a/src/arch/arm/interrupts.cc +++ b/src/arch/arm/interrupts.cc @@ -287,6 +287,14 @@ ArmISA::Interrupts::takeInt(InterruptTypes int_type) const bool ArmISA::Interrupts::takeVirtualInt(InterruptTypes int_type) const +{ + return ArmSystem::highestELIs64(tc) ? takeVirtualInt64(int_type) : + takeVirtualInt32(int_type); + +} + +bool +ArmISA::Interrupts::takeVirtualInt32(InterruptTypes int_type) const { CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); @@ -328,4 +336,77 @@ ArmISA::Interrupts::takeVirtualInt(InterruptTypes int_type) const !is_secure && !is_hyp_mode; } +bool +ArmISA::Interrupts::takeVirtualInt64(InterruptTypes int_type) const +{ + InterruptMask mask; + CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); + HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); + SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); + + ExceptionLevel el = currEL(tc); + bool cpsr_mask_bit, hcr_mask_override_bit; + bool is_secure = ArmISA::isSecureBelowEL3(tc); + + switch(int_type) { + case INT_VIRT_FIQ: + cpsr_mask_bit = cpsr.f; + hcr_mask_override_bit = hcr.fmo; + break; + case INT_VIRT_IRQ: + cpsr_mask_bit = cpsr.i; + hcr_mask_override_bit = hcr.imo; + break; + case INT_VIRT_ABT: + cpsr_mask_bit = cpsr.a; + hcr_mask_override_bit = hcr.amo; + break; + default: + panic("Unhandled interrupt type!"); + } + + if (is_secure) { + if (!scr.eel2) { + // NS=0,EEL2=0 + mask = INT_MASK_P; + } else { + if (!hcr.tge) { + if (!hcr_mask_override_bit) { + // NS=0,EEL2=1,TGE=0,AMO/IMO/FMO=0 + mask = INT_MASK_P; + } else { + // NS=0,EEL2=1,TGE=0,AMO/IMO/FMO=1 + if (el == EL2 || el == EL3) + mask = INT_MASK_P; + else + mask = INT_MASK_M; + } + } else { + // NS=0,EEL2=1,TGE=1 + mask = INT_MASK_P; + } + } + } else { + if (!hcr.tge) { + if (!hcr_mask_override_bit) { + // NS=1,TGE=0,AMO/IMO/FMO=0 + mask = INT_MASK_P; + } else { + // NS=1,TGE=0,AMO/IMO/FMO=1 + if (el == EL2 || el == EL3) + mask = INT_MASK_P; + else + mask = INT_MASK_M; + } + } else { + // NS=1,TGE=1 + mask = INT_MASK_P; + } + } + + return ((mask == INT_MASK_T) || + ((mask == INT_MASK_M) && !cpsr_mask_bit)) && + (mask != INT_MASK_P); +} + } // namespace gem5 diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index df6ffaa30c..da2a17206c 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -137,6 +137,8 @@ class Interrupts : public BaseInterrupts bool takeInt64(InterruptTypes int_type) const; bool takeVirtualInt(InterruptTypes int_type) const; + bool takeVirtualInt32(InterruptTypes int_type) const; + bool takeVirtualInt64(InterruptTypes int_type) const; bool checkInterrupts() const override From 098feb40427f3f3755b504fa4740219ba4743cc3 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 17 Oct 2023 15:54:49 +0100 Subject: [PATCH 07/13] arch-arm: Fix WFI sleeping in secure mode The CPU should not sleep with a pending virtual interrupt if secure mode EL2 is supported (FEAT_SEL2) Change-Id: Ib71c4a09d76a790331cf6750da45f83694946aee Signed-off-by: Giacomo Travaglini --- src/arch/arm/interrupts.hh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index da2a17206c..bddb932323 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -169,16 +169,16 @@ class Interrupts : public BaseInterrupts bool checkWfiWake(HCR hcr, CPSR cpsr, SCR scr) const { - uint64_t maskedIntStatus; - bool virtWake; + uint64_t masked_int_status; + bool virt_wake; - maskedIntStatus = intStatus & ~((1 << INT_VIRT_IRQ) | - (1 << INT_VIRT_FIQ)); - virtWake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo; - virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo; - virtWake |= hcr.va && hcr.amo; - virtWake &= (cpsr.mode != MODE_HYP) && !isSecure(tc); - return maskedIntStatus || virtWake; + masked_int_status = intStatus & ~((1 << INT_VIRT_IRQ) | + (1 << INT_VIRT_FIQ)); + virt_wake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo; + virt_wake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo; + virt_wake |= hcr.va && hcr.amo; + virt_wake &= currEL(cpsr) < EL2 && EL2Enabled(tc); + return masked_int_status || virt_wake; } uint32_t From cb61d01ededc4ef6d7297f6064b71ac0b198e020 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 20 Nov 2023 13:24:32 -0800 Subject: [PATCH 08/13] ext: Add 'cmake' dep check to DRAMSys install CMake is not required to build gem5. It is only required to build and link the optional DRAMSysm library. Therefore, if the DRAMSys repo has been cloned but CMake is not present this patch ensures no attempt at building or linking DRAMSysm is made. A warning is thrown inform the user of the missing CMake. Change-Id: I4d22e3a16655fd90f6b109b4e75859628f7d532d --- ext/dramsys/SConscript | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ext/dramsys/SConscript b/ext/dramsys/SConscript index 0cf163aede..bfe4ee5ec1 100644 --- a/ext/dramsys/SConscript +++ b/ext/dramsys/SConscript @@ -27,6 +27,10 @@ import os import subprocess +from shutil import which + +from gem5_scons import warning + Import("env") build_root = Dir("../..").abspath @@ -40,6 +44,16 @@ if not os.path.exists(Dir(".").srcnode().abspath + "/DRAMSys"): env["HAVE_DRAMSYS"] = False Return() +# DRAMSys requires CMake to build but this is is not a dependency for +# gem5 outside of this DRAMSys integration. Therefore, we do not fail the +# entire gem5 build if CMake is not found. Instead we just skip the building of +# DRAMSys and print a warning. +if which("cmake") is None: + warning("The DRAMSys repo is present but CMake cannot be found. " + "DRAMSys will not be built.") + env["HAVE_DRAMSYS"] = False + Return() + env["HAVE_DRAMSYS"] = True subprocess.run( From 575114b63b39e1b102eb58fcdc72ed2277466784 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 20 Nov 2023 13:31:42 -0800 Subject: [PATCH 09/13] ext: Add .gitignore to ext/dramsys Change-Id: Ifc1a3c77b56cbe5777d041a88b2c0d5cb77eaf89 --- ext/dramsys/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 ext/dramsys/.gitignore diff --git a/ext/dramsys/.gitignore b/ext/dramsys/.gitignore new file mode 100644 index 0000000000..0193b6e8f3 --- /dev/null +++ b/ext/dramsys/.gitignore @@ -0,0 +1 @@ +DRAMSys From 8f9a3286529a81903ed4434e85d791e1aac69775 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 20 Nov 2023 13:32:10 -0800 Subject: [PATCH 10/13] util-docker: Add 'cmake' to all-deps 'cmake' is required to build DRAMSysm. This is an optional dependency for compiling DRAMSys. It is therefore not required. It is included in the "all-dependencies" Docker images as they may be needed if DRAMSys is desired. Change-Id: I1a3e1a6fa2da4d0116d423e9267d4d3095000d4e --- util/dockerfiles/ubuntu-20.04_all-dependencies/Dockerfile | 2 +- util/dockerfiles/ubuntu-22.04_all-dependencies/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/util/dockerfiles/ubuntu-20.04_all-dependencies/Dockerfile b/util/dockerfiles/ubuntu-20.04_all-dependencies/Dockerfile index 8f092adc7a..ba3d554c3b 100644 --- a/util/dockerfiles/ubuntu-20.04_all-dependencies/Dockerfile +++ b/util/dockerfiles/ubuntu-20.04_all-dependencies/Dockerfile @@ -32,7 +32,7 @@ RUN apt -y update && apt -y upgrade && \ libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev \ python3-dev python-is-python3 doxygen libboost-all-dev \ libhdf5-serial-dev python3-pydot libpng-dev libelf-dev pkg-config pip \ - python3-venv black gcc-10 g++-10 + python3-venv black gcc-10 g++-10 cmake RUN pip install mypy pre-commit diff --git a/util/dockerfiles/ubuntu-22.04_all-dependencies/Dockerfile b/util/dockerfiles/ubuntu-22.04_all-dependencies/Dockerfile index 9e2580e642..679248a081 100644 --- a/util/dockerfiles/ubuntu-22.04_all-dependencies/Dockerfile +++ b/util/dockerfiles/ubuntu-22.04_all-dependencies/Dockerfile @@ -31,6 +31,6 @@ RUN apt -y update && apt -y upgrade && \ apt -y install build-essential git m4 scons zlib1g zlib1g-dev \ libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev \ python3-dev doxygen libboost-all-dev libhdf5-serial-dev python3-pydot \ - libpng-dev libelf-dev pkg-config pip python3-venv black + libpng-dev libelf-dev pkg-config pip python3-venv black cmake RUN pip install mypy pre-commit From 36e83943b594c829e2f3d97e709fab30516a6bd4 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 20 Nov 2023 13:35:19 -0800 Subject: [PATCH 11/13] tests,misc: Update DRAMSys test clone command This clone is updated to reflect the new advice given in ext/dramasys/README that was introduced in PR https://github.com/gem5/gem5/pull/525 to upgrade DRAMSysm to v5.0. Change-Id: I868619ecc1a44298dd3885e5719979bdaa24e9c2 --- .github/workflows/weekly-tests.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/weekly-tests.yaml b/.github/workflows/weekly-tests.yaml index 72b1454a5e..6c211435c2 100644 --- a/.github/workflows/weekly-tests.yaml +++ b/.github/workflows/weekly-tests.yaml @@ -89,11 +89,7 @@ jobs: - name: Checkout DRAMSys working-directory: ${{ github.workspace }}/ext/dramsys - run: | - git clone https://github.com/tukl-msd/DRAMSys DRAMSys - cd DRAMSys - git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f - git submodule update --init --recursive + run: git clone https://github.com/tukl-msd/DRAMSys --branch v5.0 --depth 1 DRAMSys # gem5 is built separately because it depends on the DRAMSys library - name: Build gem5 From cc9f81b08a0493d82a10145f15d36f9453e3625b Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Sun, 26 Nov 2023 23:22:01 -0800 Subject: [PATCH 12/13] arch-vega,arch-gcn3: Bugfix V_PERM_B32 and V_OR3_B32 (#599) The V_PERM_B32 instruction is selecting the correct byte, but is shifting into place moving by bits instead of bytes. The V_OR3_B32 instruction is calling the wrong instruction implementation in the decoder. This patch fixes both issues plus a bonus fix for GCN3's V_PERM_B32. (GCN3 does not have V_OR3_B32). Change-Id: Ied66c43981bc4236f680db42a9868f760becc284 --- src/arch/amdgpu/gcn3/insts/instructions.cc | 2 +- src/arch/amdgpu/vega/decoder.cc | 2 +- src/arch/amdgpu/vega/insts/instructions.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arch/amdgpu/gcn3/insts/instructions.cc b/src/arch/amdgpu/gcn3/insts/instructions.cc index 478b1d38d0..b9d29a2204 100644 --- a/src/arch/amdgpu/gcn3/insts/instructions.cc +++ b/src/arch/amdgpu/gcn3/insts/instructions.cc @@ -29692,7 +29692,7 @@ namespace Gcn3ISA for (int i = 0; i < 4 ; ++i) { VecElemU32 permuted_val = permute(selector, 0xFF & ((VecElemU32)src2[lane] >> (8 * i))); - vdst[lane] |= (permuted_val << i); + vdst[lane] |= (permuted_val << (8 * i)); } DPRINTF(GCN3, "v_perm result: 0x%08x\n", vdst[lane]); diff --git a/src/arch/amdgpu/vega/decoder.cc b/src/arch/amdgpu/vega/decoder.cc index a86dd668ec..065f8c8493 100644 --- a/src/arch/amdgpu/vega/decoder.cc +++ b/src/arch/amdgpu/vega/decoder.cc @@ -7020,7 +7020,7 @@ namespace VegaISA GPUStaticInst* Decoder::decode_OPU_VOP3__V_OR3_B32(MachInst iFmt) { - return new Inst_VOP3__V_OR_B32(&iFmt->iFmt_VOP3A); + return new Inst_VOP3__V_OR3_B32(&iFmt->iFmt_VOP3A); } GPUStaticInst* diff --git a/src/arch/amdgpu/vega/insts/instructions.cc b/src/arch/amdgpu/vega/insts/instructions.cc index 74b6abee62..cd4ad74e6e 100644 --- a/src/arch/amdgpu/vega/insts/instructions.cc +++ b/src/arch/amdgpu/vega/insts/instructions.cc @@ -32671,7 +32671,7 @@ namespace VegaISA for (int i = 0; i < 4 ; ++i) { VecElemU32 permuted_val = permute(selector, 0xFF & ((VecElemU32)src2[lane] >> (8 * i))); - vdst[lane] |= (permuted_val << i); + vdst[lane] |= (permuted_val << (8 * i)); } DPRINTF(VEGA, "v_perm result: 0x%08x\n", vdst[lane]); From 1de992bc757e59c592df13e94c9299d3544330ff Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Nov 2023 07:42:59 -0800 Subject: [PATCH 13/13] tests: fix lulesh (#600) - fixed the broken command that was causing lulesh to fail the run Change-Id: I4e8a310f153d86deb8829f41b5ddd0c317df23cb --- .github/workflows/gpu-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gpu-tests.yaml b/.github/workflows/gpu-tests.yaml index b390e0750f..7edcab5ba5 100644 --- a/.github/workflows/gpu-tests.yaml +++ b/.github/workflows/gpu-tests.yaml @@ -61,7 +61,7 @@ jobs: working-directory: ${{ github.workspace }} run: | build/GCN3_X86/gem5.opt configs/example/apu_se.py -n3 --mem-size=8GB --reg-alloc-policy=dynamic --benchmark-root="lulesh" -c \ - lulesh 0.01 2 + lulesh --options="0.01 2" HACC-tests: runs-on: [self-hosted, linux, x64]