gem5  v21.1.0.2
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 
38 #include "arch/arm/semihosting.hh"
39 
40 #include <unistd.h>
41 
42 #include <cerrno>
43 #include <cstdio>
44 
45 #include "arch/arm/utility.hh"
46 #include "base/logging.hh"
47 #include "base/output.hh"
48 #include "base/time.hh"
49 #include "debug/Semihosting.hh"
50 #include "dev/serial/serial.hh"
51 #include "mem/physical.hh"
54 #include "params/ArmSemihosting.hh"
55 #include "sim/byteswap.hh"
56 #include "sim/full_system.hh"
57 #include "sim/pseudo_inst.hh"
58 #include "sim/sim_exit.hh"
59 #include "sim/system.hh"
60 
61 namespace gem5
62 {
63 
64 const std::map<uint32_t, ArmSemihosting::SemiCall> ArmSemihosting::calls{
65  { SYS_OPEN, { "SYS_OPEN", &ArmSemihosting::callOpen } },
66  { SYS_CLOSE, { "SYS_CLOSE", &ArmSemihosting::callClose } },
67  { SYS_WRITEC, { "SYS_WRITEC", &ArmSemihosting::callWriteC } },
68  { SYS_WRITE0, { "SYS_WRITE0", &ArmSemihosting::callWrite0 } },
69  { SYS_WRITE, { "SYS_WRITE", &ArmSemihosting::callWrite } },
70  { SYS_READ, { "SYS_READ", &ArmSemihosting::callRead } },
71  { SYS_READC, { "SYS_READC", &ArmSemihosting::callReadC } },
72  { SYS_ISERROR, { "SYS_ISERROR", &ArmSemihosting::callIsError } },
73  { SYS_ISTTY, { "SYS_ISTTY", &ArmSemihosting::callIsTTY } },
74  { SYS_SEEK, { "SYS_SEEK", &ArmSemihosting::callSeek } },
75  { SYS_FLEN, { "SYS_FLEN", &ArmSemihosting::callFLen } },
76  { SYS_TMPNAM, { "SYS_TMPNAM", &ArmSemihosting::callTmpNam } },
77  { SYS_REMOVE, { "SYS_REMOVE", &ArmSemihosting::callRemove } },
78  { SYS_RENAME, { "SYS_RENAME", &ArmSemihosting::callRename } },
79  { SYS_CLOCK, { "SYS_CLOCK", &ArmSemihosting::callClock } },
80  { SYS_TIME, { "SYS_TIME", &ArmSemihosting::callTime } },
81  { SYS_SYSTEM, { "SYS_SYSTEM", &ArmSemihosting::callSystem } },
82  { SYS_ERRNO, { "SYS_ERRNO", &ArmSemihosting::callErrno } },
83  { SYS_GET_CMDLINE,
84  { "SYS_GET_CMDLINE", &ArmSemihosting::callGetCmdLine } },
85  { SYS_HEAPINFO, { "SYS_HEAPINFO", &ArmSemihosting::callHeapInfo32,
87 
88  { SYS_EXIT, { "SYS_EXIT", &ArmSemihosting::callExit32,
90  { SYS_EXIT_EXTENDED,
91  { "SYS_EXIT_EXTENDED", &ArmSemihosting::callExitExtended } },
92 
93  { SYS_ELAPSED, { "SYS_ELAPSED", &ArmSemihosting::callElapsed32,
95  { SYS_TICKFREQ, { "SYS_TICKFREQ", &ArmSemihosting::callTickFreq } },
96  { SYS_GEM5_PSEUDO_OP,
97  { "SYS_GEM5_PSEUDO_OP", &ArmSemihosting::callGem5PseudoOp32,
99 };
100 
102  "r", "rb", "r+", "r+b",
103  "w", "wb", "w+", "w+b",
104  "a", "ab", "a+", "a+b",
105 };
106 
107 const std::map<uint64_t, const char *> ArmSemihosting::exitCodes{
108  { 0x20000, "semi:ADP_Stopped_BranchThroughZero" },
109  { 0x20001, "semi:ADP_Stopped_UndefinedInstr" },
110  { 0x20002, "semi:ADP_Stopped_SoftwareInterrupt" },
111  { 0x20003, "semi:ADP_Stopped_PrefetchAbort" },
112  { 0x20004, "semi:ADP_Stopped_DataAbort" },
113  { 0x20005, "semi:ADP_Stopped_AddressException" },
114  { 0x20006, "semi:ADP_Stopped_IRQ" },
115  { 0x20007, "semi:ADP_Stopped_FIQ" },
116 
117  { 0x20020, "semi:ADP_Stopped_BreakPoint" },
118  { 0x20021, "semi:ADP_Stopped_WatchPoint" },
119  { 0x20022, "semi:ADP_Stopped_StepComplete" },
120  { 0x20023, "semi:ADP_Stopped_RunTimeErrorUnknown" },
121  { 0x20024, "semi:ADP_Stopped_InternalError" },
122  { 0x20025, "semi:ADP_Stopped_UserInterruption" },
123  { 0x20026, "semi:ADP_Stopped_ApplicationExit" },
124  { 0x20027, "semi:ADP_Stopped_StackOverflow" },
125  { 0x20028, "semi:ADP_Stopped_DivisionByZero" },
126  { 0x20029, "semi:ADP_Stopped_DivisionByZero" },
127 };
128 
129 
131  0x53, 0x48, 0x46, 0x42, // Magic
132  0x3, // EXT_EXIT_EXTENDED, EXT_STDOUT_STDERR
133 };
134 
135 const std::map<const std::string, FILE *> ArmSemihosting::stdioMap{
136  {"cin", ::stdin},
137  {"stdin", ::stdin},
138  {"cout", ::stdout},
139  {"stdout", ::stdout},
140  {"cerr", ::stderr},
141  {"stderr", ::stderr},
142 };
143 
144 ArmSemihosting::ArmSemihosting(const ArmSemihostingParams &p)
145  : SimObject(p),
146  cmdLine(p.cmd_line),
147  memReserve(p.mem_reserve),
148  stackSize(p.stack_size),
149  timeBase([p]{ struct tm t = p.time; return mkutctime(&t); }()),
150  tickShift(calcTickShift()),
151  semiErrno(0),
152  filesRootDir(!p.files_root_dir.empty() &&
153  p.files_root_dir.back() != '/' ?
154  p.files_root_dir + '/' : p.files_root_dir),
155  stdin(getSTDIO("stdin", p.stdin, "r")),
156  stdout(getSTDIO("stdout", p.stdout, "w")),
157  stderr(p.stderr == p.stdout ?
158  stdout : getSTDIO("stderr", p.stderr, "w"))
159 {
160  // Create an empty place-holder file for position 0 as semi-hosting
161  // calls typically expect non-zero file handles.
162  files.push_back(nullptr);
163 
164  if (tickShift > 0)
165  inform("Semihosting: Shifting elapsed ticks by %i bits.",
166  tickShift);
167 }
168 
169 bool
171 {
172  RegVal op = tc->readIntReg(ArmISA::INTREG_X0 & mask(32));
173  if (op > MaxStandardOp && !gem5_ops) {
174  unrecognizedCall<Abi64>(
175  tc, "Gem5 semihosting op (0x%x) disabled from here.", op);
176  return false;
177  }
178 
179  auto it = calls.find(op);
180  if (it == calls.end()) {
181  unrecognizedCall<Abi64>(
182  tc, "Unknown aarch64 semihosting call: op = 0x%x", op);
183  return false;
184  }
185  const SemiCall &call = it->second;
186 
187  DPRINTF(Semihosting, "Semihosting call64: %s\n", call.dump64(tc));
188  auto err = call.call64(this, tc);
189  semiErrno = err.second;
190  DPRINTF(Semihosting, "\t ->: 0x%x, %i\n", err.first, err.second);
191 
192  return true;
193 }
194 
195 bool
197 {
198  RegVal op = tc->readIntReg(ArmISA::INTREG_R0);
199  if (op > MaxStandardOp && !gem5_ops) {
200  unrecognizedCall<Abi32>(
201  tc, "Gem5 semihosting op (0x%x) disabled from here.", op);
202  return false;
203  }
204 
205  auto it = calls.find(op);
206  if (it == calls.end()) {
207  unrecognizedCall<Abi32>(
208  tc, "Unknown aarch32 semihosting call: op = 0x%x", op);
209  return false;
210  }
211  const SemiCall &call = it->second;
212 
213  DPRINTF(Semihosting, "Semihosting call32: %s\n", call.dump32(tc));
214  auto err = call.call32(this, tc);
215  semiErrno = err.second;
216  DPRINTF(Semihosting, "\t ->: 0x%x, %i\n", err.first, err.second);
217 
218  return true;
219 }
220 
221 void
223 {
225 
226  paramOut(cp, "num_files", files.size());
227  for (int i = 0; i < files.size(); i++) {
228  // File closed?
229  if (!files[i])
230  continue;
231 
232  files[i]->serializeSection(cp, csprintf("file%i", i));
233  }
234 }
235 
236 void
238 {
240 
241  size_t num_files;
242  paramIn(cp, "num_files", num_files);
243  files.resize(num_files);
244  for (int i = 0; i < num_files; i++)
245  files[i] = FileBase::create(*this, cp, csprintf("file%i", i));
246 }
247 
248 PortProxy &
250 {
251  static std::unique_ptr<PortProxy> port_proxy_s;
252  static System *secure_sys = nullptr;
253 
254  if (ArmISA::isSecure(tc)) {
255  System *sys = tc->getSystemPtr();
256  if (sys != secure_sys) {
257  if (FullSystem) {
258  port_proxy_s.reset(
260  } else {
261  port_proxy_s.reset(
264  Request::SECURE));
265  }
266  }
267  secure_sys = sys;
268  return *port_proxy_s;
269  } else {
270  return tc->getVirtProxy();
271  }
272 }
273 
274 
275 std::string
277 {
278  std::vector<char> buf(len + 1);
279 
280  buf[len] = '\0';
281  portProxy(tc).readBlob(ptr, buf.data(), len);
282 
283  return std::string(buf.data());
284 }
285 
288  int fmode, size_t name_size)
289 {
290  const char *mode = fmode < fmodes.size() ? fmodes[fmode] : nullptr;
291 
292  DPRINTF(Semihosting, "Semihosting SYS_OPEN(0x%x, %i[%s], %i)\n",
293  name_base, fmode, mode ? mode : "-", name_size);
294  if (!mode || !name_base)
295  return retError(EINVAL);
296 
297  std::string fname = readString(tc, name_base, name_size);
298  if (!fname.empty() && fname.front() != '/')
299  fname = filesRootDir + fname;
300 
301  std::unique_ptr<ArmSemihosting::FileBase> file =
302  FileBase::create(*this, fname, mode);
303  int64_t ret = file->open();
304  DPRINTF(Semihosting, "Semihosting SYS_OPEN(\"%s\", %i[%s]): %i\n",
305  fname, fmode, mode, ret);
306  if (ret < 0) {
307  return retError(-ret);
308  } else {
309  files.push_back(std::move(file));
310  return retOK(files.size() - 1);
311  }
312 }
313 
316 {
317  if (handle > files.size()) {
318  DPRINTF(Semihosting, "Semihosting SYS_CLOSE(%i): Illegal file\n");
319  return retError(EBADF);
320  }
321 
322  std::unique_ptr<FileBase> &file = files[handle];
323  int64_t error = file->close();
324  DPRINTF(Semihosting, "Semihosting SYS_CLOSE(%i[%s]): %i\n",
325  handle, file->fileName(), error);
326  if (error < 0) {
327  return retError(-error);
328  } else {
329  // Zap the pointer and free the entry in the file table as
330  // well.
331  files[handle].reset();
332  return retOK(0);
333  }
334 }
335 
338 {
339  const char c = portProxy(tc).read<char>(arg.addr);
340 
341  DPRINTF(Semihosting, "Semihosting SYS_WRITEC('%c')\n", c);
342  std::cout.put(c);
343 
344  return retOK(0);
345 }
346 
349 {
350  DPRINTF(Semihosting, "Semihosting SYS_WRITE0(...)\n");
351  PortProxy &proxy = portProxy(tc);
352  std::string str;
353  proxy.readString(str, arg.addr);
354  std::cout.write(str.c_str(), str.size());
355 
356  return retOK(0);
357 }
358 
361  size_t size)
362 {
363  if (handle > files.size() || !files[handle])
364  return RetErrno(size, EBADF);
365 
366  std::vector<uint8_t> buffer(size);
367  portProxy(tc).readBlob(addr, buffer.data(), buffer.size());
368 
369  int64_t ret = files[handle]->write(buffer.data(), buffer.size());
370  if (ret < 0) {
371  // No bytes written (we're returning the number of bytes not
372  // written)
373  return RetErrno(size, -ret);
374  } else {
375  // Return the number of bytes not written
376  return RetErrno(size - ret, 0);
377  }
378 }
379 
382  size_t size)
383 {
384  if (handle > files.size() || !files[handle])
385  return RetErrno(size, EBADF);
386 
387  std::vector<uint8_t> buffer(size);
388  int64_t ret = files[handle]->read(buffer.data(), buffer.size());
389  if (ret < 0) {
390  return RetErrno(size, -ret);
391  } else {
392  panic_if(ret > buffer.size(), "Read longer than buffer size.");
393 
394  portProxy(tc).writeBlob(addr, buffer.data(), ret);
395 
396  // Return the number of bytes not written
397  return retOK(size - ret);
398  }
399 }
400 
403 {
404  return retOK((char)std::cin.get());
405 }
406 
409 {
410  return retOK(status < 0 ? 1 : 0);
411 }
412 
415 {
416  if (handle > files.size() || !files[handle])
417  return retError(EBADF);
418 
419  int64_t ret = files[handle]->isTTY();
420  if (ret < 0) {
421  return retError(-ret);
422  } else {
423  return retOK(ret ? 1 : 0);
424  }
425 }
426 
429 {
430  if (handle > files.size() || !files[handle])
431  return retError(EBADF);
432 
433  int64_t ret = files[handle]->seek(pos);
434  if (ret < 0) {
435  return retError(-ret);
436  } else {
437  return retOK(0);
438  }
439 }
440 
443 {
444  if (handle > files.size() || !files[handle])
445  return retError(EBADF);
446 
447  int64_t ret = files[handle]->flen();
448  if (ret < 0) {
449  return retError(-ret);
450  } else {
451  return retOK(ret);
452  }
453 }
454 
457  size_t size)
458 {
459  std::string path = "";
460  int64_t unlink_call_ret = 0;
461 
462  do {
463  path = simout.resolve(csprintf("%s.tmp%05i", name(), tmpNameIndex++));
464  // remove the (potentially existing) file of the given path
465  unlink_call_ret = unlink(path.c_str());
466  // if the file is busy, find another name
467  } while ((unlink_call_ret < 0) && (errno == EBUSY));
468 
469  const size_t path_len = path.length();
470  if (path_len >= size)
471  return retError(ENOSPC);
472 
473  portProxy(tc).writeBlob(addr, path.c_str(), path_len + 1);
474  return retOK(0);
475 }
476 
478 ArmSemihosting::callRemove(ThreadContext *tc, Addr name_base, size_t name_size)
479 {
480  std::string fname = readString(tc, name_base, name_size);
481 
482  if (remove(fname.c_str()) != 0) {
483  return retError(errno);
484  } else {
485  return retOK(0);
486  }
487 }
488 
490 ArmSemihosting::callRename(ThreadContext *tc, Addr from_addr, size_t from_size,
491  Addr to_addr, size_t to_size)
492 {
493  std::string from = readString(tc, from_addr, from_size);
494  std::string to = readString(tc, to_addr, to_size);
495 
496  if (rename(from.c_str(), to.c_str()) != 0) {
497  return retError(errno);
498  } else {
499  return retOK(0);
500  }
501 }
502 
505 {
506  return retOK(curTick() / (sim_clock::as_int::s / 100));
507 }
508 
511 {
512  return retOK(timeBase + round(curTick() / sim_clock::as_float::s));
513 }
514 
516 ArmSemihosting::callSystem(ThreadContext *tc, Addr cmd_addr, size_t cmd_size)
517 {
518  const std::string cmd = readString(tc, cmd_addr, cmd_size);
519  warn("Semihosting: SYS_SYSTEM not implemented. Guest tried to run: %s\n",
520  cmd);
521  return retError(EINVAL);
522 
523 }
524 
527 {
528  // Preserve errno by returning it in errno as well.
529  return RetErrno(semiErrno, semiErrno);
530 }
531 
534  InPlaceArg size_arg)
535 {
536  PortProxy &proxy = portProxy(tc);
537  ByteOrder endian = ArmISA::byteOrder(tc);
538  size_t size = size_arg.read(tc, endian);
539 
540  if (cmdLine.size() + 1 < size) {
541  proxy.writeBlob(addr, cmdLine.c_str(), cmdLine.size() + 1);
542  size_arg.write(tc, cmdLine.size(), endian);
543  return retOK(0);
544  } else {
545  return retError(0);
546  }
547 }
548 
549 void
551  Addr &heap_base, Addr &heap_limit,
552  Addr &stack_base, Addr &stack_limit)
553 {
554  const memory::PhysicalMemory &phys = tc->getSystemPtr()->getPhysMem();
555  const AddrRangeList memories = phys.getConfAddrRanges();
556  fatal_if(memories.size() < 1, "No memories reported from System");
557  warn_if(memories.size() > 1, "Multiple physical memory ranges available. "
558  "Using first range heap/stack.");
559  const AddrRange mem = *memories.begin();
560  const Addr mem_start = mem.start() + memReserve;
561  Addr mem_end = mem.end();
562 
563  // Make sure that 32-bit guests can access their memory.
564  if (!aarch64) {
565  const Addr phys_max = (1ULL << 32) - 1;
566  panic_if(mem_start > phys_max,
567  "Physical memory out of range for a 32-bit guest.");
568  if (mem_end > phys_max) {
569  warn("Some physical memory out of range for a 32-bit guest.");
570  mem_end = phys_max;
571  }
572  }
573 
574  fatal_if(mem_start + stackSize >= mem_end,
575  "Physical memory too small to fit desired stack and a heap.");
576 
577  heap_base = mem_start;
578  heap_limit = mem_end - stackSize + 1;
579  stack_base = (mem_end + 1) & ~0x7ULL; // 8 byte stack alignment
580  stack_limit = heap_limit;
581 
582  inform("Reporting heap/stack info to guest:\n"
583  "\tHeap base: 0x%x\n"
584  "\tHeap limit: 0x%x\n"
585  "\tStack base: 0x%x\n"
586  "\tStack limit: 0x%x\n",
587  heap_base, heap_limit, stack_base, stack_limit);
588 }
589 
592 {
593  uint64_t heap_base, heap_limit, stack_base, stack_limit;
594  gatherHeapInfo(tc, false, heap_base, heap_limit, stack_base, stack_limit);
595 
596  std::array<uint32_t, 4> block = {{
597  (uint32_t)heap_base, (uint32_t)heap_limit,
598  (uint32_t)stack_base, (uint32_t)stack_limit
599  }};
600  portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));
601 
602  return retOK(0);
603 }
604 
607 {
608  uint64_t heap_base, heap_limit, stack_base, stack_limit;
609  gatherHeapInfo(tc, true, heap_base, heap_limit, stack_base, stack_limit);
610 
611  std::array<uint64_t, 4> block = {{
612  heap_base, heap_limit, stack_base, stack_limit
613  }};
614  portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));
615 
616  return retOK(0);
617 }
618 
621 {
622  semiExit(code.addr, 0);
623  return retOK(0);
624 }
625 
627 ArmSemihosting::callExit64(ThreadContext *tc, uint64_t code, uint64_t subcode)
628 {
629  semiExit(code, subcode);
630  return retOK(0);
631 }
632 
635  uint64_t code, uint64_t subcode)
636 {
637  semiExit(code, subcode);
638  return retOK(0);
639 }
640 
641 void
642 ArmSemihosting::semiExit(uint64_t code, uint64_t subcode)
643 {
644  auto it = exitCodes.find(code);
645  if (it != exitCodes.end()) {
646  exitSimLoop(it->second, subcode);
647  } else {
648  exitSimLoop(csprintf("semi:0x%x", code), subcode);
649  }
650 }
651 
652 
656 {
657  ByteOrder endian = ArmISA::byteOrder(tc);
658  uint64_t tick = semiTick(curTick());
659 
660  low.write(tc, tick, endian);
661  high.write(tc, tick >> 32, endian);
662 
663  return retOK(0);
664 }
665 
666 
669 {
670  ticks.write(tc, semiTick(curTick()), ArmISA::byteOrder(tc));
671  return retOK(0);
672 }
673 
674 
677 {
679 }
680 
681 
683 {
685  {
686  public:
687  State(const ThreadContext *tc) : ArmSemihosting::Abi32::State(tc)
688  {
689  // Use getAddr() to skip the func number in the first slot.
690  getAddr();
691  }
692  };
693 };
694 
696 {
698  {
699  public:
700  State(const ThreadContext *tc) : ArmSemihosting::Abi64::State(tc)
701  {
702  // Use getAddr() to skip the func number in the first slot.
703  getAddr();
704  }
705  };
706 };
707 
708 GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi);
709 namespace guest_abi
710 {
711 
712 // Handle arguments the same as for semihosting operations. Skipping the first
713 // slot is handled internally by the State type.
714 template <typename T>
716  public Argument<ArmSemihosting::Abi32, T>
717 {};
718 template <typename T>
720  public Argument<ArmSemihosting::Abi64, T>
721 {};
722 
723 } // namespace guest_abi
724 
727 {
728  uint8_t func;
729  pseudo_inst::decodeAddrOffset(encoded_func, func);
730 
731  uint64_t ret;
732  if (pseudo_inst::pseudoInst<SemiPseudoAbi32>(tc, func, ret))
733  return retOK(ret);
734  else
735  return retError(EINVAL);
736 }
737 
740 {
741  uint8_t func;
742  pseudo_inst::decodeAddrOffset(encoded_func, func);
743 
744  uint64_t ret;
745  if (pseudo_inst::pseudoInst<SemiPseudoAbi64>(tc, func, ret))
746  return retOK(ret);
747  else
748  return retError(EINVAL);
749 }
750 
751 FILE *
752 ArmSemihosting::getSTDIO(const char *stream_name,
753  const std::string &name, const char *mode)
754 {
755  auto it = stdioMap.find(name);
756  if (it == stdioMap.end()) {
757  FILE *f = fopen(name.c_str(), mode);
758  if (!f) {
759  fatal("Failed to open %s (%s): %s\n",
760  stream_name, name, strerror(errno));
761  }
762  return f;
763  } else {
764  return it->second;
765  }
766 }
767 
768 std::unique_ptr<ArmSemihosting::FileBase>
770  ArmSemihosting &parent, const std::string &fname, const char *mode)
771 {
772  std::unique_ptr<FileBase> file;
773  if (fname == ":semihosting-features") {
774  file.reset(new FileFeatures(parent, fname.c_str(), mode));
775  } else {
776  file.reset(new File(parent, fname.c_str(), mode));
777  }
778 
779  return file;
780 }
781 
782 std::unique_ptr<ArmSemihosting::FileBase>
784  CheckpointIn &cp, const std::string &sec)
785 {
786  std::unique_ptr<FileBase> file;
787  ScopedCheckpointSection _sec(cp, sec);
788 
789  // Was the file open when the checkpoint was created?
791  return file;
792 
793  std::string fname, mode;
794  paramIn(cp, "name", fname);
795  paramIn(cp, "mode", mode);
796  file = create(parent, fname, mode.c_str());
797  assert(file);
798  file->unserialize(cp);
799 
800  return file;
801 }
802 
803 void
805 {
806  paramOut(cp, "name", _name);
808 }
809 
810 void
812 {
813  /* Unserialization of name and mode happens in
814  * ArmSemihosting::FileBase::create() */
815 }
816 
817 int64_t
818 ArmSemihosting::FileBase::read(uint8_t *buffer, uint64_t size)
819 {
820  return -EINVAL;
821 }
822 
823 int64_t
824 ArmSemihosting::FileBase::write(const uint8_t *buffer, uint64_t size)
825 {
826  return -EINVAL;
827 }
828 
829 int64_t
831 {
832  return -EINVAL;
833 }
834 
835 int64_t
837 {
838  return -EINVAL;
839 }
840 
841 
843  ArmSemihosting &_parent, const char *_name, const char *_mode)
844  : FileBase(_parent, _name, _mode)
845 {
846 }
847 
848 int64_t
849 ArmSemihosting::FileFeatures::read(uint8_t *buffer, uint64_t size)
850 {
851  int64_t len = 0;
852 
853  for (; pos < size && pos < ArmSemihosting::features.size(); pos++)
854  buffer[len++] = ArmSemihosting::features[pos];
855 
856  return len;
857 }
858 
859 int64_t
861 {
862  if (_pos < ArmSemihosting::features.size()) {
863  pos = _pos;
864  return 0;
865  } else {
866  return -ENXIO;
867  }
868 }
869 
870 void
872 {
874  SERIALIZE_SCALAR(pos);
875 }
876 
877 void
879 {
881  UNSERIALIZE_SCALAR(pos);
882 }
883 
884 
885 
887  const char *_name, const char *_perms)
888  : FileBase(_parent, _name, _perms),
889  file(nullptr)
890 {
891 }
892 
894 {
895  if (file)
896  close();
897 }
898 
899 int64_t
901 {
902  panic_if(file, "Trying to open an already open file.\n");
903 
904  if (_name == ":tt") {
905  if (mode[0] == 'r') {
906  file = parent.stdin;
907  } else if (mode[0] == 'w') {
908  file = parent.stdout;
909  } else if (mode[0] == 'a') {
910  file = parent.stderr;
911  } else {
912  warn("Unknown file mode for the ':tt' special file");
913  return -EINVAL;
914  }
915  } else {
916  std::string real_mode(this->mode);
917  // Avoid truncating the file if we are restoring from a
918  // checkpoint.
919  if (in_cpt && real_mode[0] == 'w')
920  real_mode[0] = 'a';
921 
922  file = fopen(_name.c_str(), real_mode.c_str());
923  }
924 
925  return file ? 0 : -errno;
926 }
927 
928 int64_t
930 {
931  panic_if(!file, "Trying to close an already closed file.\n");
932 
933  if (needClose()) {
934  fclose(file);
935  }
936  file = nullptr;
937 
938  return 0;
939 }
940 
941 bool
943 {
944  return file == parent.stdout ||
945  file == parent.stderr ||
946  file == parent.stdin;
947 }
948 
949 int64_t
950 ArmSemihosting::File::read(uint8_t *buffer, uint64_t size)
951 {
952  panic_if(!file, "Trying to read from a closed file");
953 
954  size_t ret = fread(buffer, 1, size, file);
955  if (ret == 0) {
956  // Error or EOF. Assume errors are due to invalid file
957  // operations (e.g., reading a write-only stream).
958  return ferror(file) ? -EINVAL : 0;
959  } else {
960  return ret;
961  }
962 }
963 
964 int64_t
965 ArmSemihosting::File::write(const uint8_t *buffer, uint64_t size)
966 {
967  panic_if(!file, "Trying to write to a closed file");
968 
969 
970  size_t ret = fwrite(buffer, 1, size, file);
971  if (ret == 0) {
972  // Assume errors are due to invalid file operations (e.g.,
973  // writing a read-only stream).
974  return -EINVAL;
975  } else {
976  return ret;
977  }
978 }
979 
980 int64_t
982 {
983  panic_if(!file, "Trying to seek in a closed file");
984 
985  errno = 0;
986  if (fseek(file, _pos, SEEK_SET) == 0)
987  return 0;
988  else
989  return -errno;
990 }
991 
992 int64_t
994 {
995  errno = 0;
996  long pos = ftell(file);
997  if (pos < 0)
998  return -errno;
999 
1000  if (fseek(file, 0, SEEK_END) != 0)
1001  return -errno;
1002 
1003  long len = ftell(file);
1004  if (len < 0)
1005  return -errno;
1006 
1007  if (fseek(file, pos, SEEK_SET) != 0)
1008  return -errno;
1009 
1010  return len;
1011 }
1012 
1013 
1014 void
1016 {
1017  FileBase::serialize(cp);
1018 
1019  if (!isTTY()) {
1020  long pos = file ? ftell(file) : 0;
1021  panic_if(pos < 0, "Failed to get file position.");
1022  SERIALIZE_SCALAR(pos);
1023  }
1024 }
1025 
1026 void
1028 {
1030 
1031  if (openImpl(true) < 0) {
1032  fatal("Failed to open file: %s", _name);
1033  }
1034 
1035  if (!isTTY()) {
1036  long pos = 0;
1037  UNSERIALIZE_SCALAR(pos);
1038  if (fseek(file, pos, SEEK_SET) != 0) {
1039  fatal("Failed seek to current position (%i) in '%s'", pos, _name);
1040  }
1041  }
1042 }
1043 
1044 std::ostream &
1045 operator << (std::ostream &os, const ArmSemihosting::InPlaceArg &ipa)
1046 {
1047  ccprintf(os, "[%#x-%#x)", ipa.addr, ipa.addr + ipa.size - 1);
1048  return os;
1049 }
1050 
1051 } // namespace gem5
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::operator<<
std::ostream & operator<<(std::ostream &os, const ArmSemihosting::InPlaceArg &ipa)
Definition: semihosting.cc:1045
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::ArmSemihosting::callFLen
RetErrno callFLen(ThreadContext *tc, Handle handle)
Definition: semihosting.cc:442
gem5::ArmSemihosting::Abi32::State
Definition: semihosting.hh:156
gem5::ArmSemihosting::callReadC
RetErrno callReadC(ThreadContext *tc)
Definition: semihosting.cc:402
gem5::ArmSemihosting::callExitExtended
RetErrno callExitExtended(ThreadContext *tc, uint64_t code, uint64_t subcode)
Definition: semihosting.cc:634
gem5::SETranslatingPortProxy
Definition: se_translating_port_proxy.hh:49
gem5::ArmSemihosting::timeBase
const time_t timeBase
Base time when the simulation started.
Definition: semihosting.hh:256
gem5::ArmSemihosting::callExit64
RetErrno callExit64(ThreadContext *tc, uint64_t code, uint64_t subcode)
Definition: semihosting.cc:627
gem5::ArmSemihosting::callClose
RetErrno callClose(ThreadContext *tc, Handle handle)
Definition: semihosting.cc:315
gem5::ThreadContext::getSystemPtr
virtual System * getSystemPtr()=0
gem5::ArmISA::len
Bitfield< 18, 16 > len
Definition: misc_types.hh:444
warn
#define warn(...)
Definition: logging.hh:245
gem5::PortProxy::writeBlob
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
Definition: port_proxy.hh:192
gem5::RegVal
uint64_t RegVal
Definition: types.hh:173
system.hh
gem5::SemiPseudoAbi64::State::State
State(const ThreadContext *tc)
Definition: semihosting.cc:700
gem5::ArmSemihosting::FileBase::mode
std::string mode
Definition: semihosting.hh:366
gem5::ArmSemihosting::File::write
int64_t write(const uint8_t *buffer, uint64_t size) override
Write data to file.
Definition: semihosting.cc:965
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::ArmSemihosting::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: semihosting.cc:237
gem5::ArmSemihosting::ArmSemihosting
ArmSemihosting(const ArmSemihostingParams &p)
Definition: semihosting.cc:144
gem5::PortProxy::readString
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:260
gem5::SETranslatingPortProxy::NextPage
@ NextPage
Definition: se_translating_port_proxy.hh:57
gem5::ArmISA::aarch64
Bitfield< 34 > aarch64
Definition: types.hh:81
gem5::ArmSemihosting::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: semihosting.cc:222
gem5::ArmSemihosting::InPlaceArg::write
void write(ThreadContext *tc, uint64_t val, ByteOrder endian)
Definition: semihosting.hh:192
gem5::Serializable::path
static std::stack< std::string > path
Definition: serialize.hh:315
pseudo_inst.hh
gem5::ArmSemihosting::SemiCall::call32
Dispatcher call32
Definition: semihosting.hh:483
gem5::ArmSemihosting::callRemove
RetErrno callRemove(ThreadContext *tc, Addr name_base, size_t name_size)
Definition: semihosting.cc:478
gem5::memory::PhysicalMemory
The physical memory encapsulates all memories in the system and provides basic functionality for acce...
Definition: physical.hh:122
gem5::ArmSemihosting::FileBase
Internal state for open files.
Definition: semihosting.hh:279
gem5::ArmSemihosting::File::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: semihosting.cc:1027
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::ArmISA::f
Bitfield< 6 > f
Definition: misc_types.hh:67
gem5::ArmSemihosting::Abi64
Definition: semihosting.hh:138
time.hh
gem5::ArmSemihosting::semiTick
uint64_t semiTick(Tick tick) const
Definition: semihosting.hh:425
gem5::ArmSemihosting::FileBase::parent
ArmSemihosting & parent
Definition: semihosting.hh:364
gem5::ArmISA::err
Bitfield< 6 > err
Definition: misc_types.hh:750
gem5::ArmSemihosting::exitCodes
static const std::map< uint64_t, const char * > exitCodes
Definition: semihosting.hh:590
translating_port_proxy.hh
gem5::ArmSemihosting::callIsTTY
RetErrno callIsTTY(ThreadContext *tc, Handle handle)
Definition: semihosting.cc:414
gem5::SemiPseudoAbi64::State
Definition: semihosting.cc:697
gem5::simout
OutputDirectory simout
Definition: output.cc:62
gem5::sim_clock::Frequency
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:48
gem5::ArmSemihosting::File::close
int64_t close() override
Close the file.
Definition: semihosting.cc:929
gem5::ArmSemihosting::RetErrno
std::pair< uint64_t, SemiErrno > RetErrno
Definition: semihosting.hh:433
gem5::ArmSemihosting::File::~File
~File()
Definition: semihosting.cc:893
gem5::ArmSemihosting::portProxy
static PortProxy & portProxy(ThreadContext *tc)
Definition: semihosting.cc:249
gem5::ArmISA::byteOrder
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:412
gem5::ArmSemihosting::callHeapInfo32
RetErrno callHeapInfo32(ThreadContext *tc, Addr block_addr)
Definition: semihosting.cc:591
gem5::ArmSemihosting::FileFeatures
Implementation of the ':semihosting-features' magic file.
Definition: semihosting.hh:370
std::vector< const char * >
gem5::csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
gem5::sim_clock::as_int::s
Tick s
second
Definition: core.cc:68
gem5::ArmSemihosting::callErrno
RetErrno callErrno(ThreadContext *tc)
Definition: semihosting.cc:526
gem5::ArmSemihosting::File::File
File(ArmSemihosting &_parent, const char *name, const char *mode)
Definition: semihosting.cc:886
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::ArmSemihosting::semiExit
void semiExit(uint64_t code, uint64_t subcode)
Definition: semihosting.cc:642
sim_exit.hh
gem5::ArmSemihosting::File
Definition: semihosting.hh:386
output.hh
gem5::ArmSemihosting::File::isTTY
bool isTTY() const override
Check if a file corresponds to a TTY device.
Definition: semihosting.cc:942
gem5::ArmSemihosting::SemiCall::dump32
Dumper dump32
Definition: semihosting.hh:487
gem5::ArmSemihosting::FileBase::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: semihosting.cc:804
gem5::ArmSemihosting::FileFeatures::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: semihosting.cc:878
gem5::ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
gem5::ArmSemihosting::call32
bool call32(ThreadContext *tc, bool gem5_ops)
Perform an Arm Semihosting call from aarch32 code.
Definition: semihosting.cc:196
gem5::exitSimLoop
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition: sim_events.cc:88
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
gem5::ArmSemihosting::FileFeatures::FileFeatures
FileFeatures(ArmSemihosting &_parent, const char *name, const char *mode)
Definition: semihosting.cc:842
gem5::TranslatingPortProxy
This proxy attempts to translate virtual addresses using the TLBs.
Definition: translating_port_proxy.hh:58
gem5::ArmSemihosting::semiErrno
SemiErrno semiErrno
Definition: semihosting.hh:263
gem5::ArmSemihosting::InPlaceArg::addr
Addr addr
Definition: semihosting.hh:171
gem5::PowerISA::to
Bitfield< 25, 21 > to
Definition: types.hh:96
gem5::ArmSemihosting::InPlaceArg
Definition: semihosting.hh:169
gem5::ArmSemihosting::callIsError
RetErrno callIsError(ThreadContext *tc, int64_t status)
Definition: semihosting.cc:408
gem5::ArmSemihosting::File::read
int64_t read(uint8_t *buffer, uint64_t size) override
Read data from file.
Definition: semihosting.cc:950
gem5::ArmSemihosting::callSystem
RetErrno callSystem(ThreadContext *tc, Addr cmd_addr, size_t cmd_size)
Definition: semihosting.cc:516
gem5::ArmSemihosting::callGem5PseudoOp64
RetErrno callGem5PseudoOp64(ThreadContext *tc, uint64_t encoded_func)
Definition: semihosting.cc:739
gem5::ArmSemihosting::callGetCmdLine
RetErrno callGetCmdLine(ThreadContext *tc, Addr addr, InPlaceArg size_arg)
Definition: semihosting.cc:533
gem5::ArmSemihosting::callExit32
RetErrno callExit32(ThreadContext *tc, InPlaceArg code)
Definition: semihosting.cc:620
gem5::ArmSemihosting::FileBase::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: semihosting.cc:811
gem5::ArmSemihosting::callWrite
RetErrno callWrite(ThreadContext *tc, Handle handle, Addr buffer, size_t size)
Definition: semihosting.cc:360
gem5::high
high
Definition: intmath.hh:176
gem5::System
Definition: system.hh:77
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:93
gem5::Request::SECURE
@ SECURE
The request targets the secure memory space.
Definition: request.hh:184
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::ThreadContext::getVirtProxy
virtual PortProxy & getVirtProxy()=0
gem5::ArmSemihosting::fmodes
static const std::vector< const char * > fmodes
Definition: semihosting.hh:589
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::ArmSemihosting::AbiBase::StateBase::getAddr
Addr getAddr()
Definition: semihosting.hh:117
gem5::ArmSemihosting::InPlaceArg::size
size_t size
Definition: semihosting.hh:172
gem5::ArmSemihosting::File::seek
int64_t seek(uint64_t pos) override
Seek to an absolute position in the file.
Definition: semihosting.cc:981
gem5::ArmSemihosting::filesRootDir
std::string filesRootDir
Definition: semihosting.hh:410
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::ArmSemihosting::retError
static RetErrno retError(SemiErrno e)
Definition: semihosting.hh:437
gem5::PortProxy::read
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
Definition: port_proxy.hh:287
gem5::ArmSemihosting::retOK
static RetErrno retOK(uint64_t r)
Definition: semihosting.hh:443
gem5::ArmSemihosting::File::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: semihosting.cc:1015
gem5::OutputDirectory::resolve
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
Definition: output.cc:204
gem5::ArmSemihosting::callRead
RetErrno callRead(ThreadContext *tc, Handle handle, Addr buffer, size_t size)
Definition: semihosting.cc:381
gem5::SemiPseudoAbi64
Definition: semihosting.cc:695
gem5::PortProxy
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition: port_proxy.hh:86
gem5::ArmSemihosting::File::flen
int64_t flen() override
Get the length of a file in bytes.
Definition: semihosting.cc:993
gem5::ArmSemihosting::InPlaceArg::read
uint64_t read(ThreadContext *tc, ByteOrder endian)
Definition: semihosting.hh:179
gem5::ArmSemihosting::Abi64::State
Definition: semihosting.hh:142
gem5::ArmSemihosting::callGem5PseudoOp32
RetErrno callGem5PseudoOp32(ThreadContext *tc, uint32_t encoded_func)
Definition: semihosting.cc:726
gem5::ArmSemihosting::callElapsed32
RetErrno callElapsed32(ThreadContext *tc, InPlaceArg low, InPlaceArg high)
Definition: semihosting.cc:654
gem5::PortProxy::readBlob
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
Definition: port_proxy.hh:182
gem5::SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:146
serial.hh
gem5::ArmISA::t
Bitfield< 5 > t
Definition: misc_types.hh:70
std::pair
STL pair class.
Definition: stl.hh:58
gem5::ArmISA::c
Bitfield< 29 > c
Definition: misc_types.hh:53
gem5::pseudo_inst::decodeAddrOffset
static void decodeAddrOffset(Addr offset, uint8_t &func)
Definition: pseudo_inst.hh:63
gem5::ArmSemihosting::call64
bool call64(ThreadContext *tc, bool gem5_ops)
Perform an Arm Semihosting call from aarch64 code.
Definition: semihosting.cc:170
gem5::PowerISA::tm
Bitfield< 32 > tm
Definition: misc.hh:107
gem5::ArmSemihosting::callWrite0
RetErrno callWrite0(ThreadContext *tc, InPlaceArg str)
Definition: semihosting.cc:348
gem5::ArmSemihosting::FileFeatures::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: semihosting.cc:871
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::ArmSemihosting::FileFeatures::read
int64_t read(uint8_t *buffer, uint64_t size) override
Read data from file.
Definition: semihosting.cc:849
gem5::ArmSemihosting::callTime
RetErrno callTime(ThreadContext *tc)
Definition: semihosting.cc:510
gem5::ThreadContext::readIntReg
virtual RegVal readIntReg(RegIndex reg_idx) const =0
gem5::GEM5_DEPRECATED_NAMESPACE
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
name
const std::string & name()
Definition: trace.cc:49
gem5::ArmSemihosting::callSeek
RetErrno callSeek(ThreadContext *tc, Handle handle, uint64_t pos)
Definition: semihosting.cc:428
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::ArmSemihosting::cmdLine
const std::string cmdLine
Definition: semihosting.hh:248
gem5::ArmISA::isSecure
bool isSecure(ThreadContext *tc)
Definition: utility.cc:72
gem5::ArmSemihosting
Semihosting for AArch32 and AArch64.
Definition: semihosting.hh:76
gem5::ArmSemihosting::FileBase::flen
virtual int64_t flen()
Get the length of a file in bytes.
Definition: semihosting.cc:836
gem5::ArmSemihosting::Abi32
Definition: semihosting.hh:152
utility.hh
gem5::ArmSemihosting::FileBase::create
static std::unique_ptr< FileBase > create(ArmSemihosting &parent, const std::string &fname, const char *mode)
Definition: semihosting.cc:769
gem5::ArmSemihosting::stackSize
const Addr stackSize
Definition: semihosting.hh:250
full_system.hh
gem5::ArmSemihosting::getSTDIO
static FILE * getSTDIO(const char *stream_name, const std::string &name, const char *mode)
Definition: semihosting.cc:752
gem5::ArmSemihosting::FileBase::read
virtual int64_t read(uint8_t *buffer, uint64_t size)
Read data from file.
Definition: semihosting.cc:818
gem5::Serializable::currentSection
static const std::string & currentSection()
Gets the fully-qualified name of the active section.
Definition: serialize.cc:130
gem5::ArmSemihosting::callElapsed64
RetErrno callElapsed64(ThreadContext *tc, InPlaceArg ticks)
Definition: semihosting.cc:668
gem5::ArmSemihosting::callTickFreq
RetErrno callTickFreq(ThreadContext *tc)
Definition: semihosting.cc:676
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:223
gem5::ArmSemihosting::FileBase::seek
virtual int64_t seek(uint64_t pos)
Seek to an absolute position in the file.
Definition: semihosting.cc:830
warn_if
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:272
gem5::mkutctime
time_t mkutctime(struct tm *time)
Definition: time.cc:154
gem5::ArmSemihosting::SemiCall::dump64
Dumper dump64
Definition: semihosting.hh:488
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:203
gem5::ArmSemihosting::readString
std::string readString(ThreadContext *tc, Addr ptr, size_t len)
Definition: semihosting.cc:276
gem5::SemiPseudoAbi32::State::State
State(const ThreadContext *tc)
Definition: semihosting.cc:687
gem5::SemiPseudoAbi32::State
Definition: semihosting.cc:684
inform
#define inform(...)
Definition: logging.hh:246
gem5::ArmSemihosting::callWriteC
RetErrno callWriteC(ThreadContext *tc, InPlaceArg c)
Definition: semihosting.cc:337
gem5::ArmSemihosting::gatherHeapInfo
void gatherHeapInfo(ThreadContext *tc, bool aarch64, Addr &heap_base, Addr &heap_limit, Addr &stack_base, Addr &stack_limit)
Definition: semihosting.cc:550
gem5::CheckpointIn::sectionExists
bool sectionExists(const std::string &section)
Definition: serialize.cc:200
gem5::paramOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition: types.cc:40
semihosting.hh
gem5::ArmSemihosting::stdioMap
static const std::map< const std::string, FILE * > stdioMap
Definition: semihosting.hh:592
gem5::X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:809
gem5::ArmSemihosting::SemiCall::call64
Dispatcher call64
Definition: semihosting.hh:484
gem5::paramIn
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition: types.cc:72
gem5::ArmSemihosting::calls
static const std::map< uint32_t, SemiCall > calls
Definition: semihosting.hh:588
gem5::ArmSemihosting::FileFeatures::seek
int64_t seek(uint64_t pos) override
Seek to an absolute position in the file.
Definition: semihosting.cc:860
physical.hh
gem5::ArmSemihosting::FileBase::write
virtual int64_t write(const uint8_t *buffer, uint64_t size)
Write data to file.
Definition: semihosting.cc:824
gem5::ArmSemihosting::callHeapInfo64
RetErrno callHeapInfo64(ThreadContext *tc, Addr block_addr)
Definition: semihosting.cc:606
logging.hh
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
mem
bool_vector8 mem[]
Definition: reset_stim.h:43
gem5::guest_abi::Argument
Definition: definition.hh:99
se_translating_port_proxy.hh
gem5::ArmSemihosting::features
static const std::vector< uint8_t > features
Definition: semihosting.hh:591
gem5::ArmSemihosting::memReserve
const Addr memReserve
Definition: semihosting.hh:249
gem5::System::getPhysMem
memory::PhysicalMemory & getPhysMem()
Get a pointer to access the physical memory of the system.
Definition: system.hh:348
gem5::AddrRange
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:71
std::list< AddrRange >
gem5::ArmSemihosting::callClock
RetErrno callClock(ThreadContext *tc)
Definition: semihosting.cc:504
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:225
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::ArmSemihosting::callRename
RetErrno callRename(ThreadContext *tc, Addr from_addr, size_t from_size, Addr to_addr, size_t to_size)
Definition: semihosting.cc:490
gem5::ArmSemihosting::MaxStandardOp
@ MaxStandardOp
Definition: semihosting.hh:231
gem5::memory::PhysicalMemory::getConfAddrRanges
AddrRangeList getConfAddrRanges() const
Get the memory ranges for all memories that are to be reported to the configuration table.
Definition: physical.cc:262
gem5::Serializable::ScopedCheckpointSection
Definition: serialize.hh:172
gem5::ArmSemihosting::File::openImpl
int64_t openImpl(bool unserialize)
Definition: semihosting.cc:900
gem5::ArmSemihosting::SemiCall
Semihosting call information structure.
Definition: semihosting.hh:455
gem5::ArmSemihosting::callTmpNam
RetErrno callTmpNam(ThreadContext *tc, Addr buffer, uint64_t id, size_t size)
Definition: semihosting.cc:456
gem5::X86ISA::op
Bitfield< 4 > op
Definition: types.hh:83
gem5::ArmSemihosting::tmpNameIndex
uint16_t tmpNameIndex
Definition: semihosting.hh:595
gem5::ArmSemihosting::callOpen
RetErrno callOpen(ThreadContext *tc, const Addr name_base, int fmode, size_t name_size)
Definition: semihosting.cc:287
gem5::SemiPseudoAbi32
Definition: semihosting.cc:682
gem5::ArmSemihosting::Handle
size_t Handle
Definition: semihosting.hh:412
gem5::Named::_name
const std::string _name
Definition: named.hh:41
byteswap.hh
gem5::PortProxy::write
void write(Addr address, const T &data) const
Write object T to address.
Definition: port_proxy.hh:296
gem5::ArmISA::status
Bitfield< 5, 0 > status
Definition: misc_types.hh:422
gem5::sim_clock::as_float::s
double s
These variables equal the number of ticks in the unit of time they're named after in a double.
Definition: core.cc:53
gem5::ArmISA::mode
Bitfield< 4, 0 > mode
Definition: misc_types.hh:73
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
error
std::string error
Definition: remote_gdb.cc:208
gem5::ArmSemihosting::files
std::vector< std::unique_ptr< FileBase > > files
Definition: semihosting.hh:411

Generated on Tue Sep 21 2021 12:24:46 for gem5 by doxygen 1.8.17