gem5 v24.0.0.0
Loading...
Searching...
No Matches
semihosting.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
39
40#include <unistd.h>
41
42#include <cerrno>
43#include <cstdio>
44
45#include "arch/arm/utility.hh"
46#include "base/output.hh"
47#include "base/time.hh"
48#include "debug/Semihosting.hh"
49#include "dev/serial/serial.hh"
50#include "mem/physical.hh"
53#include "params/ArmSemihosting.hh"
54#include "sim/byteswap.hh"
55#include "sim/full_system.hh"
56#include "sim/pseudo_inst.hh"
57#include "sim/system.hh"
58
59namespace gem5
60{
61
62const std::map<uint32_t, ArmSemihosting::SemiCall> ArmSemihosting::calls{
63 { SYS_OPEN, { "SYS_OPEN", &ArmSemihosting::callOpen } },
64 { SYS_CLOSE, { "SYS_CLOSE", &ArmSemihosting::callClose } },
65 { SYS_WRITEC, { "SYS_WRITEC", &ArmSemihosting::callWriteC } },
66 { SYS_WRITE0, { "SYS_WRITE0", &ArmSemihosting::callWrite0 } },
67 { SYS_WRITE, { "SYS_WRITE", &ArmSemihosting::callWrite } },
68 { SYS_READ, { "SYS_READ", &ArmSemihosting::callRead } },
69 { SYS_READC, { "SYS_READC", &ArmSemihosting::callReadC } },
70 { SYS_ISERROR, { "SYS_ISERROR", &ArmSemihosting::callIsError } },
71 { SYS_ISTTY, { "SYS_ISTTY", &ArmSemihosting::callIsTTY } },
72 { SYS_SEEK, { "SYS_SEEK", &ArmSemihosting::callSeek } },
73 { SYS_FLEN, { "SYS_FLEN", &ArmSemihosting::callFLen } },
74 { SYS_TMPNAM, { "SYS_TMPNAM", &ArmSemihosting::callTmpNam } },
75 { SYS_REMOVE, { "SYS_REMOVE", &ArmSemihosting::callRemove } },
76 { SYS_RENAME, { "SYS_RENAME", &ArmSemihosting::callRename } },
77 { SYS_CLOCK, { "SYS_CLOCK", &ArmSemihosting::callClock } },
78 { SYS_TIME, { "SYS_TIME", &ArmSemihosting::callTime } },
79 { SYS_SYSTEM, { "SYS_SYSTEM", &ArmSemihosting::callSystem } },
80 { SYS_ERRNO, { "SYS_ERRNO", &ArmSemihosting::callErrno } },
81 { SYS_GET_CMDLINE,
82 { "SYS_GET_CMDLINE", &ArmSemihosting::callGetCmdLine } },
83 { SYS_HEAPINFO, { "SYS_HEAPINFO", &ArmSemihosting::callHeapInfo32,
85
86 { SYS_EXIT, { "SYS_EXIT", &ArmSemihosting::callExit32,
88 { SYS_EXIT_EXTENDED,
89 { "SYS_EXIT_EXTENDED", &ArmSemihosting::callExitExtended } },
90
91 { SYS_ELAPSED, { "SYS_ELAPSED", &ArmSemihosting::callElapsed32,
93 { SYS_TICKFREQ, { "SYS_TICKFREQ", &ArmSemihosting::callTickFreq } },
94 { SYS_GEM5_PSEUDO_OP,
95 { "SYS_GEM5_PSEUDO_OP", &ArmSemihosting::callGem5PseudoOp32,
97};
98
99ArmSemihosting::ArmSemihosting(const ArmSemihostingParams &p)
100 : BaseSemihosting(p) {}
101
102bool
104{
106 if (op > MaxStandardOp && !gem5_ops) {
108 tc, "Gem5 semihosting op (0x%x) disabled from here.", op);
109 return false;
110 }
111
112 auto it = calls.find(op);
113 if (it == calls.end()) {
115 tc, "Unknown aarch64 semihosting call: op = 0x%x", op);
116 return false;
117 }
118 const SemiCall &call = it->second;
119
120 DPRINTF(Semihosting, "Semihosting call64: %s\n", call.dump64(tc));
121 auto err = call.call64(this, tc);
122 semiErrno = err.second;
123 DPRINTF(Semihosting, "\t ->: 0x%x, %i\n", err.first, err.second);
124
125 return true;
126}
127
128bool
130{
132 if (op > MaxStandardOp && !gem5_ops) {
134 tc, "Gem5 semihosting op (0x%x) disabled from here.", op);
135 return false;
136 }
137
138 auto it = calls.find(op);
139 if (it == calls.end()) {
141 tc, "Unknown aarch32 semihosting call: op = 0x%x", op);
142 return false;
143 }
144 const SemiCall &call = it->second;
145
146 DPRINTF(Semihosting, "Semihosting call32: %s\n", call.dump32(tc));
147 auto err = call.call32(this, tc);
148 semiErrno = err.second;
149 DPRINTF(Semihosting, "\t ->: 0x%x, %i\n", err.first, err.second);
150
151 return true;
152}
153
154PortProxy &
156{
157 static std::unique_ptr<PortProxy> port_proxy_s;
158 static std::unique_ptr<PortProxy> port_proxy_ns;
159 static System *secure_sys = nullptr;
160
161 if (ArmISA::isSecure(tc)) {
162 System *sys = tc->getSystemPtr();
163 if (sys != secure_sys) {
164 if (FullSystem) {
165 port_proxy_s.reset(
167 } else {
168 port_proxy_s.reset(
172 }
173 }
174 secure_sys = sys;
175 return *port_proxy_s;
176 } else {
177 if (!port_proxy_ns) {
178 if (FullSystem) {
179 port_proxy_ns.reset(new TranslatingPortProxy(tc));
180 } else {
181 port_proxy_ns.reset(new SETranslatingPortProxy(tc));
182 }
183 }
184
185 return *port_proxy_ns;
186 }
187}
188
190{
192 {
193 public:
194 State(const ThreadContext *tc) : ArmSemihosting::Abi32::State(tc)
195 {
196 // Use getAddr() to skip the func number in the first slot.
197 getAddr();
198 }
199 };
200};
201
203{
205 {
206 public:
207 State(const ThreadContext *tc) : ArmSemihosting::Abi64::State(tc)
208 {
209 // Use getAddr() to skip the func number in the first slot.
210 getAddr();
211 }
212 };
213};
214
215namespace guest_abi
216{
217
218// Handle arguments the same as for semihosting operations. Skipping the first
219// slot is handled internally by the State type.
220template <typename T>
222 public Argument<ArmSemihosting::Abi32, T>
223{};
224template <typename T>
226 public Argument<ArmSemihosting::Abi64, T>
227{};
228
229} // namespace guest_abi
230
233{
234 uint8_t func;
235 pseudo_inst::decodeAddrOffset(encoded_func, func);
236
237 uint64_t ret;
239 return retOK(ret);
240 else
241 return retError(EINVAL);
242}
243
246{
247 uint8_t func;
248 pseudo_inst::decodeAddrOffset(encoded_func, func);
249
250 uint64_t ret;
252 return retOK(ret);
253 else
254 return retError(EINVAL);
255}
256
257} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Semihosting for AArch32 and AArch64.
static const std::map< uint32_t, SemiCall > calls
bool call32(ThreadContext *tc, bool gem5_ops)
Perform an Arm Semihosting call from aarch32 code.
static PortProxy & portProxyImpl(ThreadContext *tc)
bool call64(ThreadContext *tc, bool gem5_ops)
Perform an Arm Semihosting call from aarch64 code.
SemiCallBase< ArmSemihosting, Abi32, Abi64 > SemiCall
RetErrno callGem5PseudoOp32(ThreadContext *tc, uint32_t encoded_func)
ArmSemihosting(const ArmSemihostingParams &p)
RetErrno callGem5PseudoOp64(ThreadContext *tc, uint64_t encoded_func)
Semihosting for AArch32, AArch64, RISCV-32 and RISCV-64: https://github.com/ARM-software/abi-aa/blob/...
RetErrno callReadC(ThreadContext *tc)
RetErrno callElapsed32(ThreadContext *tc, InPlaceArg low, InPlaceArg high)
RetErrno callExit64(ThreadContext *tc, uint64_t code, uint64_t subcode)
RetErrno callFLen(ThreadContext *tc, Handle handle)
void unrecognizedCall(ThreadContext *tc, const char *format, uint64_t op)
RetErrno callTickFreq(ThreadContext *tc)
RetErrno callRename(ThreadContext *tc, Addr from_addr, size_t from_size, Addr to_addr, size_t to_size)
RetErrno callExitExtended(ThreadContext *tc, uint64_t code, uint64_t subcode)
RetErrno callTmpNam(ThreadContext *tc, Addr buffer, uint64_t id, size_t size)
RetErrno callSeek(ThreadContext *tc, Handle handle, uint64_t pos)
RetErrno callSystem(ThreadContext *tc, Addr cmd_addr, size_t cmd_size)
RetErrno callWrite(ThreadContext *tc, Handle handle, Addr buffer, size_t size)
RetErrno callOpen(ThreadContext *tc, const Addr name_base, int fmode, size_t name_size)
static RetErrno retError(SemiErrno e)
RetErrno callIsError(ThreadContext *tc, int64_t status)
RetErrno callElapsed64(ThreadContext *tc, InPlaceArg ticks)
RetErrno callRead(ThreadContext *tc, Handle handle, Addr buffer, size_t size)
RetErrno callExit32(ThreadContext *tc, InPlaceArg code)
static RetErrno retOK(uint64_t r)
RetErrno callGetCmdLine(ThreadContext *tc, Addr addr, InPlaceArg size_arg)
RetErrno callHeapInfo32(ThreadContext *tc, Addr block_addr)
RetErrno callClock(ThreadContext *tc)
RetErrno callRemove(ThreadContext *tc, Addr name_base, size_t name_size)
RetErrno callHeapInfo64(ThreadContext *tc, Addr block_addr)
RetErrno callIsTTY(ThreadContext *tc, Handle handle)
RetErrno callWriteC(ThreadContext *tc, InPlaceArg c)
RetErrno callErrno(ThreadContext *tc)
RetErrno callTime(ThreadContext *tc)
RetErrno callWrite0(ThreadContext *tc, InPlaceArg str)
RetErrno callClose(ThreadContext *tc, Handle handle)
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition port_proxy.hh:87
@ SECURE
The request targets the secure memory space.
Definition request.hh:186
State(const ThreadContext *tc)
State(const ThreadContext *tc)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal getReg(const RegId &reg) const
virtual System * getSystemPtr()=0
This proxy attempts to translate virtual addresses using the TLBs.
STL pair class.
Definition stl.hh:58
constexpr RegId X0
Definition int.hh:240
constexpr RegId R0
Definition int.hh:186
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
Bitfield< 6 > err
Bitfield< 0 > p
Bitfield< 4 > op
Definition types.hh:83
static void decodeAddrOffset(Addr offset, uint8_t &func)
bool pseudoInst(ThreadContext *tc, uint8_t func, uint64_t &result)
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t RegVal
Definition types.hh:173
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0