diff options
-rw-r--r-- | src/arch/arm/ArmSemihosting.py | 6 | ||||
-rw-r--r-- | src/arch/arm/semihosting.cc | 42 | ||||
-rw-r--r-- | src/arch/arm/semihosting.hh | 6 |
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__ |