112531Sandreas.sandberg@arm.com/*
212531Sandreas.sandberg@arm.com * Copyright (c) 2018 ARM Limited
312531Sandreas.sandberg@arm.com * All rights reserved
412531Sandreas.sandberg@arm.com *
512531Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
612531Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
712531Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
812531Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
912531Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1012531Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1112531Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1212531Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1312531Sandreas.sandberg@arm.com *
1412531Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1512531Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1612531Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1712531Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1812531Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1912531Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2012531Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2112531Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2212531Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2312531Sandreas.sandberg@arm.com * this software without specific prior written permission.
2412531Sandreas.sandberg@arm.com *
2512531Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2612531Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2712531Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2812531Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2912531Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3012531Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3112531Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3212531Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3312531Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3412531Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3512531Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3612531Sandreas.sandberg@arm.com *
3712531Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3812531Sandreas.sandberg@arm.com */
3912531Sandreas.sandberg@arm.com#ifndef __ARCH_ARM_SEMIHOSTING_HH__
4012531Sandreas.sandberg@arm.com#define __ARCH_ARM_SEMIHOSTING_HH__
4112531Sandreas.sandberg@arm.com
4212531Sandreas.sandberg@arm.com#include <cstdio>
4312531Sandreas.sandberg@arm.com#include <map>
4412531Sandreas.sandberg@arm.com#include <memory>
4512531Sandreas.sandberg@arm.com#include <utility>
4612531Sandreas.sandberg@arm.com#include <vector>
4712531Sandreas.sandberg@arm.com
4812531Sandreas.sandberg@arm.com#include "sim/sim_object.hh"
4912531Sandreas.sandberg@arm.com
5012531Sandreas.sandberg@arm.comstruct ArmSemihostingParams;
5112533Sandreas.sandberg@arm.comclass PortProxy;
5212531Sandreas.sandberg@arm.comclass SerialDevice;
5312531Sandreas.sandberg@arm.comclass ThreadContext;
5412531Sandreas.sandberg@arm.com
5512531Sandreas.sandberg@arm.com/**
5612531Sandreas.sandberg@arm.com * Semihosting for AArch32 and AArch64
5712531Sandreas.sandberg@arm.com *
5812531Sandreas.sandberg@arm.com * This class implements the Arm semihosting interface. This interface
5912531Sandreas.sandberg@arm.com * allows baremetal code access service, such as IO, from the
6012531Sandreas.sandberg@arm.com * simulator. It is conceptually a simplified version of gem5's more
6112531Sandreas.sandberg@arm.com * general syscall emulation mode.
6212531Sandreas.sandberg@arm.com *
6312531Sandreas.sandberg@arm.com * Exits calls (SYS_EXIT, SYS_EXIT_EXTENDED) from the guest get
6412531Sandreas.sandberg@arm.com * translated into simualtion exits. Well-known exit codes are
6512531Sandreas.sandberg@arm.com * translated to messages on the form 'semi:ADP_.*' while unknown
6612531Sandreas.sandberg@arm.com * codes are returned in hex ('semi:0x..'). The subcode is reported in
6712531Sandreas.sandberg@arm.com * the gem5 exit event.
6812531Sandreas.sandberg@arm.com */
6912531Sandreas.sandberg@arm.comclass ArmSemihosting : public SimObject
7012531Sandreas.sandberg@arm.com{
7112531Sandreas.sandberg@arm.com  public:
7212531Sandreas.sandberg@arm.com    ArmSemihosting(const ArmSemihostingParams *p);
7312531Sandreas.sandberg@arm.com
7412531Sandreas.sandberg@arm.com    /** Perform an Arm Semihosting call from aarch64 code. */
7512531Sandreas.sandberg@arm.com    uint64_t call64(ThreadContext *tc, uint32_t op, uint64_t param);
7612531Sandreas.sandberg@arm.com    /** Perform an Arm Semihosting call from aarch32 code. */
7712531Sandreas.sandberg@arm.com    uint32_t call32(ThreadContext *tc, uint32_t op, uint32_t param);
7812531Sandreas.sandberg@arm.com
7912531Sandreas.sandberg@arm.com  public: // SimObject and related interfaces
8012531Sandreas.sandberg@arm.com    void serialize(CheckpointOut &cp) const override;
8112531Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp) override;
8212531Sandreas.sandberg@arm.com
8312531Sandreas.sandberg@arm.com  protected: // Configuration
8412531Sandreas.sandberg@arm.com    const std::string cmdLine;
8512531Sandreas.sandberg@arm.com    const Addr memReserve;
8612531Sandreas.sandberg@arm.com    const Addr stackSize;
8712531Sandreas.sandberg@arm.com
8812531Sandreas.sandberg@arm.com    /**
8912531Sandreas.sandberg@arm.com     * Base time when the simulation started. This is used to
9012531Sandreas.sandberg@arm.com     * calculate the time of date when the guest call SYS_TIME.
9112531Sandreas.sandberg@arm.com     */
9212531Sandreas.sandberg@arm.com    const time_t timeBase;
9312531Sandreas.sandberg@arm.com
9412531Sandreas.sandberg@arm.com    /** Number of bits to right shift gem5 ticks to fit in a uint32_t */
9512531Sandreas.sandberg@arm.com    const unsigned tickShift;
9612531Sandreas.sandberg@arm.com
9712531Sandreas.sandberg@arm.com  protected: // Internal state
9812531Sandreas.sandberg@arm.com    typedef uint64_t SemiErrno;
9912531Sandreas.sandberg@arm.com    SemiErrno semiErrno;
10012531Sandreas.sandberg@arm.com
10112531Sandreas.sandberg@arm.com  protected: // File IO
10212531Sandreas.sandberg@arm.com    /**
10312531Sandreas.sandberg@arm.com     * Internal state for open files
10412531Sandreas.sandberg@arm.com     *
10512531Sandreas.sandberg@arm.com     * This class describes the internal state of a file opened
10612531Sandreas.sandberg@arm.com     * through the semihosting interface.
10712531Sandreas.sandberg@arm.com     *
10812531Sandreas.sandberg@arm.com     * A file instance is normally created using one of the
10912531Sandreas.sandberg@arm.com     * ArmSemihosting::FileBase::create() factory methods. These
11012531Sandreas.sandberg@arm.com     * methods handle some the magic file names in the Arm Semihosting
11112531Sandreas.sandberg@arm.com     * specification and instantiate the right implementation. For the
11212531Sandreas.sandberg@arm.com     * same, when unserializing a checkpoint, the create method must
11312531Sandreas.sandberg@arm.com     * be used to unserialize a new instance of a file descriptor.
11412531Sandreas.sandberg@arm.com     */
11512531Sandreas.sandberg@arm.com    class FileBase : public Serializable
11612531Sandreas.sandberg@arm.com    {
11712531Sandreas.sandberg@arm.com      public:
11812531Sandreas.sandberg@arm.com        FileBase(ArmSemihosting &_parent, const char *name, const char *_mode)
11912531Sandreas.sandberg@arm.com            : parent(_parent), _name(name), mode(_mode) {}
12012531Sandreas.sandberg@arm.com        virtual ~FileBase() {};
12112531Sandreas.sandberg@arm.com
12212531Sandreas.sandberg@arm.com        FileBase() = delete;
12312531Sandreas.sandberg@arm.com        FileBase(FileBase &) = delete;
12412531Sandreas.sandberg@arm.com
12512531Sandreas.sandberg@arm.com        static std::unique_ptr<FileBase> create(
12612531Sandreas.sandberg@arm.com            ArmSemihosting &parent, const std::string &fname,
12712531Sandreas.sandberg@arm.com            const char *mode);
12812531Sandreas.sandberg@arm.com        static std::unique_ptr<FileBase> create(
12912531Sandreas.sandberg@arm.com            ArmSemihosting &parent, CheckpointIn &cp, const std::string &sec);
13012531Sandreas.sandberg@arm.com
13112531Sandreas.sandberg@arm.com        void serialize(CheckpointOut &cp) const override;
13212531Sandreas.sandberg@arm.com        void unserialize(CheckpointIn &cp) override;
13312531Sandreas.sandberg@arm.com
13412531Sandreas.sandberg@arm.com        const std::string &fileName() { return _name; }
13512531Sandreas.sandberg@arm.com
13612531Sandreas.sandberg@arm.com      public:
13712531Sandreas.sandberg@arm.com        /** @{
13812531Sandreas.sandberg@arm.com         * Semihosting file IO interfaces
13912531Sandreas.sandberg@arm.com         *
14012531Sandreas.sandberg@arm.com         * These interfaces implement common IO functionality in the
14112531Sandreas.sandberg@arm.com         * Semihosting interface.
14212531Sandreas.sandberg@arm.com         *
14312531Sandreas.sandberg@arm.com         * All functions return a negative value that corresponds to a
14412531Sandreas.sandberg@arm.com         * UNIX errno value when they fail and >=0 on success.
14512531Sandreas.sandberg@arm.com         */
14612531Sandreas.sandberg@arm.com
14712531Sandreas.sandberg@arm.com        /**
14812531Sandreas.sandberg@arm.com         * Open the the file.
14912531Sandreas.sandberg@arm.com         *
15012531Sandreas.sandberg@arm.com         * @return <0 on error (-errno), 0 on success.
15112531Sandreas.sandberg@arm.com         */
15212531Sandreas.sandberg@arm.com        virtual int64_t open() { return 0; }
15312531Sandreas.sandberg@arm.com
15412531Sandreas.sandberg@arm.com        /**
15512531Sandreas.sandberg@arm.com         * Close the file.
15612531Sandreas.sandberg@arm.com         *
15712531Sandreas.sandberg@arm.com         * @return <0 on error (-errno), 0 on success.
15812531Sandreas.sandberg@arm.com         */
15912531Sandreas.sandberg@arm.com        virtual int64_t close() { return 0; }
16012531Sandreas.sandberg@arm.com
16112531Sandreas.sandberg@arm.com        /**
16212531Sandreas.sandberg@arm.com         * Check if a file corresponds to a TTY device.
16312531Sandreas.sandberg@arm.com         *
16412531Sandreas.sandberg@arm.com         * @return True if the file is a TTY, false otherwise.
16512531Sandreas.sandberg@arm.com         */
16612531Sandreas.sandberg@arm.com        virtual bool isTTY() const { return false; }
16712531Sandreas.sandberg@arm.com
16812531Sandreas.sandberg@arm.com        /**
16912531Sandreas.sandberg@arm.com         * Read data from file.
17012531Sandreas.sandberg@arm.com         *
17112531Sandreas.sandberg@arm.com         * @return <0 on error (-errno), bytes read on success (0 for EOF).
17212531Sandreas.sandberg@arm.com         */
17312531Sandreas.sandberg@arm.com        virtual int64_t read(uint8_t *buffer, uint64_t size);
17412531Sandreas.sandberg@arm.com
17512531Sandreas.sandberg@arm.com        /**
17612531Sandreas.sandberg@arm.com         * Write data to file.
17712531Sandreas.sandberg@arm.com         *
17812531Sandreas.sandberg@arm.com         * @return <0 on error (-errno), bytes written on success.
17912531Sandreas.sandberg@arm.com         */
18012531Sandreas.sandberg@arm.com        virtual int64_t write(const uint8_t *buffer, uint64_t size);
18112531Sandreas.sandberg@arm.com
18212531Sandreas.sandberg@arm.com        /**
18312531Sandreas.sandberg@arm.com         * Seek to an absolute position in the file.
18412531Sandreas.sandberg@arm.com         *
18512531Sandreas.sandberg@arm.com         * @param pos Byte offset from start of file.
18612531Sandreas.sandberg@arm.com         * @return <0 on error (-errno), 0 on success.
18712531Sandreas.sandberg@arm.com         */
18812531Sandreas.sandberg@arm.com        virtual int64_t seek(uint64_t pos);
18912531Sandreas.sandberg@arm.com
19012531Sandreas.sandberg@arm.com        /**
19112531Sandreas.sandberg@arm.com         * Get the length of a file in bytes.
19212531Sandreas.sandberg@arm.com         *
19312531Sandreas.sandberg@arm.com         * @return <0 on error (-errno), length on success
19412531Sandreas.sandberg@arm.com         */
19512531Sandreas.sandberg@arm.com        virtual int64_t flen();
19612531Sandreas.sandberg@arm.com
19712531Sandreas.sandberg@arm.com        /** @} */
19812531Sandreas.sandberg@arm.com
19912531Sandreas.sandberg@arm.com      protected:
20012531Sandreas.sandberg@arm.com        ArmSemihosting &parent;
20112531Sandreas.sandberg@arm.com        std::string _name;
20212531Sandreas.sandberg@arm.com        std::string mode;
20312531Sandreas.sandberg@arm.com    };
20412531Sandreas.sandberg@arm.com
20512531Sandreas.sandberg@arm.com    /** Implementation of the ':semihosting-features' magic file. */
20612531Sandreas.sandberg@arm.com    class FileFeatures : public FileBase
20712531Sandreas.sandberg@arm.com    {
20812531Sandreas.sandberg@arm.com      public:
20912531Sandreas.sandberg@arm.com        FileFeatures(ArmSemihosting &_parent,
21012531Sandreas.sandberg@arm.com                     const char *name, const char *mode);
21112531Sandreas.sandberg@arm.com
21212531Sandreas.sandberg@arm.com        void serialize(CheckpointOut &cp) const override;
21312531Sandreas.sandberg@arm.com        void unserialize(CheckpointIn &cp) override;
21412531Sandreas.sandberg@arm.com
21512531Sandreas.sandberg@arm.com        int64_t read(uint8_t *buffer, uint64_t size) override;
21612531Sandreas.sandberg@arm.com        int64_t seek(uint64_t pos) override;
21712531Sandreas.sandberg@arm.com
21812531Sandreas.sandberg@arm.com      protected:
21912531Sandreas.sandberg@arm.com        size_t pos;
22012531Sandreas.sandberg@arm.com    };
22112531Sandreas.sandberg@arm.com
22212531Sandreas.sandberg@arm.com    class File : public FileBase
22312531Sandreas.sandberg@arm.com    {
22412531Sandreas.sandberg@arm.com      public:
22512531Sandreas.sandberg@arm.com        File(ArmSemihosting &_parent, const char *name, const char *mode);
22612531Sandreas.sandberg@arm.com        ~File();
22712531Sandreas.sandberg@arm.com
22812531Sandreas.sandberg@arm.com        void serialize(CheckpointOut &cp) const override;
22912531Sandreas.sandberg@arm.com        void unserialize(CheckpointIn &cp) override;
23012531Sandreas.sandberg@arm.com
23112531Sandreas.sandberg@arm.com        int64_t open() override { return openImpl(false); }
23212531Sandreas.sandberg@arm.com        int64_t close() override;
23312531Sandreas.sandberg@arm.com        bool isTTY() const override;
23412531Sandreas.sandberg@arm.com        int64_t read(uint8_t *buffer, uint64_t size) override;
23512531Sandreas.sandberg@arm.com        int64_t write(const uint8_t *buffer, uint64_t size) override;
23612531Sandreas.sandberg@arm.com        int64_t seek(uint64_t pos) override;
23712531Sandreas.sandberg@arm.com        int64_t flen() override;
23812531Sandreas.sandberg@arm.com
23912531Sandreas.sandberg@arm.com      protected:
24012531Sandreas.sandberg@arm.com        int64_t openImpl(bool unserialize);
24112531Sandreas.sandberg@arm.com        bool needClose() const { return !isTTY(); }
24212531Sandreas.sandberg@arm.com
24312531Sandreas.sandberg@arm.com        FILE *file;
24412531Sandreas.sandberg@arm.com    };
24512531Sandreas.sandberg@arm.com
24612531Sandreas.sandberg@arm.com    std::vector<std::unique_ptr<FileBase>> files;
24712698Sandreas.sandberg@arm.com    FILE *stdin;
24812698Sandreas.sandberg@arm.com    FILE *stdout;
24912698Sandreas.sandberg@arm.com    FILE *stderr;
25012531Sandreas.sandberg@arm.com
25112531Sandreas.sandberg@arm.com  protected: // Helper functions
25212531Sandreas.sandberg@arm.com    unsigned calcTickShift() const {
25312531Sandreas.sandberg@arm.com        int msb = findMsbSet(SimClock::Frequency);
25412531Sandreas.sandberg@arm.com        return msb > 31 ? msb - 31 : 0;
25512531Sandreas.sandberg@arm.com    }
25612531Sandreas.sandberg@arm.com    uint64_t semiTick(Tick tick) const {
25712531Sandreas.sandberg@arm.com        return tick >> tickShift;
25812531Sandreas.sandberg@arm.com    }
25912531Sandreas.sandberg@arm.com    void semiExit(uint64_t code, uint64_t subcode);
26012533Sandreas.sandberg@arm.com    PortProxy &physProxy(ThreadContext *tc);
26112531Sandreas.sandberg@arm.com    std::string readString(ThreadContext *tc, Addr ptr, size_t len);
26212531Sandreas.sandberg@arm.com
26312533Sandreas.sandberg@arm.com    std::unique_ptr<PortProxy> physProxyS;
26412533Sandreas.sandberg@arm.com
26512531Sandreas.sandberg@arm.com  private:
26612531Sandreas.sandberg@arm.com    typedef std::pair<uint64_t, SemiErrno> RetErrno;
26713452SMatteo.Andreozzi@arm.com    static  RetErrno retError(SemiErrno e) {
26812531Sandreas.sandberg@arm.com        return RetErrno((uint64_t)-1, e);
26912531Sandreas.sandberg@arm.com    }
27012531Sandreas.sandberg@arm.com
27113452SMatteo.Andreozzi@arm.com    static  RetErrno retOK(uint64_t r) {
27212531Sandreas.sandberg@arm.com        return RetErrno(r, 0);
27312531Sandreas.sandberg@arm.com    }
27412531Sandreas.sandberg@arm.com
27512531Sandreas.sandberg@arm.com    /**
27612531Sandreas.sandberg@arm.com     * Semihosting call information structure.
27712531Sandreas.sandberg@arm.com     *
27812531Sandreas.sandberg@arm.com     * This structure describes how a semi-hosting call is
27912531Sandreas.sandberg@arm.com     * implemented. It contains debug information (e.g., the name of
28012531Sandreas.sandberg@arm.com     * the call), a pointer to the implementation, and information
28112531Sandreas.sandberg@arm.com     * needed to read its parameters from guest memory.
28212531Sandreas.sandberg@arm.com     */
28312531Sandreas.sandberg@arm.com    struct SemiCall
28412531Sandreas.sandberg@arm.com    {
28512531Sandreas.sandberg@arm.com        /** Call name */
28612531Sandreas.sandberg@arm.com        const char *name;
28712531Sandreas.sandberg@arm.com
28812531Sandreas.sandberg@arm.com        /**
28912531Sandreas.sandberg@arm.com         * Pointer to  call implementation
29012531Sandreas.sandberg@arm.com         *
29112531Sandreas.sandberg@arm.com         * @param tc ThreadContext pointer for caller
29212531Sandreas.sandberg@arm.com         * @param aarch64 True if in aarc64 mode, false otherwise.
29312531Sandreas.sandberg@arm.com         * @parma argv Argument vector. argv[0] always corresponds to
29412531Sandreas.sandberg@arm.com         *             the pointer to the argument list. Remaining
29512531Sandreas.sandberg@arm.com         *             entries are read as consecutive words starting
29612531Sandreas.sandberg@arm.com         *             at the address pointed to by argv[0].
29712531Sandreas.sandberg@arm.com         * @return a (return value, errno) pair
29812531Sandreas.sandberg@arm.com         */
29912531Sandreas.sandberg@arm.com        RetErrno (ArmSemihosting::*call)(ThreadContext *tc, bool aarch64,
30012531Sandreas.sandberg@arm.com                                         std::vector<uint64_t> &argv);
30112531Sandreas.sandberg@arm.com
30212531Sandreas.sandberg@arm.com        /** Number of aarch32 arguments to read from guest memory. -1
30312531Sandreas.sandberg@arm.com         * if unimplemented.*/
30412531Sandreas.sandberg@arm.com        int argc32;
30512531Sandreas.sandberg@arm.com        /** Number of aarch32 arguments to read from guest memory. -1
30612531Sandreas.sandberg@arm.com         * if unimplemented.*/
30712531Sandreas.sandberg@arm.com        int argc64;
30812531Sandreas.sandberg@arm.com
30912531Sandreas.sandberg@arm.com        /** Is call implemented in aarch32? */
31012531Sandreas.sandberg@arm.com        bool implemented32() const { return call && argc32 >= 0; }
31112531Sandreas.sandberg@arm.com        /** Is call implemented in aarch64? */
31212531Sandreas.sandberg@arm.com        bool implemented64() const { return call && argc64 >= 0; }
31312531Sandreas.sandberg@arm.com    };
31412531Sandreas.sandberg@arm.com
31512531Sandreas.sandberg@arm.com#define SEMI_CALL(N)                                                    \
31612531Sandreas.sandberg@arm.com    RetErrno call ## N (ThreadContext *tc,                              \
31712531Sandreas.sandberg@arm.com                        bool aarch64, std::vector<uint64_t> &argv)
31812531Sandreas.sandberg@arm.com
31912531Sandreas.sandberg@arm.com    SEMI_CALL(Open);
32012531Sandreas.sandberg@arm.com    SEMI_CALL(Close);
32112531Sandreas.sandberg@arm.com    SEMI_CALL(WriteC);
32212531Sandreas.sandberg@arm.com    SEMI_CALL(Write0);
32312531Sandreas.sandberg@arm.com    SEMI_CALL(Write);
32412531Sandreas.sandberg@arm.com    SEMI_CALL(Read);
32512531Sandreas.sandberg@arm.com    SEMI_CALL(ReadC);
32612531Sandreas.sandberg@arm.com    SEMI_CALL(IsError);
32712531Sandreas.sandberg@arm.com    SEMI_CALL(IsTTY);
32812531Sandreas.sandberg@arm.com    SEMI_CALL(Seek);
32912531Sandreas.sandberg@arm.com    SEMI_CALL(FLen);
33012531Sandreas.sandberg@arm.com    SEMI_CALL(TmpNam);
33112531Sandreas.sandberg@arm.com    SEMI_CALL(Remove);
33212531Sandreas.sandberg@arm.com    SEMI_CALL(Rename);
33312531Sandreas.sandberg@arm.com    SEMI_CALL(Clock);
33412531Sandreas.sandberg@arm.com    SEMI_CALL(Time);
33512531Sandreas.sandberg@arm.com    SEMI_CALL(System);
33612531Sandreas.sandberg@arm.com    SEMI_CALL(Errno);
33712531Sandreas.sandberg@arm.com    SEMI_CALL(GetCmdLine);
33812531Sandreas.sandberg@arm.com    SEMI_CALL(HeapInfo);
33912531Sandreas.sandberg@arm.com    SEMI_CALL(Exit);
34012531Sandreas.sandberg@arm.com    SEMI_CALL(ExitExtended);
34112531Sandreas.sandberg@arm.com
34212531Sandreas.sandberg@arm.com    SEMI_CALL(Elapsed);
34312531Sandreas.sandberg@arm.com    SEMI_CALL(TickFreq);
34412531Sandreas.sandberg@arm.com
34512531Sandreas.sandberg@arm.com#undef SEMI_CALL
34612531Sandreas.sandberg@arm.com
34712531Sandreas.sandberg@arm.com    static const SemiCall *getCall(uint32_t op, bool aarch64);
34812698Sandreas.sandberg@arm.com    static FILE *getSTDIO(const char *stream_name,
34912698Sandreas.sandberg@arm.com                          const std::string &name, const char *mode);
35012531Sandreas.sandberg@arm.com
35112531Sandreas.sandberg@arm.com    static const std::map<uint32_t, SemiCall> calls;
35212531Sandreas.sandberg@arm.com    static const std::vector<const char *> fmodes;
35312531Sandreas.sandberg@arm.com    static const std::map<uint64_t, const char *> exitCodes;
35412531Sandreas.sandberg@arm.com    static const std::vector<uint8_t> features;
35512698Sandreas.sandberg@arm.com    static const std::map<const std::string, FILE *> stdioMap;
35612531Sandreas.sandberg@arm.com};
35712531Sandreas.sandberg@arm.com
35812531Sandreas.sandberg@arm.com#endif // __ARCH_ARM_SEMIHOSTING_HH__
359