| /* |
| * Copyright (c) 2010, 2012-2013, 2015-2021 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. |
| * |
| * Copyright (c) 2002-2005 The Regents of The University of Michigan |
| * All rights reserved. |
| * |
| * 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 __ARCH_ARM_SYSTEM_HH__ |
| #define __ARCH_ARM_SYSTEM_HH__ |
| |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include "arch/arm/page_size.hh" |
| #include "arch/arm/types.hh" |
| #include "kern/linux/events.hh" |
| #include "params/ArmSystem.hh" |
| #include "sim/full_system.hh" |
| #include "sim/sim_object.hh" |
| #include "sim/system.hh" |
| #include "enums/ArmExtension.hh" |
| |
| |
| namespace gem5 |
| { |
| |
| class GenericTimer; |
| class BaseGic; |
| class FVPBasePwrCtrl; |
| class ThreadContext; |
| |
| struct ArmReleaseParams; |
| |
| class ArmRelease : public SimObject |
| { |
| public: |
| PARAMS(ArmRelease); |
| ArmRelease(const Params &p); |
| |
| bool |
| has(ArmExtension ext) const |
| { |
| if (auto it = _extensions.find(ext); it != _extensions.end()) { |
| return it->second; |
| } else { |
| return false; |
| } |
| } |
| |
| protected: |
| /** |
| * List of implemented extensions |
| */ |
| std::unordered_map<ArmExtension, bool> _extensions; |
| }; |
| |
| class ArmSystem : public System |
| { |
| protected: |
| /** |
| * Pointer to the Generic Timer wrapper. |
| */ |
| GenericTimer *_genericTimer; |
| BaseGic *_gic; |
| |
| /** |
| * Pointer to the Power Controller (if any) |
| */ |
| FVPBasePwrCtrl *_pwrCtrl; |
| |
| /** |
| * Reset address (ARMv8) |
| */ |
| Addr _resetAddr; |
| |
| /** |
| * True if the register width of the highest implemented exception level is |
| * 64 bits (ARMv8) |
| */ |
| bool _highestELIs64; |
| |
| /** |
| * Supported physical address range in bits if the highest implemented |
| * exception level is 64 bits (ARMv8) |
| */ |
| const uint8_t _physAddrRange64; |
| |
| /** |
| * True if ASID is 16 bits in AArch64 (ARMv8) |
| */ |
| const bool _haveLargeAsid64; |
| |
| /** SVE vector length at reset, in quadwords */ |
| const unsigned _sveVL; |
| |
| /** |
| * True if the Semihosting interface is enabled. |
| */ |
| ArmSemihosting *const semihosting; |
| |
| /** |
| * Arm Release object: contains a list of implemented |
| * features |
| */ |
| const ArmRelease *release; |
| |
| public: |
| static constexpr Addr PageBytes = ArmISA::PageBytes; |
| static constexpr Addr PageShift = ArmISA::PageShift; |
| |
| PARAMS(ArmSystem); |
| |
| ArmSystem(const Params &p); |
| |
| /** true if this a multiprocessor system */ |
| bool multiProc; |
| |
| const ArmRelease* releaseFS() const { return release; } |
| |
| bool has(ArmExtension ext) const { return release->has(ext); } |
| |
| /** Sets the pointer to the Generic Timer. */ |
| void |
| setGenericTimer(GenericTimer *generic_timer) |
| { |
| _genericTimer = generic_timer; |
| } |
| |
| /** 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; } |
| |
| /** Returns the highest implemented exception level */ |
| ArmISA::ExceptionLevel |
| highestEL() const |
| { |
| if (has(ArmExtension::SECURITY)) |
| return ArmISA::EL3; |
| if (has(ArmExtension::VIRTUALIZATION)) |
| return ArmISA::EL2; |
| return ArmISA::EL1; |
| } |
| |
| /** Returns the reset address if the highest implemented exception level is |
| * 64 bits (ARMv8) */ |
| Addr resetAddr() const { return _resetAddr; } |
| void setResetAddr(Addr addr) { _resetAddr = addr; } |
| |
| /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */ |
| bool haveLargeAsid64() const { return _haveLargeAsid64; } |
| |
| /** Returns the SVE vector length at reset, in quadwords */ |
| unsigned sveVL() const { return _sveVL; } |
| |
| /** Returns the supported physical address range in bits if the highest |
| * implemented exception level is 64 bits (ARMv8) */ |
| uint8_t physAddrRange64() const { return _physAddrRange64; } |
| |
| /** Returns the supported physical address range in bits */ |
| uint8_t |
| physAddrRange() const |
| { |
| if (_highestELIs64) |
| return _physAddrRange64; |
| if (has(ArmExtension::LPAE)) |
| return 40; |
| return 32; |
| } |
| |
| /** Returns the physical address mask */ |
| Addr physAddrMask() const { return mask(physAddrRange()); } |
| |
| /** Is Arm Semihosting support enabled? */ |
| bool haveSemihosting() const { return semihosting != nullptr; } |
| |
| /** |
| * Returns a valid ArmSystem pointer if using ARM ISA, it fails |
| * otherwise. |
| */ |
| static ArmSystem* |
| getArmSystem(ThreadContext *tc) |
| { |
| assert(FullSystem); |
| return static_cast<ArmSystem *>(tc->getSystemPtr()); |
| } |
| |
| static bool has(ArmExtension ext, ThreadContext *tc); |
| |
| static bool highestELIs64(ThreadContext *tc); |
| |
| /** Returns the highest implemented exception level for the system of a |
| * specific thread context |
| */ |
| static ArmISA::ExceptionLevel highestEL(ThreadContext *tc); |
| |
| /** Return true if the system implements a specific exception level */ |
| static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el); |
| |
| /** Returns the reset address if the highest implemented exception level |
| * for the system of a specific thread context is 64 bits (ARMv8) |
| */ |
| static Addr resetAddr(ThreadContext *tc); |
| |
| /** Returns the supported physical address range in bits for the system of a |
| * specific thread context |
| */ |
| static uint8_t physAddrRange(ThreadContext *tc); |
| |
| /** Returns the physical address mask for the system of a specific thread |
| * context |
| */ |
| static Addr physAddrMask(ThreadContext *tc); |
| |
| /** Returns true if ASID is 16 bits for the system of a specific thread |
| * context while in AArch64 (ARMv8) */ |
| static bool haveLargeAsid64(ThreadContext *tc); |
| |
| /** Is Arm Semihosting support enabled? */ |
| static bool haveSemihosting(ThreadContext *tc); |
| |
| /** Make a Semihosting call from aarch64 */ |
| static bool callSemihosting64(ThreadContext *tc, bool gem5_ops=false); |
| |
| /** Make a Semihosting call from aarch32 */ |
| static bool callSemihosting32(ThreadContext *tc, bool gem5_ops=false); |
| |
| /** Make a Semihosting call from either aarch64 or aarch32 */ |
| static bool callSemihosting(ThreadContext *tc, bool gem5_ops=false); |
| |
| /** 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); |
| |
| /** |
| * Notify the power controller of WAKEREQUEST assertion. Returns true |
| * if WAKEREQUEST is enabled as a power-on mechanism, and the core is now |
| * powered, false otherwise |
| */ |
| static bool callSetWakeRequest(ThreadContext *tc); |
| |
| /** Notify the power controller of WAKEREQUEST deassertion */ |
| static void callClearWakeRequest(ThreadContext *tc); |
| }; |
| |
| } // namespace gem5 |
| |
| #endif |