summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/ArmSemihosting.py6
-rw-r--r--src/arch/arm/semihosting.cc42
-rw-r--r--src/arch/arm/semihosting.hh6
3 files changed, 49 insertions, 5 deletions
diff --git a/src/arch/arm/ArmSemihosting.py b/src/arch/arm/ArmSemihosting.py
index 1da4c4988..784649914 100644
--- a/src/arch/arm/ArmSemihosting.py
+++ b/src/arch/arm/ArmSemihosting.py
@@ -46,6 +46,12 @@ class ArmSemihosting(SimObject):
cxx_header = "arch/arm/semihosting.hh"
cmd_line = Param.String("", "Command line to report to guest");
+ stdin = Param.String("stdin",
+ "Standard input (stdin for gem5's terminal)")
+ stdout = Param.String("stdout",
+ "Standard output (stdout for gem5's terminal)")
+ stderr = Param.String("stderr",
+ "Standard error (stderr for gem5's terminal)")
mem_reserve = Param.MemorySize("32MB",
"Amount of memory to reserve at the start of the address map. This "
diff --git a/src/arch/arm/semihosting.cc b/src/arch/arm/semihosting.cc
index 89e1b2e7d..46d964d63 100644
--- a/src/arch/arm/semihosting.cc
+++ b/src/arch/arm/semihosting.cc
@@ -121,6 +121,15 @@ const std::vector<uint8_t> ArmSemihosting::features{
0x3, // EXT_EXIT_EXTENDED, EXT_STDOUT_STDERR
};
+const std::map<const std::string, FILE *> ArmSemihosting::stdioMap{
+ {"cin", ::stdin},
+ {"stdin", ::stdin},
+ {"cout", ::stdout},
+ {"stdout", ::stdout},
+ {"cerr", ::stderr},
+ {"stderr", ::stderr},
+};
+
ArmSemihosting::ArmSemihosting(const ArmSemihostingParams *p)
: SimObject(p),
cmdLine(p->cmd_line),
@@ -128,7 +137,11 @@ ArmSemihosting::ArmSemihosting(const ArmSemihostingParams *p)
stackSize(p->stack_size),
timeBase([p]{ struct tm t = p->time; return mkutctime(&t); }()),
tickShift(calcTickShift()),
- semiErrno(0)
+ semiErrno(0),
+ stdin(getSTDIO("stdin", p->stdin, "r")),
+ stdout(getSTDIO("stdout", p->stdout, "w")),
+ stderr(p->stderr == p->stdout ?
+ stdout : getSTDIO("stderr", p->stderr, "w"))
{
// Create an empty place-holder file for position 0 as semi-hosting
// calls typically expect non-zero file handles.
@@ -681,6 +694,23 @@ ArmSemihosting::getCall(uint32_t op, bool aarch64)
}
}
+FILE *
+ArmSemihosting::getSTDIO(const char *stream_name,
+ const std::string &name, const char *mode)
+{
+ auto it = stdioMap.find(name);
+ if (it == stdioMap.end()) {
+ FILE *f = fopen(name.c_str(), mode);
+ if (!f) {
+ fatal("Failed to open %s (%s): %s\n",
+ stream_name, name, strerror(errno));
+ }
+ return f;
+ } else {
+ return it->second;
+ }
+}
+
std::unique_ptr<ArmSemihosting::FileBase>
ArmSemihosting::FileBase::create(
ArmSemihosting &parent, const std::string &fname, const char *mode)
@@ -819,11 +849,11 @@ ArmSemihosting::File::openImpl(bool in_cpt)
if (_name == ":tt") {
if (mode[0] == 'r') {
- file = stdin;
+ file = parent.stdin;
} else if (mode[0] == 'w') {
- file = stdout;
+ file = parent.stdout;
} else if (mode[0] == 'a') {
- file = stderr;
+ file = parent.stderr;
} else {
warn("Unknown file mode for the ':tt' special file");
return -EINVAL;
@@ -857,7 +887,9 @@ ArmSemihosting::File::close()
bool
ArmSemihosting::File::isTTY() const
{
- return file == stdout || file == stderr || file == stdin;
+ return file == parent.stdout ||
+ file == parent.stderr ||
+ file == parent.stdin;
}
int64_t
diff --git a/src/arch/arm/semihosting.hh b/src/arch/arm/semihosting.hh
index 14c5f9d2d..581646021 100644
--- a/src/arch/arm/semihosting.hh
+++ b/src/arch/arm/semihosting.hh
@@ -244,6 +244,9 @@ class ArmSemihosting : public SimObject
};
std::vector<std::unique_ptr<FileBase>> files;
+ FILE *stdin;
+ FILE *stdout;
+ FILE *stderr;
protected: // Helper functions
unsigned calcTickShift() const {
@@ -342,11 +345,14 @@ class ArmSemihosting : public SimObject
#undef SEMI_CALL
static const SemiCall *getCall(uint32_t op, bool aarch64);
+ static FILE *getSTDIO(const char *stream_name,
+ const std::string &name, const char *mode);
static const std::map<uint32_t, SemiCall> calls;
static const std::vector<const char *> fmodes;
static const std::map<uint64_t, const char *> exitCodes;
static const std::vector<uint8_t> features;
+ static const std::map<const std::string, FILE *> stdioMap;
};
#endif // __ARCH_ARM_SEMIHOSTING_HH__