system.hh revision 14128
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
13314128Sgiacomo.travaglini@arm.com    /** True if Priviledge Access Never is implemented */
13414128Sgiacomo.travaglini@arm.com    const unsigned _havePAN;
13514128Sgiacomo.travaglini@arm.com
13613759Sgiacomo.gabrielli@arm.com    /**
13712005Sandreas.sandberg@arm.com     * Range for memory-mapped m5 pseudo ops. The range will be
13812005Sandreas.sandberg@arm.com     * invalid/empty if disabled.
13912005Sandreas.sandberg@arm.com     */
14012005Sandreas.sandberg@arm.com    const AddrRange _m5opRange;
14112005Sandreas.sandberg@arm.com
14212531Sandreas.sandberg@arm.com    /**
14312531Sandreas.sandberg@arm.com     * True if the Semihosting interface is enabled.
14412531Sandreas.sandberg@arm.com     */
14512531Sandreas.sandberg@arm.com    ArmSemihosting *const semihosting;
14612531Sandreas.sandberg@arm.com
14711234Sandreas.sandberg@arm.com  protected:
14811234Sandreas.sandberg@arm.com    /**
14911234Sandreas.sandberg@arm.com     * Get a boot loader that matches the kernel.
15011234Sandreas.sandberg@arm.com     *
15111234Sandreas.sandberg@arm.com     * @param obj Kernel binary
15211234Sandreas.sandberg@arm.com     * @return Pointer to boot loader ObjectFile or nullptr if there
15311234Sandreas.sandberg@arm.com     *         is no matching boot loader.
15411234Sandreas.sandberg@arm.com     */
15511234Sandreas.sandberg@arm.com    ObjectFile *getBootLoader(ObjectFile *const obj);
15611234Sandreas.sandberg@arm.com
1572567SN/A  public:
1586757SAli.Saidi@ARM.com    typedef ArmSystemParams Params;
1598286SAli.Saidi@ARM.com    const Params *
1608286SAli.Saidi@ARM.com    params() const
1618286SAli.Saidi@ARM.com    {
1628286SAli.Saidi@ARM.com        return dynamic_cast<const Params *>(_params);
1638286SAli.Saidi@ARM.com    }
1648286SAli.Saidi@ARM.com
1656757SAli.Saidi@ARM.com    ArmSystem(Params *p);
1666757SAli.Saidi@ARM.com    ~ArmSystem();
1678286SAli.Saidi@ARM.com
1688706Sandreas.hansson@arm.com    /**
1698706Sandreas.hansson@arm.com     * Initialise the system
1708706Sandreas.hansson@arm.com     */
1718706Sandreas.hansson@arm.com    virtual void initState();
1728286SAli.Saidi@ARM.com
1733553SN/A    virtual Addr fixFuncEventAddr(Addr addr)
1743553SN/A    {
1757693SAli.Saidi@ARM.com        // Remove the low bit that thumb symbols have set
1767693SAli.Saidi@ARM.com        // but that aren't actually odd aligned
1777693SAli.Saidi@ARM.com        if (addr & 0x1)
1787720Sgblack@eecs.umich.edu            return addr & ~1;
1793553SN/A        return addr;
1803553SN/A    }
1819050Schander.sudanthi@arm.com
1829050Schander.sudanthi@arm.com    /** true if this a multiprocessor system */
1839050Schander.sudanthi@arm.com    bool multiProc;
18410037SARM gem5 Developers
18510037SARM gem5 Developers    /** Returns true if this system implements the Security Extensions */
18610037SARM gem5 Developers    bool haveSecurity() const { return _haveSecurity; }
18710037SARM gem5 Developers
18810037SARM gem5 Developers    /** Returns true if this system implements the Large Physical Address
18910037SARM gem5 Developers     * Extension */
19010037SARM gem5 Developers    bool haveLPAE() const { return _haveLPAE; }
19110037SARM gem5 Developers
19210037SARM gem5 Developers    /** Returns true if this system implements the virtualization
19310037SARM gem5 Developers      * Extensions
19410037SARM gem5 Developers      */
19510037SARM gem5 Developers    bool haveVirtualization() const { return _haveVirtualization; }
19610037SARM gem5 Developers
19713173Sgiacomo.travaglini@arm.com    /** Returns true if this system implements the Crypto
19813173Sgiacomo.travaglini@arm.com      * Extension
19913173Sgiacomo.travaglini@arm.com      */
20013173Sgiacomo.travaglini@arm.com    bool haveCrypto() const { return _haveCrypto; }
20113173Sgiacomo.travaglini@arm.com
20210037SARM gem5 Developers    /** Sets the pointer to the Generic Timer. */
20310037SARM gem5 Developers    void setGenericTimer(GenericTimer *generic_timer)
20410037SARM gem5 Developers    {
20510037SARM gem5 Developers        _genericTimer = generic_timer;
20610037SARM gem5 Developers    }
20710037SARM gem5 Developers
20813531Sjairo.balart@metempsy.com    /** Sets the pointer to the GIC. */
20913531Sjairo.balart@metempsy.com    void setGIC(BaseGic *gic)
21013531Sjairo.balart@metempsy.com    {
21113531Sjairo.balart@metempsy.com        _gic = gic;
21213531Sjairo.balart@metempsy.com    }
21313531Sjairo.balart@metempsy.com
21410844Sandreas.sandberg@arm.com    /** Get a pointer to the system's generic timer model */
21510844Sandreas.sandberg@arm.com    GenericTimer *getGenericTimer() const { return _genericTimer; }
21610037SARM gem5 Developers
21713531Sjairo.balart@metempsy.com    /** Get a pointer to the system's GIC */
21813531Sjairo.balart@metempsy.com    BaseGic *getGIC() const { return _gic; }
21913531Sjairo.balart@metempsy.com
22010037SARM gem5 Developers    /** Returns true if the register width of the highest implemented exception
22110037SARM gem5 Developers     * level is 64 bits (ARMv8) */
22210037SARM gem5 Developers    bool highestELIs64() const { return _highestELIs64; }
22310037SARM gem5 Developers
22410037SARM gem5 Developers    /** Returns the highest implemented exception level */
22510037SARM gem5 Developers    ExceptionLevel highestEL() const
22610037SARM gem5 Developers    {
22710037SARM gem5 Developers        if (_haveSecurity)
22810037SARM gem5 Developers            return EL3;
22911574SCurtis.Dunham@arm.com        if (_haveVirtualization)
23011574SCurtis.Dunham@arm.com            return EL2;
23110037SARM gem5 Developers        return EL1;
23210037SARM gem5 Developers    }
23310037SARM gem5 Developers
23410037SARM gem5 Developers    /** Returns the reset address if the highest implemented exception level is
23510037SARM gem5 Developers     * 64 bits (ARMv8) */
23613396Sgiacomo.travaglini@arm.com    Addr resetAddr() const { return _resetAddr; }
23710037SARM gem5 Developers
23810037SARM gem5 Developers    /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */
23910037SARM gem5 Developers    bool haveLargeAsid64() const { return _haveLargeAsid64; }
24010037SARM gem5 Developers
24113759Sgiacomo.gabrielli@arm.com    /** Returns true if SVE is implemented (ARMv8) */
24213759Sgiacomo.gabrielli@arm.com    bool haveSVE() const { return _haveSVE; }
24313759Sgiacomo.gabrielli@arm.com
24413759Sgiacomo.gabrielli@arm.com    /** Returns the SVE vector length at reset, in quadwords */
24513759Sgiacomo.gabrielli@arm.com    unsigned sveVL() const { return _sveVL; }
24613759Sgiacomo.gabrielli@arm.com
24714128Sgiacomo.travaglini@arm.com    /** Returns true if Priviledge Access Never is implemented */
24814128Sgiacomo.travaglini@arm.com    bool havePAN() const { return _havePAN; }
24914128Sgiacomo.travaglini@arm.com
25010037SARM gem5 Developers    /** Returns the supported physical address range in bits if the highest
25110037SARM gem5 Developers     * implemented exception level is 64 bits (ARMv8) */
25210037SARM gem5 Developers    uint8_t physAddrRange64() const { return _physAddrRange64; }
25310037SARM gem5 Developers
25410037SARM gem5 Developers    /** Returns the supported physical address range in bits */
25510037SARM gem5 Developers    uint8_t physAddrRange() const
25610037SARM gem5 Developers    {
25710037SARM gem5 Developers        if (_highestELIs64)
25810037SARM gem5 Developers            return _physAddrRange64;
25910037SARM gem5 Developers        if (_haveLPAE)
26010037SARM gem5 Developers            return 40;
26110037SARM gem5 Developers        return 32;
26210037SARM gem5 Developers    }
26310037SARM gem5 Developers
26410037SARM gem5 Developers    /** Returns the physical address mask */
26510037SARM gem5 Developers    Addr physAddrMask() const
26610037SARM gem5 Developers    {
26710037SARM gem5 Developers        return mask(physAddrRange());
26810037SARM gem5 Developers    }
26910037SARM gem5 Developers
27012005Sandreas.sandberg@arm.com    /**
27112005Sandreas.sandberg@arm.com     * Range used by memory-mapped m5 pseudo-ops if enabled. Returns
27212005Sandreas.sandberg@arm.com     * an invalid/empty range if disabled.
27312005Sandreas.sandberg@arm.com     */
27412005Sandreas.sandberg@arm.com    const AddrRange &m5opRange() const { return _m5opRange; }
27512005Sandreas.sandberg@arm.com
27612531Sandreas.sandberg@arm.com    /** Is Arm Semihosting support enabled? */
27712531Sandreas.sandberg@arm.com    bool haveSemihosting() const { return semihosting != nullptr; }
27812531Sandreas.sandberg@arm.com
27912317Sgiacomo.travaglini@arm.com    /**
28012317Sgiacomo.travaglini@arm.com     * Returns a valid ArmSystem pointer if using ARM ISA, it fails
28112317Sgiacomo.travaglini@arm.com     * otherwise.
28212317Sgiacomo.travaglini@arm.com     */
28312317Sgiacomo.travaglini@arm.com    static ArmSystem* getArmSystem(ThreadContext *tc);
28412317Sgiacomo.travaglini@arm.com
28510037SARM gem5 Developers    /** Returns true if the system of a specific thread context implements the
28610037SARM gem5 Developers     * Security Extensions
28710037SARM gem5 Developers     */
28810037SARM gem5 Developers    static bool haveSecurity(ThreadContext *tc);
28910037SARM gem5 Developers
29010037SARM gem5 Developers    /** Returns true if the system of a specific thread context implements the
29110037SARM gem5 Developers     * virtualization Extensions
29210037SARM gem5 Developers     */
29310037SARM gem5 Developers    static bool haveVirtualization(ThreadContext *tc);
29410037SARM gem5 Developers
29510037SARM gem5 Developers    /** Returns true if the system of a specific thread context implements the
29610037SARM gem5 Developers     * Large Physical Address Extension
29710037SARM gem5 Developers     */
29810037SARM gem5 Developers    static bool haveLPAE(ThreadContext *tc);
29910037SARM gem5 Developers
30010037SARM gem5 Developers    /** Returns true if the register width of the highest implemented exception
30110037SARM gem5 Developers     * level for the system of a specific thread context is 64 bits (ARMv8)
30210037SARM gem5 Developers     */
30310037SARM gem5 Developers    static bool highestELIs64(ThreadContext *tc);
30410037SARM gem5 Developers
30510037SARM gem5 Developers    /** Returns the highest implemented exception level for the system of a
30610037SARM gem5 Developers     * specific thread context
30710037SARM gem5 Developers     */
30810037SARM gem5 Developers    static ExceptionLevel highestEL(ThreadContext *tc);
30910037SARM gem5 Developers
31012318Sgiacomo.travaglini@arm.com    /** Return true if the system implements a specific exception level */
31112318Sgiacomo.travaglini@arm.com    static bool haveEL(ThreadContext *tc, ExceptionLevel el);
31212318Sgiacomo.travaglini@arm.com
31312318Sgiacomo.travaglini@arm.com    /** Returns the reset address if the highest implemented exception level
31412318Sgiacomo.travaglini@arm.com     * for the system of a specific thread context is 64 bits (ARMv8)
31510037SARM gem5 Developers     */
31613396Sgiacomo.travaglini@arm.com    static Addr resetAddr(ThreadContext *tc);
31710037SARM gem5 Developers
31810037SARM gem5 Developers    /** Returns the supported physical address range in bits for the system of a
31910037SARM gem5 Developers     * specific thread context
32010037SARM gem5 Developers     */
32110037SARM gem5 Developers    static uint8_t physAddrRange(ThreadContext *tc);
32210037SARM gem5 Developers
32310037SARM gem5 Developers    /** Returns the physical address mask for the system of a specific thread
32410037SARM gem5 Developers     * context
32510037SARM gem5 Developers     */
32610037SARM gem5 Developers    static Addr physAddrMask(ThreadContext *tc);
32710037SARM gem5 Developers
32810037SARM gem5 Developers    /** Returns true if ASID is 16 bits for the system of a specific thread
32910037SARM gem5 Developers     * context while in AArch64 (ARMv8) */
33010037SARM gem5 Developers    static bool haveLargeAsid64(ThreadContext *tc);
33112531Sandreas.sandberg@arm.com
33212531Sandreas.sandberg@arm.com    /** Is Arm Semihosting support enabled? */
33312531Sandreas.sandberg@arm.com    static bool haveSemihosting(ThreadContext *tc);
33412531Sandreas.sandberg@arm.com
33512531Sandreas.sandberg@arm.com    /** Make a Semihosting call from aarch64 */
33612531Sandreas.sandberg@arm.com    static uint64_t callSemihosting64(ThreadContext *tc,
33712531Sandreas.sandberg@arm.com                                      uint32_t op, uint64_t param);
33812531Sandreas.sandberg@arm.com
33912531Sandreas.sandberg@arm.com    /** Make a Semihosting call from aarch32 */
34012531Sandreas.sandberg@arm.com    static uint32_t callSemihosting32(ThreadContext *tc,
34112531Sandreas.sandberg@arm.com                                      uint32_t op, uint32_t param);
34210810Sbr@bsdpad.com};
34310037SARM gem5 Developers
34410810Sbr@bsdpad.comclass GenericArmSystem : public ArmSystem
34510810Sbr@bsdpad.com{
34610810Sbr@bsdpad.com  public:
34710810Sbr@bsdpad.com    typedef GenericArmSystemParams Params;
34810810Sbr@bsdpad.com    const Params *
34910810Sbr@bsdpad.com    params() const
35010810Sbr@bsdpad.com    {
35110810Sbr@bsdpad.com        return dynamic_cast<const Params *>(_params);
35210810Sbr@bsdpad.com    }
35310810Sbr@bsdpad.com
35410810Sbr@bsdpad.com    GenericArmSystem(Params *p) : ArmSystem(p) {};
35510810Sbr@bsdpad.com    virtual ~GenericArmSystem() {};
35610810Sbr@bsdpad.com
35710810Sbr@bsdpad.com    /**
35810810Sbr@bsdpad.com     * Initialise the system
35910810Sbr@bsdpad.com     */
36010810Sbr@bsdpad.com    virtual void initState();
3612567SN/A};
3622567SN/A
3632567SN/A#endif
364