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

Generated on Wed Sep 30 2020 14:02:01 for gem5 by doxygen 1.8.17