12567SN/A/*
214128Sgiacomo.travaglini@arm.com * Copyright (c) 2010, 2012-2013, 2015-2019 ARM Limited
37650SAli.Saidi@ARM.com * All rights reserved
47650SAli.Saidi@ARM.com *
57650SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
67650SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
77650SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
87650SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
97650SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
107650SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
117650SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
127650SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
137650SAli.Saidi@ARM.com *
142567SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152567SN/A * All rights reserved.
162567SN/A *
172567SN/A * Redistribution and use in source and binary forms, with or without
182567SN/A * modification, are permitted provided that the following conditions are
192567SN/A * met: redistributions of source code must retain the above copyright
202567SN/A * notice, this list of conditions and the following disclaimer;
212567SN/A * redistributions in binary form must reproduce the above copyright
222567SN/A * notice, this list of conditions and the following disclaimer in the
232567SN/A * documentation and/or other materials provided with the distribution;
242567SN/A * neither the name of the copyright holders nor the names of its
252567SN/A * contributors may be used to endorse or promote products derived from
262567SN/A * this software without specific prior written permission.
272567SN/A *
282567SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292567SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302567SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312567SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322567SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332567SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342567SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352567SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362567SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372567SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382567SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665SN/A *
402665SN/A * Authors: Ali Saidi
412567SN/A */
422567SN/A
436757SAli.Saidi@ARM.com#ifndef __ARCH_ARM_SYSTEM_HH__
446757SAli.Saidi@ARM.com#define __ARCH_ARM_SYSTEM_HH__
452567SN/A
4611234Sandreas.sandberg@arm.com#include <memory>
472567SN/A#include <string>
482567SN/A#include <vector>
492567SN/A
508229Snate@binkert.org#include "kern/linux/events.hh"
516757SAli.Saidi@ARM.com#include "params/ArmSystem.hh"
5210810Sbr@bsdpad.com#include "params/GenericArmSystem.hh"
532567SN/A#include "sim/sim_object.hh"
542567SN/A#include "sim/system.hh"
552567SN/A
5610844Sandreas.sandberg@arm.comclass GenericTimer;
5713531Sjairo.balart@metempsy.comclass BaseGic;
5810037SARM gem5 Developersclass ThreadContext;
5910037SARM gem5 Developers
606757SAli.Saidi@ARM.comclass ArmSystem : public System
612567SN/A{
628285SPrakash.Ramrakhyani@arm.com  protected:
637650SAli.Saidi@ARM.com    /**
647650SAli.Saidi@ARM.com     * PC based event to skip the dprink() call and emulate its
657650SAli.Saidi@ARM.com     * functionality
667650SAli.Saidi@ARM.com     */
677650SAli.Saidi@ARM.com    Linux::DebugPrintkEvent *debugPrintkEvent;
687650SAli.Saidi@ARM.com
6911234Sandreas.sandberg@arm.com    /** Bootloaders */
7011234Sandreas.sandberg@arm.com    std::vector<std::unique_ptr<ObjectFile>> bootLoaders;
7111234Sandreas.sandberg@arm.com
728286SAli.Saidi@ARM.com    /**
738286SAli.Saidi@ARM.com     * Pointer to the bootloader object
748286SAli.Saidi@ARM.com     */
758286SAli.Saidi@ARM.com    ObjectFile *bootldr;
768286SAli.Saidi@ARM.com
7710037SARM gem5 Developers    /**
7810037SARM gem5 Developers     * True if this system implements the Security Extensions
7910037SARM gem5 Developers     */
8010037SARM gem5 Developers    const bool _haveSecurity;
8110037SARM gem5 Developers
8210037SARM gem5 Developers    /**
8310037SARM gem5 Developers     * True if this system implements the Large Physical Address Extension
8410037SARM gem5 Developers     */
8510037SARM gem5 Developers    const bool _haveLPAE;
8610037SARM gem5 Developers
8710037SARM gem5 Developers    /**
8810037SARM gem5 Developers     * True if this system implements the virtualization Extensions
8910037SARM gem5 Developers     */
9010037SARM gem5 Developers    const bool _haveVirtualization;
9110037SARM gem5 Developers
9210037SARM gem5 Developers    /**
9313173Sgiacomo.travaglini@arm.com     * True if this system implements the Crypto Extension
9413173Sgiacomo.travaglini@arm.com     */
9513173Sgiacomo.travaglini@arm.com    const bool _haveCrypto;
9613173Sgiacomo.travaglini@arm.com
9713173Sgiacomo.travaglini@arm.com    /**
9810037SARM gem5 Developers     * Pointer to the Generic Timer wrapper.
9910037SARM gem5 Developers     */
10010037SARM gem5 Developers    GenericTimer *_genericTimer;
10113531Sjairo.balart@metempsy.com    BaseGic *_gic;
10210037SARM gem5 Developers
10310037SARM gem5 Developers    /**
10413396Sgiacomo.travaglini@arm.com     * Reset address (ARMv8)
10513396Sgiacomo.travaglini@arm.com     */
10613396Sgiacomo.travaglini@arm.com    const Addr _resetAddr;
10713396Sgiacomo.travaglini@arm.com
10813396Sgiacomo.travaglini@arm.com    /**
10910037SARM gem5 Developers     * True if the register width of the highest implemented exception level is
11010037SARM gem5 Developers     * 64 bits (ARMv8)
11110037SARM gem5 Developers     */
11210037SARM gem5 Developers    bool _highestELIs64;
11310037SARM gem5 Developers
11410037SARM gem5 Developers    /**
11510037SARM gem5 Developers     * Supported physical address range in bits if the highest implemented
11610037SARM gem5 Developers     * exception level is 64 bits (ARMv8)
11710037SARM gem5 Developers     */
11810037SARM gem5 Developers    const uint8_t _physAddrRange64;
11910037SARM gem5 Developers
12010037SARM gem5 Developers    /**
12110037SARM gem5 Developers     * True if ASID is 16 bits in AArch64 (ARMv8)
12210037SARM gem5 Developers     */
12310037SARM gem5 Developers    const bool _haveLargeAsid64;
12410037SARM gem5 Developers
12512005Sandreas.sandberg@arm.com    /**
12613759Sgiacomo.gabrielli@arm.com     * True if SVE is implemented (ARMv8)
12713759Sgiacomo.gabrielli@arm.com     */
12813759Sgiacomo.gabrielli@arm.com    const bool _haveSVE;
12913759Sgiacomo.gabrielli@arm.com
13013759Sgiacomo.gabrielli@arm.com    /** SVE vector length at reset, in quadwords */
13113759Sgiacomo.gabrielli@arm.com    const unsigned _sveVL;
13213759Sgiacomo.gabrielli@arm.com
13314133Sjordi.vaquero@metempsy.com    /**
13414133Sjordi.vaquero@metempsy.com     * True if LSE is implemented (ARMv8.1)
13514133Sjordi.vaquero@metempsy.com     */
13614133Sjordi.vaquero@metempsy.com    const bool _haveLSE;
13714133Sjordi.vaquero@metempsy.com
13814128Sgiacomo.travaglini@arm.com    /** True if Priviledge Access Never is implemented */
13914128Sgiacomo.travaglini@arm.com    const unsigned _havePAN;
14014128Sgiacomo.travaglini@arm.com
14113759Sgiacomo.gabrielli@arm.com    /**
14212005Sandreas.sandberg@arm.com     * Range for memory-mapped m5 pseudo ops. The range will be
14312005Sandreas.sandberg@arm.com     * invalid/empty if disabled.
14412005Sandreas.sandberg@arm.com     */
14512005Sandreas.sandberg@arm.com    const AddrRange _m5opRange;
14612005Sandreas.sandberg@arm.com
14712531Sandreas.sandberg@arm.com    /**
14812531Sandreas.sandberg@arm.com     * True if the Semihosting interface is enabled.
14912531Sandreas.sandberg@arm.com     */
15012531Sandreas.sandberg@arm.com    ArmSemihosting *const semihosting;
15112531Sandreas.sandberg@arm.com
15211234Sandreas.sandberg@arm.com  protected:
15311234Sandreas.sandberg@arm.com    /**
15411234Sandreas.sandberg@arm.com     * Get a boot loader that matches the kernel.
15511234Sandreas.sandberg@arm.com     *
15611234Sandreas.sandberg@arm.com     * @param obj Kernel binary
15711234Sandreas.sandberg@arm.com     * @return Pointer to boot loader ObjectFile or nullptr if there
15811234Sandreas.sandberg@arm.com     *         is no matching boot loader.
15911234Sandreas.sandberg@arm.com     */
16011234Sandreas.sandberg@arm.com    ObjectFile *getBootLoader(ObjectFile *const obj);
16111234Sandreas.sandberg@arm.com
1622567SN/A  public:
1636757SAli.Saidi@ARM.com    typedef ArmSystemParams Params;
1648286SAli.Saidi@ARM.com    const Params *
1658286SAli.Saidi@ARM.com    params() const
1668286SAli.Saidi@ARM.com    {
1678286SAli.Saidi@ARM.com        return dynamic_cast<const Params *>(_params);
1688286SAli.Saidi@ARM.com    }
1698286SAli.Saidi@ARM.com
1706757SAli.Saidi@ARM.com    ArmSystem(Params *p);
1716757SAli.Saidi@ARM.com    ~ArmSystem();
1728286SAli.Saidi@ARM.com
1738706Sandreas.hansson@arm.com    /**
1748706Sandreas.hansson@arm.com     * Initialise the system
1758706Sandreas.hansson@arm.com     */
1768706Sandreas.hansson@arm.com    virtual void initState();
1778286SAli.Saidi@ARM.com
1783553SN/A    virtual Addr fixFuncEventAddr(Addr addr)
1793553SN/A    {
1807693SAli.Saidi@ARM.com        // Remove the low bit that thumb symbols have set
1817693SAli.Saidi@ARM.com        // but that aren't actually odd aligned
1827693SAli.Saidi@ARM.com        if (addr & 0x1)
1837720Sgblack@eecs.umich.edu            return addr & ~1;
1843553SN/A        return addr;
1853553SN/A    }
1869050Schander.sudanthi@arm.com
1879050Schander.sudanthi@arm.com    /** true if this a multiprocessor system */
1889050Schander.sudanthi@arm.com    bool multiProc;
18910037SARM gem5 Developers
19010037SARM gem5 Developers    /** Returns true if this system implements the Security Extensions */
19110037SARM gem5 Developers    bool haveSecurity() const { return _haveSecurity; }
19210037SARM gem5 Developers
19310037SARM gem5 Developers    /** Returns true if this system implements the Large Physical Address
19410037SARM gem5 Developers     * Extension */
19510037SARM gem5 Developers    bool haveLPAE() const { return _haveLPAE; }
19610037SARM gem5 Developers
19710037SARM gem5 Developers    /** Returns true if this system implements the virtualization
19810037SARM gem5 Developers      * Extensions
19910037SARM gem5 Developers      */
20010037SARM gem5 Developers    bool haveVirtualization() const { return _haveVirtualization; }
20110037SARM gem5 Developers
20213173Sgiacomo.travaglini@arm.com    /** Returns true if this system implements the Crypto
20313173Sgiacomo.travaglini@arm.com      * Extension
20413173Sgiacomo.travaglini@arm.com      */
20513173Sgiacomo.travaglini@arm.com    bool haveCrypto() const { return _haveCrypto; }
20613173Sgiacomo.travaglini@arm.com
20710037SARM gem5 Developers    /** Sets the pointer to the Generic Timer. */
20810037SARM gem5 Developers    void setGenericTimer(GenericTimer *generic_timer)
20910037SARM gem5 Developers    {
21010037SARM gem5 Developers        _genericTimer = generic_timer;
21110037SARM gem5 Developers    }
21210037SARM gem5 Developers
21313531Sjairo.balart@metempsy.com    /** Sets the pointer to the GIC. */
21413531Sjairo.balart@metempsy.com    void setGIC(BaseGic *gic)
21513531Sjairo.balart@metempsy.com    {
21613531Sjairo.balart@metempsy.com        _gic = gic;
21713531Sjairo.balart@metempsy.com    }
21813531Sjairo.balart@metempsy.com
21910844Sandreas.sandberg@arm.com    /** Get a pointer to the system's generic timer model */
22010844Sandreas.sandberg@arm.com    GenericTimer *getGenericTimer() const { return _genericTimer; }
22110037SARM gem5 Developers
22213531Sjairo.balart@metempsy.com    /** Get a pointer to the system's GIC */
22313531Sjairo.balart@metempsy.com    BaseGic *getGIC() const { return _gic; }
22413531Sjairo.balart@metempsy.com
22510037SARM gem5 Developers    /** Returns true if the register width of the highest implemented exception
22610037SARM gem5 Developers     * level is 64 bits (ARMv8) */
22710037SARM gem5 Developers    bool highestELIs64() const { return _highestELIs64; }
22810037SARM gem5 Developers
22910037SARM gem5 Developers    /** Returns the highest implemented exception level */
23010037SARM gem5 Developers    ExceptionLevel highestEL() const
23110037SARM gem5 Developers    {
23210037SARM gem5 Developers        if (_haveSecurity)
23310037SARM gem5 Developers            return EL3;
23411574SCurtis.Dunham@arm.com        if (_haveVirtualization)
23511574SCurtis.Dunham@arm.com            return EL2;
23610037SARM gem5 Developers        return EL1;
23710037SARM gem5 Developers    }
23810037SARM gem5 Developers
23910037SARM gem5 Developers    /** Returns the reset address if the highest implemented exception level is
24010037SARM gem5 Developers     * 64 bits (ARMv8) */
24113396Sgiacomo.travaglini@arm.com    Addr resetAddr() const { return _resetAddr; }
24210037SARM gem5 Developers
24310037SARM gem5 Developers    /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */
24410037SARM gem5 Developers    bool haveLargeAsid64() const { return _haveLargeAsid64; }
24510037SARM gem5 Developers
24613759Sgiacomo.gabrielli@arm.com    /** Returns true if SVE is implemented (ARMv8) */
24713759Sgiacomo.gabrielli@arm.com    bool haveSVE() const { return _haveSVE; }
24813759Sgiacomo.gabrielli@arm.com
24913759Sgiacomo.gabrielli@arm.com    /** Returns the SVE vector length at reset, in quadwords */
25013759Sgiacomo.gabrielli@arm.com    unsigned sveVL() const { return _sveVL; }
25113759Sgiacomo.gabrielli@arm.com
25214133Sjordi.vaquero@metempsy.com    /** Returns true if LSE is implemented (ARMv8.1) */
25314133Sjordi.vaquero@metempsy.com    bool haveLSE() const { return _haveLSE; }
25414133Sjordi.vaquero@metempsy.com
25514128Sgiacomo.travaglini@arm.com    /** Returns true if Priviledge Access Never is implemented */
25614128Sgiacomo.travaglini@arm.com    bool havePAN() const { return _havePAN; }
25714128Sgiacomo.travaglini@arm.com
25810037SARM gem5 Developers    /** Returns the supported physical address range in bits if the highest
25910037SARM gem5 Developers     * implemented exception level is 64 bits (ARMv8) */
26010037SARM gem5 Developers    uint8_t physAddrRange64() const { return _physAddrRange64; }
26110037SARM gem5 Developers
26210037SARM gem5 Developers    /** Returns the supported physical address range in bits */
26310037SARM gem5 Developers    uint8_t physAddrRange() const
26410037SARM gem5 Developers    {
26510037SARM gem5 Developers        if (_highestELIs64)
26610037SARM gem5 Developers            return _physAddrRange64;
26710037SARM gem5 Developers        if (_haveLPAE)
26810037SARM gem5 Developers            return 40;
26910037SARM gem5 Developers        return 32;
27010037SARM gem5 Developers    }
27110037SARM gem5 Developers
27210037SARM gem5 Developers    /** Returns the physical address mask */
27310037SARM gem5 Developers    Addr physAddrMask() const
27410037SARM gem5 Developers    {
27510037SARM gem5 Developers        return mask(physAddrRange());
27610037SARM gem5 Developers    }
27710037SARM gem5 Developers
27812005Sandreas.sandberg@arm.com    /**
27912005Sandreas.sandberg@arm.com     * Range used by memory-mapped m5 pseudo-ops if enabled. Returns
28012005Sandreas.sandberg@arm.com     * an invalid/empty range if disabled.
28112005Sandreas.sandberg@arm.com     */
28212005Sandreas.sandberg@arm.com    const AddrRange &m5opRange() const { return _m5opRange; }
28312005Sandreas.sandberg@arm.com
28412531Sandreas.sandberg@arm.com    /** Is Arm Semihosting support enabled? */
28512531Sandreas.sandberg@arm.com    bool haveSemihosting() const { return semihosting != nullptr; }
28612531Sandreas.sandberg@arm.com
28712317Sgiacomo.travaglini@arm.com    /**
28812317Sgiacomo.travaglini@arm.com     * Returns a valid ArmSystem pointer if using ARM ISA, it fails
28912317Sgiacomo.travaglini@arm.com     * otherwise.
29012317Sgiacomo.travaglini@arm.com     */
29112317Sgiacomo.travaglini@arm.com    static ArmSystem* getArmSystem(ThreadContext *tc);
29212317Sgiacomo.travaglini@arm.com
29310037SARM gem5 Developers    /** Returns true if the system of a specific thread context implements the
29410037SARM gem5 Developers     * Security Extensions
29510037SARM gem5 Developers     */
29610037SARM gem5 Developers    static bool haveSecurity(ThreadContext *tc);
29710037SARM gem5 Developers
29810037SARM gem5 Developers    /** Returns true if the system of a specific thread context implements the
29910037SARM gem5 Developers     * virtualization Extensions
30010037SARM gem5 Developers     */
30110037SARM gem5 Developers    static bool haveVirtualization(ThreadContext *tc);
30210037SARM gem5 Developers
30310037SARM gem5 Developers    /** Returns true if the system of a specific thread context implements the
30410037SARM gem5 Developers     * Large Physical Address Extension
30510037SARM gem5 Developers     */
30610037SARM gem5 Developers    static bool haveLPAE(ThreadContext *tc);
30710037SARM gem5 Developers
30810037SARM gem5 Developers    /** Returns true if the register width of the highest implemented exception
30910037SARM gem5 Developers     * level for the system of a specific thread context is 64 bits (ARMv8)
31010037SARM gem5 Developers     */
31110037SARM gem5 Developers    static bool highestELIs64(ThreadContext *tc);
31210037SARM gem5 Developers
31310037SARM gem5 Developers    /** Returns the highest implemented exception level for the system of a
31410037SARM gem5 Developers     * specific thread context
31510037SARM gem5 Developers     */
31610037SARM gem5 Developers    static ExceptionLevel highestEL(ThreadContext *tc);
31710037SARM gem5 Developers
31812318Sgiacomo.travaglini@arm.com    /** Return true if the system implements a specific exception level */
31912318Sgiacomo.travaglini@arm.com    static bool haveEL(ThreadContext *tc, ExceptionLevel el);
32012318Sgiacomo.travaglini@arm.com
32112318Sgiacomo.travaglini@arm.com    /** Returns the reset address if the highest implemented exception level
32212318Sgiacomo.travaglini@arm.com     * for the system of a specific thread context is 64 bits (ARMv8)
32310037SARM gem5 Developers     */
32413396Sgiacomo.travaglini@arm.com    static Addr resetAddr(ThreadContext *tc);
32510037SARM gem5 Developers
32610037SARM gem5 Developers    /** Returns the supported physical address range in bits for the system of a
32710037SARM gem5 Developers     * specific thread context
32810037SARM gem5 Developers     */
32910037SARM gem5 Developers    static uint8_t physAddrRange(ThreadContext *tc);
33010037SARM gem5 Developers
33110037SARM gem5 Developers    /** Returns the physical address mask for the system of a specific thread
33210037SARM gem5 Developers     * context
33310037SARM gem5 Developers     */
33410037SARM gem5 Developers    static Addr physAddrMask(ThreadContext *tc);
33510037SARM gem5 Developers
33610037SARM gem5 Developers    /** Returns true if ASID is 16 bits for the system of a specific thread
33710037SARM gem5 Developers     * context while in AArch64 (ARMv8) */
33810037SARM gem5 Developers    static bool haveLargeAsid64(ThreadContext *tc);
33912531Sandreas.sandberg@arm.com
34012531Sandreas.sandberg@arm.com    /** Is Arm Semihosting support enabled? */
34112531Sandreas.sandberg@arm.com    static bool haveSemihosting(ThreadContext *tc);
34212531Sandreas.sandberg@arm.com
34312531Sandreas.sandberg@arm.com    /** Make a Semihosting call from aarch64 */
34412531Sandreas.sandberg@arm.com    static uint64_t callSemihosting64(ThreadContext *tc,
34512531Sandreas.sandberg@arm.com                                      uint32_t op, uint64_t param);
34612531Sandreas.sandberg@arm.com
34712531Sandreas.sandberg@arm.com    /** Make a Semihosting call from aarch32 */
34812531Sandreas.sandberg@arm.com    static uint32_t callSemihosting32(ThreadContext *tc,
34912531Sandreas.sandberg@arm.com                                      uint32_t op, uint32_t param);
35010810Sbr@bsdpad.com};
35110037SARM gem5 Developers
35210810Sbr@bsdpad.comclass GenericArmSystem : public ArmSystem
35310810Sbr@bsdpad.com{
35410810Sbr@bsdpad.com  public:
35510810Sbr@bsdpad.com    typedef GenericArmSystemParams Params;
35610810Sbr@bsdpad.com    const Params *
35710810Sbr@bsdpad.com    params() const
35810810Sbr@bsdpad.com    {
35910810Sbr@bsdpad.com        return dynamic_cast<const Params *>(_params);
36010810Sbr@bsdpad.com    }
36110810Sbr@bsdpad.com
36210810Sbr@bsdpad.com    GenericArmSystem(Params *p) : ArmSystem(p) {};
36310810Sbr@bsdpad.com    virtual ~GenericArmSystem() {};
36410810Sbr@bsdpad.com
36510810Sbr@bsdpad.com    /**
36610810Sbr@bsdpad.com     * Initialise the system
36710810Sbr@bsdpad.com     */
36810810Sbr@bsdpad.com    virtual void initState();
3692567SN/A};
3702567SN/A
3712567SN/A#endif
372