From 5719da9fffc639c4eb63d6ea0bb313d3f3ca864c Mon Sep 17 00:00:00 2001 From: Adrian Herrera Date: Fri, 25 Oct 2019 10:49:23 +0100 Subject: [PATCH] dev-arm: add FVP Base Power Controller model This is a reduced model of the FVP Base platforms Power Controller. As of now it allows the following functions from software: - Checking for core presence - Reporting the power state of a core / cluster - Explicitly powering off a core on WFI - Explicitly powering off cores in a CPU cluster on WFI - Explicitly powering on a core through writes to PPONR register Change-Id: Ia1d4d3ae8e4bfb2d23b2c6077396a4d8500e2e30 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26463 Maintainer: Giacomo Travaglini Reviewed-by: Nikos Nikoleris Tested-by: kokoro --- src/arch/arm/isa/insts/misc.isa | 1 + src/arch/arm/system.cc | 18 +- src/arch/arm/system.hh | 23 ++- src/dev/arm/RealView.py | 11 ++ src/dev/arm/SConscript | 4 +- src/dev/arm/fvp_base_pwr_ctrl.cc | 289 +++++++++++++++++++++++++++++++ src/dev/arm/fvp_base_pwr_ctrl.hh | 173 ++++++++++++++++++ src/dev/arm/gic_v3.cc | 3 +- 8 files changed, 518 insertions(+), 4 deletions(-) create mode 100644 src/dev/arm/fvp_base_pwr_ctrl.cc create mode 100644 src/dev/arm/fvp_base_pwr_ctrl.hh diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 0c6fdc31a..03401ca32 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -762,6 +762,7 @@ let {{ fault = trapWFx(tc, cpsr, scr, false); if (fault == NoFault) { PseudoInst::quiesce(tc); + ArmSystem::callSetStandByWfi(tc); } else { PseudoInst::quiesceSkip(tc); } diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc index 6ecc75a6a..9053a5c7d 100644 --- a/src/arch/arm/system.cc +++ b/src/arch/arm/system.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013, 2015,2017-2019 ARM Limited + * Copyright (c) 2010, 2012-2013, 2015,2017-2020 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -47,6 +47,7 @@ #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "cpu/thread_context.hh" +#include "dev/arm/fvp_base_pwr_ctrl.hh" #include "dev/arm/gic_v2.hh" #include "mem/fs_translating_port_proxy.hh" #include "mem/physical.hh" @@ -62,6 +63,7 @@ ArmSystem::ArmSystem(Params *p) _haveCrypto(p->have_crypto), _genericTimer(nullptr), _gic(nullptr), + _pwrCtrl(nullptr), _highestELIs64(p->highest_el_is_64), _physAddrRange64(p->phys_addr_range_64), _haveLargeAsid64(p->have_large_asid_64), @@ -197,6 +199,20 @@ ArmSystem::callSemihosting32(ThreadContext *tc, return sys->semihosting->call32(tc, op, param); } +void +ArmSystem::callSetStandByWfi(ThreadContext *tc) +{ + if (FVPBasePwrCtrl *pwr_ctrl = getArmSystem(tc)->getPowerController()) + pwr_ctrl->setStandByWfi(tc); +} + +void +ArmSystem::callClearStandByWfi(ThreadContext *tc) +{ + if (FVPBasePwrCtrl *pwr_ctrl = getArmSystem(tc)->getPowerController()) + pwr_ctrl->clearStandByWfi(tc); +} + ArmSystem * ArmSystemParams::create() { diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh index 0c75ad51d..d9268f093 100644 --- a/src/arch/arm/system.hh +++ b/src/arch/arm/system.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013, 2015-2019 ARM Limited + * Copyright (c) 2010, 2012-2013, 2015-2020 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -53,6 +53,7 @@ class GenericTimer; class BaseGic; +class FVPBasePwrCtrl; class ThreadContext; class ArmSystem : public System @@ -84,6 +85,11 @@ class ArmSystem : public System GenericTimer *_genericTimer; BaseGic *_gic; + /** + * Pointer to the Power Controller (if any) + */ + FVPBasePwrCtrl *_pwrCtrl; + /** * Reset address (ARMv8) */ @@ -175,12 +181,21 @@ class ArmSystem : public System /** Sets the pointer to the GIC. */ void setGIC(BaseGic *gic) { _gic = gic; } + /** Sets the pointer to the Power Controller */ + void setPowerController(FVPBasePwrCtrl *pwr_ctrl) + { + _pwrCtrl = pwr_ctrl; + } + /** Get a pointer to the system's generic timer model */ GenericTimer *getGenericTimer() const { return _genericTimer; } /** Get a pointer to the system's GIC */ BaseGic *getGIC() const { return _gic; } + /** Get a pointer to the system's power controller */ + FVPBasePwrCtrl *getPowerController() const { return _pwrCtrl; } + /** Returns true if the register width of the highest implemented exception * level is 64 bits (ARMv8) */ bool highestELIs64() const { return _highestELIs64; } @@ -305,6 +320,12 @@ class ArmSystem : public System /** Make a Semihosting call from aarch32 */ static uint32_t callSemihosting32(ThreadContext *tc, uint32_t op, uint32_t param); + + /** Make a call to notify the power controller of STANDBYWFI assertion */ + static void callSetStandByWfi(ThreadContext *tc); + + /** Make a call to notify the power controller of STANDBYWFI deassertion */ + static void callClearStandByWfi(ThreadContext *tc); }; #endif diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 68a69d3ff..40ed4684e 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -1159,3 +1159,14 @@ class VExpress_GEM5_V2(VExpress_GEM5_V2_Base): return super(VExpress_GEM5_V2,self)._on_chip_devices() + [ self.hdlcd, ] + +class FVPBasePwrCtrl(BasicPioDevice): + """ +Based on Fast Models Base_PowerController v11.8 +Reference: + Fast Models Reference Manual - Section 7.7.2 - Version 11.8 + Document ID: 100964_1180_00_en + """ + + type = 'FVPBasePwrCtrl' + cxx_header = 'dev/arm/fvp_base_pwr_ctrl.hh' diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript index b264d05cf..de5f8b74e 100644 --- a/src/dev/arm/SConscript +++ b/src/dev/arm/SConscript @@ -1,6 +1,6 @@ # -*- mode:python -*- -# Copyright (c) 2009, 2012-2013 ARM Limited +# Copyright (c) 2009, 2012-2013, 2020 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -92,6 +92,7 @@ if env['TARGET_ISA'] == 'arm': Source('vio_mmio.cc') Source('ufs_device.cc') Source('energy_ctrl.cc') + Source('fvp_base_pwr_ctrl.cc') DebugFlag('AMBA') DebugFlag('FlashDevice') @@ -106,6 +107,7 @@ if env['TARGET_ISA'] == 'arm': DebugFlag('SMMUv3Hazard') DebugFlag('Sp805') DebugFlag('EnergyCtrl') + DebugFlag('FVPBasePwrCtrl') DebugFlag('UFSHostDevice') DebugFlag('VGIC') DebugFlag('NoMali') diff --git a/src/dev/arm/fvp_base_pwr_ctrl.cc b/src/dev/arm/fvp_base_pwr_ctrl.cc new file mode 100644 index 000000000..88708bd86 --- /dev/null +++ b/src/dev/arm/fvp_base_pwr_ctrl.cc @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2020 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dev/arm/fvp_base_pwr_ctrl.hh" + +#include "arch/arm/faults.hh" +#include "arch/arm/system.hh" +#include "arch/arm/utility.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "debug/FVPBasePwrCtrl.hh" +#include "mem/packet_access.hh" +#include "params/FVPBasePwrCtrl.hh" +#include "sim/system.hh" + +FVPBasePwrCtrl::FVPBasePwrCtrl(FVPBasePwrCtrlParams *const params) + : BasicPioDevice(params, 0x1000), + regs(), + system(*static_cast(sys)) +{ + warn_if(sys->multiThread, + "Base Power Controller does not support multi-threaded systems\n"); + system.setPowerController(this); +} + +void +FVPBasePwrCtrl::init() +{ + // All cores are ON by default (PwrStatus.{l0,l1} = 0b1) + corePwrStatus.resize(sys->numContexts(), 0x60000000); + for (const auto &tc : sys->threadContexts) + poweredCoresPerCluster[tc->socketId()] += 1; + BasicPioDevice::init(); +} + +void +FVPBasePwrCtrl::setStandByWfi(ThreadContext *const tc) +{ + PwrStatus *pwrs = getCorePwrStatus(tc); + + if (!pwrs->pwfi) + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::setStandByWfi: STANDBYWFI " + "asserted for core %d\n", tc->contextId()); + pwrs->pwfi = 1; + if (pwrs->l0 && (pwrs->pp || pwrs->pc)) + powerCoreOff(tc, pwrs); +} + +void +FVPBasePwrCtrl::clearStandByWfi(ThreadContext *const tc) +{ + PwrStatus *pwrs = getCorePwrStatus(tc); + + if (pwrs->pwfi) + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::clearStandByWfi: STANDBYWFI " + "deasserted for core %d\n", tc->contextId()); + pwrs->pwfi = 0; +} + +Tick +FVPBasePwrCtrl::read(PacketPtr pkt) +{ + const Addr addr = pkt->getAddr() - pioAddr; + const size_t size = pkt->getSize(); + panic_if(size != 4, "FVPBasePwrCtrl::read: Invalid size %i\n", size); + + uint64_t resp = 0; + switch (addr) { + case PPOFFR: + resp = regs.ppoffr; + break; + case PPONR: + resp = regs.pponr; + break; + case PCOFFR: + resp = regs.pcoffr; + break; + case PWKUPR: + resp = regs.pwkupr; + break; + case PSYSR: + resp = regs.psysr; + break; + default: + warn("FVPBasePwrCtrl::read: Unexpected address (0x%x:%i), " + "assuming RAZ\n", addr, size); + } + + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::read: 0x%x<-0x%x(%i)\n", resp, + addr, size); + + pkt->setUintX(resp, LittleEndianByteOrder); + pkt->makeResponse(); + return pioDelay; +} + +Tick +FVPBasePwrCtrl::write(PacketPtr pkt) +{ + const Addr addr = pkt->getAddr() - pioAddr; + const size_t size = pkt->getSize(); + panic_if(size != 4, "FVPBasePwrCtrl::write: Invalid size %i\n", size); + + uint64_t data = pkt->getUintX(LittleEndianByteOrder); + + // Software may use the power controller to check for core presence + // If core is not present, return an invalid MPID as notification + ThreadContext *tc = getThreadContextByMPID(data & MPID_MSK); + PwrStatus *pwrs = tc ? getCorePwrStatus(tc) : nullptr; + switch (addr) { + case PPOFFR: + if (!tc) { + regs.ppoffr = ~0; + } else if (pwrs->l0) { + // Set pending power off + pwrs->pp = 1; + regs.ppoffr = data & MPID_MSK; + } else { + regs.ppoffr = ~0 & MPID_MSK; + } + break; + case PPONR: + if (!tc) { + regs.pponr = ~0; + } else { + if (!pwrs->l0) { + pwrs->wk = WK_PPONR; + powerCoreOn(tc, pwrs); + startCoreUp(tc); + regs.pponr = data & MPID_MSK; + } else { + regs.pponr = ~0 & MPID_MSK; + } + } + break; + case PCOFFR: + if (!tc) { + regs.pcoffr = ~0; + } else if (pwrs->l0) { + // Power off all cores in the cluster + for (const auto &tco : sys->threadContexts) { + if (tc->socketId() == tco->socketId()) { + PwrStatus *npwrs = getCorePwrStatus(tco); + // Set pending cluster power off + npwrs->pc = 1; + if (npwrs->l0 && npwrs->pwfi) + powerCoreOff(tco, npwrs); + } + } + } else { + regs.pcoffr = ~0 & MPID_MSK; + } + break; + case PWKUPR: + if (!tc) { + regs.pwkupr = ~0; + } else { + // Update WEN value + pwrs->wen = bits(data, 31); + // Power-on if there is any pending Wakeup Requests + if (!pwrs->l0 && pwrs->wen && pwrs->pwk) { + pwrs->wk = WK_GICWR; + powerCoreOn(tc, pwrs); + startCoreUp(tc); + } + regs.pwkupr = data & (MPID_MSK | (1 << 31)); + } + break; + case PSYSR: + if (!tc) + regs.psysr = ~0; + else + regs.psysr = (data & MPID_MSK) | (((uint32_t) *pwrs) & ~MPID_MSK); + break; + default: + warn("FVPBasePwrCtrl::write: Unexpected address (0x%x:%i), " + "assuming WI\n", addr, size); + } + + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::write: 0x%x->0x%x(%i)\n", data, + addr, size); + + pkt->makeResponse(); + return pioDelay; +} + +FVPBasePwrCtrl::PwrStatus * +FVPBasePwrCtrl::getCorePwrStatus(ThreadContext *const tc) +{ + PwrStatus *pwrs = &corePwrStatus[tc->contextId()]; + pwrs->l1 = poweredCoresPerCluster[tc->socketId()] > 0; + return pwrs; +} + +ThreadContext * +FVPBasePwrCtrl::getThreadContextByMPID(uint32_t mpid) const +{ + for (auto &tc : sys->threadContexts) { + if (mpid == ArmISA::getAffinity(&system, tc)) + return tc; + } + return nullptr; +} + +void +FVPBasePwrCtrl::powerCoreOn(ThreadContext *const tc, PwrStatus *const pwrs) +{ + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::powerCoreOn: Powering ON " + "core %d\n", tc->contextId()); + pwrs->l0 = 1; + poweredCoresPerCluster[tc->socketId()]++; + // Clear pending power-offs to the core + pwrs->pp = 0; + // Clear pending power-offs to the core's cluster + for (const auto &tco : sys->threadContexts) { + if (tc->socketId() == tco->socketId()) { + PwrStatus *npwrs = getCorePwrStatus(tco); + npwrs->pc = 0; + } + } + tc->getCpuPtr()->pwrState(Enums::PwrState::ON); +} + +void +FVPBasePwrCtrl::powerCoreOff(ThreadContext *const tc, PwrStatus *const pwrs) +{ + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::powerCoreOff: Powering OFF " + "core %d\n", tc->contextId()); + pwrs->l0 = 0; + poweredCoresPerCluster[tc->socketId()]--; + // Clear pending power-offs to the core + pwrs->pp = 0; + pwrs->pc = 0; + // Clear power-on reason + pwrs->wk = 0; + tc->getCpuPtr()->pwrState(Enums::PwrState::OFF); +} + +void +FVPBasePwrCtrl::startCoreUp(ThreadContext *const tc) +{ + DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::startCoreUp: Starting core %d " + "from the power controller\n", tc->contextId()); + clearStandByWfi(tc); + + // InitCPU + Reset().invoke(tc); + tc->activate(); +} + +FVPBasePwrCtrl * +FVPBasePwrCtrlParams::create() +{ + return new FVPBasePwrCtrl(this); +} diff --git a/src/dev/arm/fvp_base_pwr_ctrl.hh b/src/dev/arm/fvp_base_pwr_ctrl.hh new file mode 100644 index 000000000..df0b686f6 --- /dev/null +++ b/src/dev/arm/fvp_base_pwr_ctrl.hh @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2020 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_ARM_FVP_BASE_PWR_CTRL_HH__ +#define __DEV_ARM_FVP_BASE_PWR_CTRL_HH__ + +#include + +#include "base/bitunion.hh" +#include "dev/io_device.hh" + +class ArmSystem; +class FVPBasePwrCtrlParams; +class ThreadContext; + +/** + * @file + * This class implements the base power controller for FVP-based + * platforms. Based on Fast Models version 11.8. + * + * Limitations: + * - Level 2 affinity is not implemented -> PSYSR.L2 is RAZ + * - WakeRequests are not modelled by GICv3 -> PSYSR.WEN is always 0 + * - PSYSR.WK can only be 0b00 (Cold power-on) and 0b10 (Wake by PPONR) + */ +class FVPBasePwrCtrl : public BasicPioDevice +{ + public: + FVPBasePwrCtrl(FVPBasePwrCtrlParams *const params); + + /** + * Triggered by the ISA when a WFI instruction is executed and (1) there + * are no pending interrupts and (2) it is not trapped. Core is set + * to quiescent state only if there is a pending power off + * @param tc Thread context representing the core + */ + void setStandByWfi(ThreadContext *const tc); + + /** + * Triggered when an interrupt is posted to the core. Core is brought up + * from quiescent state if it is suspended. The latter is done by + * BaseCPU::wakeup. + * @param tc Thread context representing the core + */ + void clearStandByWfi(ThreadContext *const tc); + + void init() override; + + protected: + Tick read(PacketPtr pkt) override; + Tick write(PacketPtr pkt) override; + + private: + BitUnion32(PwrStatus) + Bitfield<30> l1; + Bitfield<29> l0; + Bitfield<28> wen; + Bitfield<27> pc; + Bitfield<26> pp; + Bitfield<25,24> wk; + Bitfield<1> pwfi; + Bitfield<0> pwk; + EndBitUnion(PwrStatus) + + enum Offset : Addr { + PPOFFR = 0x00, + PPONR = 0x04, + PCOFFR = 0x08, + PWKUPR = 0x0c, + PSYSR = 0x10 + }; + + struct Registers { + uint32_t ppoffr; + uint32_t pponr; + uint32_t pcoffr; + uint32_t pwkupr; + uint32_t psysr; + } regs; + + /** Mask for extracting the MPID from a 32-bit value */ + static constexpr uint32_t MPID_MSK = 0x00ffffff; + /** Wake-up reasons */ + enum { WK_COLD, WK_RESET, WK_PPONR, WK_GICWR }; + + /** + * Per-core power status. This is power related information for each core + * that is bound to this power controller functionality + */ + std::vector corePwrStatus; + + /** Number of powered cores per cluster. Helps keep track of PSYSR.L1 */ + std::unordered_map poweredCoresPerCluster; + + /** + * Retrieves the power status of a certain core and resizes the entries + * if needed. This is a workaround for a limitation of the System object + * only exposing existing thread contexts after "init()" + * @param Thread (HW) context in the core + * @return Core power status + */ + PwrStatus *getCorePwrStatus(ThreadContext *const tc); + + /** + * Retrieves the thread context reference for a CPU core by MPID + * @param mpid ID provided by software + * @return valid thread context reference if valid MPID, nullptr otherwise + */ + ThreadContext *getThreadContextByMPID(uint32_t mpid) const; + + /** + * Powers on a core. A Reset fault is invoked in the core followed by + * an activation + * @param Thread (HW) context in the core + * @param Core power status + */ + void powerCoreOn(ThreadContext *const tc, PwrStatus *const pwrs); + + /** + * Powers off a core. The core enters into quiescent state until + * an explicit PPONR write or a WakeRequest from the GIC wakes it up + * @param Thread (HW) context in the core + * @param Core power status + */ + void powerCoreOff(ThreadContext *const tc, PwrStatus *const pwrs); + + /** + * Starts a core up. This invokes the reset vector to setup the wake-up + * entrypoint and activates the thread context. This covers cases when + * PSYSR.WEN is enabled or PPONR is written + * @param Thread (HW) context in the core + */ + void startCoreUp(ThreadContext *const tc); + + /** Reference to the arm system */ + ArmSystem &system; +}; + +#endif // __DEV_ARM_FVP_BASE_PWR_CTRL_HH__ diff --git a/src/dev/arm/gic_v3.cc b/src/dev/arm/gic_v3.cc index 3607f4f98..ede5f16ba 100644 --- a/src/dev/arm/gic_v3.cc +++ b/src/dev/arm/gic_v3.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited + * Copyright (c) 2019-2020 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -205,6 +205,7 @@ void Gicv3::postInt(uint32_t cpu, ArmISA::InterruptTypes int_type) { platform->intrctrl->post(cpu, int_type, 0); + ArmSystem::callClearStandByWfi(sys->getThreadContext(cpu)); } bool -- 2.30.2