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