system.hh revision 13396:23277eaae855
12810SN/A/* 212599Snikos.nikoleris@arm.com * Copyright (c) 2010, 2012-2013, 2015-2018 ARM Limited 39663Suri.wiener@arm.com * All rights reserved 49663Suri.wiener@arm.com * 59663Suri.wiener@arm.com * The license below extends only to copyright in the software and shall 69663Suri.wiener@arm.com * not be construed as granting a license to any other intellectual 79663Suri.wiener@arm.com * property including but not limited to intellectual property relating 89663Suri.wiener@arm.com * to a hardware implementation of the functionality of the software 99663Suri.wiener@arm.com * licensed hereunder. You may use the software subject to the license 109663Suri.wiener@arm.com * terms below provided that you ensure that this notice is replicated 119663Suri.wiener@arm.com * unmodified and in its entirety in all distributions of the software, 129663Suri.wiener@arm.com * modified or unmodified, in source code or in binary form. 139663Suri.wiener@arm.com * 142810SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 152810SN/A * All rights reserved. 162810SN/A * 172810SN/A * Redistribution and use in source and binary forms, with or without 182810SN/A * modification, are permitted provided that the following conditions are 192810SN/A * met: redistributions of source code must retain the above copyright 202810SN/A * notice, this list of conditions and the following disclaimer; 212810SN/A * redistributions in binary form must reproduce the above copyright 222810SN/A * notice, this list of conditions and the following disclaimer in the 232810SN/A * documentation and/or other materials provided with the distribution; 242810SN/A * neither the name of the copyright holders nor the names of its 252810SN/A * contributors may be used to endorse or promote products derived from 262810SN/A * this software without specific prior written permission. 272810SN/A * 282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392810SN/A * 402810SN/A * Authors: Ali Saidi 4113349Snikos.nikoleris@arm.com */ 422810SN/A 432810SN/A#ifndef __ARCH_ARM_SYSTEM_HH__ 442810SN/A#define __ARCH_ARM_SYSTEM_HH__ 452810SN/A 462810SN/A#include <memory> 472810SN/A#include <string> 482810SN/A#include <vector> 4910764Sandreas.hansson@arm.com 5010764Sandreas.hansson@arm.com#include "kern/linux/events.hh" 512810SN/A#include "params/ArmSystem.hh" 5212727Snikos.nikoleris@arm.com#include "params/GenericArmSystem.hh" 5312727Snikos.nikoleris@arm.com#include "sim/sim_object.hh" 544626SN/A#include "sim/system.hh" 5512727Snikos.nikoleris@arm.com 5613349Snikos.nikoleris@arm.comclass GenericTimer; 574626SN/Aclass ThreadContext; 585314SN/A 5912727Snikos.nikoleris@arm.comclass ArmSystem : public System 6011375Sandreas.hansson@arm.com{ 6112727Snikos.nikoleris@arm.com protected: 6213349Snikos.nikoleris@arm.com /** 6312727Snikos.nikoleris@arm.com * PC based event to skip the dprink() call and emulate its 642810SN/A * functionality 6512724Snikos.nikoleris@arm.com */ 662810SN/A Linux::DebugPrintkEvent *debugPrintkEvent; 672810SN/A 682810SN/A /** Bootloaders */ 693374SN/A std::vector<std::unique_ptr<ObjectFile>> bootLoaders; 709264Sdjordje.kovacevic@arm.com 712810SN/A /** 7211375Sandreas.hansson@arm.com * Pointer to the bootloader object 734626SN/A */ 744626SN/A ObjectFile *bootldr; 759725Sandreas.hansson@arm.com 7611375Sandreas.hansson@arm.com /** 779725Sandreas.hansson@arm.com * True if this system implements the Security Extensions 7811375Sandreas.hansson@arm.com */ 7911375Sandreas.hansson@arm.com const bool _haveSecurity; 809725Sandreas.hansson@arm.com 819725Sandreas.hansson@arm.com /** 829725Sandreas.hansson@arm.com * True if this system implements the Large Physical Address Extension 839725Sandreas.hansson@arm.com */ 849725Sandreas.hansson@arm.com const bool _haveLPAE; 859725Sandreas.hansson@arm.com 869725Sandreas.hansson@arm.com /** 8711284Sandreas.hansson@arm.com * True if this system implements the virtualization Extensions 8811284Sandreas.hansson@arm.com */ 8911284Sandreas.hansson@arm.com const bool _haveVirtualization; 9011284Sandreas.hansson@arm.com 9111284Sandreas.hansson@arm.com /** 9211284Sandreas.hansson@arm.com * True if this system implements the Crypto Extension 9311284Sandreas.hansson@arm.com */ 9411284Sandreas.hansson@arm.com const bool _haveCrypto; 9511284Sandreas.hansson@arm.com 9611284Sandreas.hansson@arm.com /** 9711284Sandreas.hansson@arm.com * Pointer to the Generic Timer wrapper. 9811284Sandreas.hansson@arm.com */ 9911284Sandreas.hansson@arm.com GenericTimer *_genericTimer; 10011284Sandreas.hansson@arm.com 10111284Sandreas.hansson@arm.com /** 10211284Sandreas.hansson@arm.com * Reset address (ARMv8) 10311284Sandreas.hansson@arm.com */ 10411284Sandreas.hansson@arm.com const Addr _resetAddr; 10511284Sandreas.hansson@arm.com 10611284Sandreas.hansson@arm.com /** 10711284Sandreas.hansson@arm.com * True if the register width of the highest implemented exception level is 10811284Sandreas.hansson@arm.com * 64 bits (ARMv8) 10911284Sandreas.hansson@arm.com */ 11011284Sandreas.hansson@arm.com bool _highestELIs64; 11111284Sandreas.hansson@arm.com 1129725Sandreas.hansson@arm.com /** 1139725Sandreas.hansson@arm.com * Supported physical address range in bits if the highest implemented 1149725Sandreas.hansson@arm.com * exception level is 64 bits (ARMv8) 1159725Sandreas.hansson@arm.com */ 1169725Sandreas.hansson@arm.com const uint8_t _physAddrRange64; 1179725Sandreas.hansson@arm.com 1189725Sandreas.hansson@arm.com /** 1192810SN/A * True if ASID is 16 bits in AArch64 (ARMv8) 1204626SN/A */ 12113349Snikos.nikoleris@arm.com const bool _haveLargeAsid64; 12213349Snikos.nikoleris@arm.com 12313349Snikos.nikoleris@arm.com /** 12411375Sandreas.hansson@arm.com * Range for memory-mapped m5 pseudo ops. The range will be 12511375Sandreas.hansson@arm.com * invalid/empty if disabled. 12611375Sandreas.hansson@arm.com */ 12713859Sodanrc@yahoo.com.br const AddrRange _m5opRange; 1284626SN/A 1295875Ssteve.reinhardt@amd.com /** 1305875Ssteve.reinhardt@amd.com * True if the Semihosting interface is enabled. 1315875Ssteve.reinhardt@amd.com */ 1325875Ssteve.reinhardt@amd.com ArmSemihosting *const semihosting; 1335875Ssteve.reinhardt@amd.com 1345875Ssteve.reinhardt@amd.com protected: 1355875Ssteve.reinhardt@amd.com /** 13610766Sandreas.hansson@arm.com * Get a boot loader that matches the kernel. 13711742Snikos.nikoleris@arm.com * 13811742Snikos.nikoleris@arm.com * @param obj Kernel binary 13911742Snikos.nikoleris@arm.com * @return Pointer to boot loader ObjectFile or nullptr if there 14011742Snikos.nikoleris@arm.com * is no matching boot loader. 14111742Snikos.nikoleris@arm.com */ 14211742Snikos.nikoleris@arm.com ObjectFile *getBootLoader(ObjectFile *const obj); 14311742Snikos.nikoleris@arm.com 14411742Snikos.nikoleris@arm.com public: 14511742Snikos.nikoleris@arm.com typedef ArmSystemParams Params; 14611742Snikos.nikoleris@arm.com const Params * 14711742Snikos.nikoleris@arm.com params() const 14811742Snikos.nikoleris@arm.com { 14911742Snikos.nikoleris@arm.com return dynamic_cast<const Params *>(_params); 15011742Snikos.nikoleris@arm.com } 15111742Snikos.nikoleris@arm.com 15211742Snikos.nikoleris@arm.com ArmSystem(Params *p); 15311742Snikos.nikoleris@arm.com ~ArmSystem(); 15411742Snikos.nikoleris@arm.com 15511741Snikos.nikoleris@arm.com /** 15611741Snikos.nikoleris@arm.com * Initialise the system 1574626SN/A */ 1585318SN/A virtual void initState(); 15911741Snikos.nikoleris@arm.com 16013859Sodanrc@yahoo.com.br virtual Addr fixFuncEventAddr(Addr addr) 16113859Sodanrc@yahoo.com.br { 1624626SN/A // Remove the low bit that thumb symbols have set 1634626SN/A // but that aren't actually odd aligned 1644626SN/A if (addr & 0x1) 1654903SN/A return addr & ~1; 1664903SN/A return addr; 1674903SN/A } 16811284Sandreas.hansson@arm.com 1694903SN/A /** true if this a multiprocessor system */ 17011741Snikos.nikoleris@arm.com bool multiProc; 17111741Snikos.nikoleris@arm.com 17212715Snikos.nikoleris@arm.com /** Returns true if this system implements the Security Extensions */ 17312715Snikos.nikoleris@arm.com bool haveSecurity() const { return _haveSecurity; } 17412715Snikos.nikoleris@arm.com 17512715Snikos.nikoleris@arm.com /** Returns true if this system implements the Large Physical Address 17612715Snikos.nikoleris@arm.com * Extension */ 1774903SN/A bool haveLPAE() const { return _haveLPAE; } 1784903SN/A 17911740Snikos.nikoleris@arm.com /** Returns true if this system implements the virtualization 18011740Snikos.nikoleris@arm.com * Extensions 18111740Snikos.nikoleris@arm.com */ 18211740Snikos.nikoleris@arm.com bool haveVirtualization() const { return _haveVirtualization; } 18311740Snikos.nikoleris@arm.com 18411740Snikos.nikoleris@arm.com /** Returns true if this system implements the Crypto 18511740Snikos.nikoleris@arm.com * Extension 18611741Snikos.nikoleris@arm.com */ 18711740Snikos.nikoleris@arm.com bool haveCrypto() const { return _haveCrypto; } 18811741Snikos.nikoleris@arm.com 18911741Snikos.nikoleris@arm.com /** Sets the pointer to the Generic Timer. */ 19011740Snikos.nikoleris@arm.com void setGenericTimer(GenericTimer *generic_timer) 19113349Snikos.nikoleris@arm.com { 19213349Snikos.nikoleris@arm.com _genericTimer = generic_timer; 19313349Snikos.nikoleris@arm.com } 19413349Snikos.nikoleris@arm.com 19513349Snikos.nikoleris@arm.com /** Get a pointer to the system's generic timer model */ 19613349Snikos.nikoleris@arm.com GenericTimer *getGenericTimer() const { return _genericTimer; } 19713349Snikos.nikoleris@arm.com 19813349Snikos.nikoleris@arm.com /** Returns true if the register width of the highest implemented exception 19913349Snikos.nikoleris@arm.com * level is 64 bits (ARMv8) */ 20013349Snikos.nikoleris@arm.com bool highestELIs64() const { return _highestELIs64; } 20113349Snikos.nikoleris@arm.com 20213349Snikos.nikoleris@arm.com /** Returns the highest implemented exception level */ 20313349Snikos.nikoleris@arm.com ExceptionLevel highestEL() const 20413349Snikos.nikoleris@arm.com { 20512715Snikos.nikoleris@arm.com if (_haveSecurity) 20613349Snikos.nikoleris@arm.com return EL3; 20713349Snikos.nikoleris@arm.com if (_haveVirtualization) 20813349Snikos.nikoleris@arm.com return EL2; 20912715Snikos.nikoleris@arm.com return EL1; 21012715Snikos.nikoleris@arm.com } 21112715Snikos.nikoleris@arm.com 21212715Snikos.nikoleris@arm.com /** Returns the reset address if the highest implemented exception level is 21312715Snikos.nikoleris@arm.com * 64 bits (ARMv8) */ 21411740Snikos.nikoleris@arm.com Addr resetAddr() const { return _resetAddr; } 21511740Snikos.nikoleris@arm.com 21611740Snikos.nikoleris@arm.com /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */ 21711740Snikos.nikoleris@arm.com bool haveLargeAsid64() const { return _haveLargeAsid64; } 21811740Snikos.nikoleris@arm.com 21911740Snikos.nikoleris@arm.com /** Returns the supported physical address range in bits if the highest 22011740Snikos.nikoleris@arm.com * implemented exception level is 64 bits (ARMv8) */ 22111740Snikos.nikoleris@arm.com uint8_t physAddrRange64() const { return _physAddrRange64; } 22211740Snikos.nikoleris@arm.com 22311741Snikos.nikoleris@arm.com /** Returns the supported physical address range in bits */ 22413349Snikos.nikoleris@arm.com uint8_t physAddrRange() const 22513349Snikos.nikoleris@arm.com { 22613349Snikos.nikoleris@arm.com if (_highestELIs64) 22713349Snikos.nikoleris@arm.com return _physAddrRange64; 22813349Snikos.nikoleris@arm.com if (_haveLPAE) 22913349Snikos.nikoleris@arm.com return 40; 23013349Snikos.nikoleris@arm.com return 32; 23113349Snikos.nikoleris@arm.com } 23213349Snikos.nikoleris@arm.com 23313349Snikos.nikoleris@arm.com /** Returns the physical address mask */ 23413349Snikos.nikoleris@arm.com Addr physAddrMask() const 23513349Snikos.nikoleris@arm.com { 23613349Snikos.nikoleris@arm.com return mask(physAddrRange()); 23713349Snikos.nikoleris@arm.com } 23813349Snikos.nikoleris@arm.com 23913349Snikos.nikoleris@arm.com /** 24013349Snikos.nikoleris@arm.com * Range used by memory-mapped m5 pseudo-ops if enabled. Returns 24113349Snikos.nikoleris@arm.com * an invalid/empty range if disabled. 24213349Snikos.nikoleris@arm.com */ 24313349Snikos.nikoleris@arm.com const AddrRange &m5opRange() const { return _m5opRange; } 24413349Snikos.nikoleris@arm.com 24513349Snikos.nikoleris@arm.com /** Is Arm Semihosting support enabled? */ 24613349Snikos.nikoleris@arm.com bool haveSemihosting() const { return semihosting != nullptr; } 24713349Snikos.nikoleris@arm.com 24813349Snikos.nikoleris@arm.com /** 24913349Snikos.nikoleris@arm.com * Returns a valid ArmSystem pointer if using ARM ISA, it fails 25013349Snikos.nikoleris@arm.com * otherwise. 25113349Snikos.nikoleris@arm.com */ 25213349Snikos.nikoleris@arm.com static ArmSystem* getArmSystem(ThreadContext *tc); 25313349Snikos.nikoleris@arm.com 25411741Snikos.nikoleris@arm.com /** Returns true if the system of a specific thread context implements the 25511741Snikos.nikoleris@arm.com * Security Extensions 25613349Snikos.nikoleris@arm.com */ 25713349Snikos.nikoleris@arm.com static bool haveSecurity(ThreadContext *tc); 25811741Snikos.nikoleris@arm.com 25911741Snikos.nikoleris@arm.com /** Returns true if the system of a specific thread context implements the 26012715Snikos.nikoleris@arm.com * virtualization Extensions 26113349Snikos.nikoleris@arm.com */ 26211741Snikos.nikoleris@arm.com static bool haveVirtualization(ThreadContext *tc); 26311741Snikos.nikoleris@arm.com 26411741Snikos.nikoleris@arm.com /** Returns true if the system of a specific thread context implements the 26511741Snikos.nikoleris@arm.com * Large Physical Address Extension 26611741Snikos.nikoleris@arm.com */ 26711741Snikos.nikoleris@arm.com static bool haveLPAE(ThreadContext *tc); 26811741Snikos.nikoleris@arm.com 26911741Snikos.nikoleris@arm.com /** Returns true if the register width of the highest implemented exception 27011741Snikos.nikoleris@arm.com * level for the system of a specific thread context is 64 bits (ARMv8) 27111741Snikos.nikoleris@arm.com */ 27211741Snikos.nikoleris@arm.com static bool highestELIs64(ThreadContext *tc); 27311741Snikos.nikoleris@arm.com 27411741Snikos.nikoleris@arm.com /** Returns the highest implemented exception level for the system of a 27511741Snikos.nikoleris@arm.com * specific thread context 2765318SN/A */ 27713349Snikos.nikoleris@arm.com static ExceptionLevel highestEL(ThreadContext *tc); 27811357Sstephan.diestelhorst@arm.com 27911357Sstephan.diestelhorst@arm.com /** Return true if the system implements a specific exception level */ 28011357Sstephan.diestelhorst@arm.com static bool haveEL(ThreadContext *tc, ExceptionLevel el); 28111357Sstephan.diestelhorst@arm.com 28211357Sstephan.diestelhorst@arm.com /** Returns the reset address if the highest implemented exception level 2834903SN/A * for the system of a specific thread context is 64 bits (ARMv8) 28411357Sstephan.diestelhorst@arm.com */ 2854908SN/A static Addr resetAddr(ThreadContext *tc); 28612791Snikos.nikoleris@arm.com 28712823Srmk35@cl.cam.ac.uk /** Returns the supported physical address range in bits for the system of a 2885314SN/A * specific thread context 2895314SN/A */ 29013349Snikos.nikoleris@arm.com static uint8_t physAddrRange(ThreadContext *tc); 29113349Snikos.nikoleris@arm.com 29213349Snikos.nikoleris@arm.com /** Returns the physical address mask for the system of a specific thread 29313349Snikos.nikoleris@arm.com * context 29413349Snikos.nikoleris@arm.com */ 29513349Snikos.nikoleris@arm.com static Addr physAddrMask(ThreadContext *tc); 29613349Snikos.nikoleris@arm.com 29713349Snikos.nikoleris@arm.com /** Returns true if ASID is 16 bits for the system of a specific thread 29813349Snikos.nikoleris@arm.com * context while in AArch64 (ARMv8) */ 29913349Snikos.nikoleris@arm.com static bool haveLargeAsid64(ThreadContext *tc); 30013349Snikos.nikoleris@arm.com 30113349Snikos.nikoleris@arm.com /** Is Arm Semihosting support enabled? */ 30213349Snikos.nikoleris@arm.com static bool haveSemihosting(ThreadContext *tc); 30313349Snikos.nikoleris@arm.com 30413349Snikos.nikoleris@arm.com /** Make a Semihosting call from aarch64 */ 30513349Snikos.nikoleris@arm.com static uint64_t callSemihosting64(ThreadContext *tc, 30613349Snikos.nikoleris@arm.com uint32_t op, uint64_t param); 30713349Snikos.nikoleris@arm.com 30813349Snikos.nikoleris@arm.com /** Make a Semihosting call from aarch32 */ 30913349Snikos.nikoleris@arm.com static uint32_t callSemihosting32(ThreadContext *tc, 31013349Snikos.nikoleris@arm.com uint32_t op, uint32_t param); 31113349Snikos.nikoleris@arm.com}; 31213349Snikos.nikoleris@arm.com 31313349Snikos.nikoleris@arm.comclass GenericArmSystem : public ArmSystem 31413349Snikos.nikoleris@arm.com{ 31513349Snikos.nikoleris@arm.com public: 31613349Snikos.nikoleris@arm.com typedef GenericArmSystemParams Params; 31713349Snikos.nikoleris@arm.com const Params * 31813349Snikos.nikoleris@arm.com params() const 31913349Snikos.nikoleris@arm.com { 32013349Snikos.nikoleris@arm.com return dynamic_cast<const Params *>(_params); 32113349Snikos.nikoleris@arm.com } 32213349Snikos.nikoleris@arm.com 3234903SN/A GenericArmSystem(Params *p) : ArmSystem(p) {}; 3244903SN/A virtual ~GenericArmSystem() {}; 3252810SN/A 3262810SN/A /** 3272810SN/A * Initialise the system 3282810SN/A */ 3294903SN/A virtual void initState(); 3307667Ssteve.reinhardt@amd.com}; 3317667Ssteve.reinhardt@amd.com 3327667Ssteve.reinhardt@amd.com#endif 3337667Ssteve.reinhardt@amd.com