From e980780efd690477666afc13b6633c8348dbcf59 Mon Sep 17 00:00:00 2001 From: Robert Hauser <85344819+robhau@users.noreply.github.com> Date: Fri, 9 Aug 2024 20:28:15 +0200 Subject: [PATCH] arch-riscv: Extend wfi behavior (#1364) At the moment, a hart does not halt if there are pending interrupts. However, an implementation can also consider the enable status of the individual interrupts, i.e., a halted hart would only resume if there are locally enabled pending interrupts. This commit introduces this behavior. The wfi behavior is controlled by the new configuration variable wfi_pending_resume of RiscvISA. Change-Id: I316239f9732c6e73e6ad692491bca08d773dd995 --------- Signed-off-by: Robert Hauser --- src/arch/riscv/RiscvISA.py | 11 +++++++++++ src/arch/riscv/isa.cc | 4 +++- src/arch/riscv/isa.hh | 12 ++++++++++++ src/arch/riscv/isa/decoder.isa | 21 +++++++++++++++++---- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/arch/riscv/RiscvISA.py b/src/arch/riscv/RiscvISA.py index 27b7e5d372..f87941d413 100644 --- a/src/arch/riscv/RiscvISA.py +++ b/src/arch/riscv/RiscvISA.py @@ -14,6 +14,7 @@ # Copyright (c) 2016 RISC-V Foundation # Copyright (c) 2016 The University of Virginia # Copyright (c) 2023 The Regents of the University of California +# Copyright (c) 2024 University of Rostock # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -114,6 +115,16 @@ class RiscvISA(BaseISA): enable_Zicbom_fs = Param.Bool(True, "Enable Zicbom extension in FS mode") enable_Zicboz_fs = Param.Bool(True, "Enable Zicboz extension in FS mode") + wfi_resume_on_pending = Param.Bool( + False, + "If wfi_resume_on_pending is set to True, the hart will resume " + "execution when interrupt becomes pending. The local enabled status " + "is not considered.\n" + "If wfi_resume_on_pending is set to False, the hart will only " + "resume the execution when an locally enabled interrupt becomes " + "pending.", + ) + def get_isa_string(self): isa_extensions = [] # check for the base ISA type diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 2d56055f79..062189c68c 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -3,6 +3,7 @@ * Copyright (c) 2016 The University of Virginia * Copyright (c) 2020 Barkhausen Institut * Copyright (c) 2022 Google LLC + * Copyright (c) 2024 University of Rostock * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -258,7 +259,8 @@ RegClass ccRegClass(CCRegClass, CCRegClassName, 0, debug::IntRegs); ISA::ISA(const Params &p) : BaseISA(p, "riscv"), _rvType(p.riscv_type), enableRvv(p.enable_rvv), vlen(p.vlen), elen(p.elen), - _privilegeModeSet(p.privilege_mode_set) + _privilegeModeSet(p.privilege_mode_set), + _wfiResumeOnPending(p.wfi_resume_on_pending) { _regClasses.push_back(&intRegClass); _regClasses.push_back(&floatRegClass); diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 9c0fd70f35..04bbcfbe9e 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -5,6 +5,7 @@ * Copyright (c) 2016 RISC-V Foundation * Copyright (c) 2016 The University of Virginia * Copyright (c) 2020 Barkhausen Institut + * Coypright (c) 2024 University of Rostock * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,6 +99,15 @@ class ISA : public BaseISA */ PrivilegeModeSet _privilegeModeSet; + /** + * The WFI instruction can halt the execution of a hart. + * If this variable is set true, the execution resumes if + * an interrupt becomes pending. If this variable is set + * to false, the execution only resumes if an locally enabled + * interrupt becomes pending. + */ + const bool _wfiResumeOnPending; + public: using Params = RiscvISAParams; @@ -170,6 +180,8 @@ class ISA : public BaseISA PrivilegeModeSet getPrivilegeModeSet() { return _privilegeModeSet; } + bool resumeOnPending() { return _wfiResumeOnPending; } + virtual Addr getFaultHandlerAddr( RegIndex idx, uint64_t cause, bool intr) const; }; diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 763709b016..9f5391c0fc 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -4873,16 +4873,29 @@ decode QUADRANT default Unknown::unknown() { "wfi in user mode or TW enabled", machInst); } - // Go to sleep only if there's no pending interrupt - // at all, including masked interrupts. auto tc = xc->tcBase(); auto cpu = tc->getCpuPtr(); auto ic = dynamic_cast( cpu->getInterruptController(tc->threadId())); + auto isa = dynamic_cast( + tc->getIsaPtr()); panic_if(!ic, "Invalid Interrupt Controller."); - if (ic->readIP() == 0 + if (isa->resumeOnPending()) { + // Go to sleep only if there are no pending + // interrupts at all, and no non-maskable + // interrupts. + if (ic->readIP() == 0 && xc->readMiscReg(MISCREG_NMIP) == 0) { - tc->quiesce(); + tc->quiesce(); + } + } else { + // Go to sleep only if there are no enabled + // pending interrupts at all, and no + // non-maskable interrupts + if (!(ic->readIP() & ic->readIE()) + && xc->readMiscReg(MISCREG_NMIP) == 0) { + tc->quiesce(); + } } }}, IsNonSpeculative, IsQuiesce, IsSerializeAfter, No_OpClass, IsSquashAfter);