Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/25950 )

Change subject: arm: Add a gem5 specific pseudo op semihosting call.
......................................................................

arm: Add a gem5 specific pseudo op semihosting call.

This is in the range of call numbers set aside for extensions. When
called, it will extract the function to use from the first argument
slot. Then it calls the pseudoInst dispatching function using an ABI
which drops the return value (which is handled by semihosting itself)
and which extracts arguments from the remaining slots in the param
structure.

This makes gem5 pseudo ops available on CPU models which support
semihosting but not instruction based or address based "magic"
operations, aka hypercalls. This includes the fast model CPUs.

Change-Id: Ic4817f2b1e6aad7784af77a1a494cf614d4d4c6c
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25950
Reviewed-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/arch/arm/semihosting.cc
M src/arch/arm/semihosting.hh
2 files changed, 91 insertions(+), 1 deletion(-)

Approvals:
  Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/arm/semihosting.cc b/src/arch/arm/semihosting.cc
index 230ded1..7b7592f 100644
--- a/src/arch/arm/semihosting.cc
+++ b/src/arch/arm/semihosting.cc
@@ -48,6 +48,7 @@
 #include "mem/secure_port_proxy.hh"
 #include "params/ArmSemihosting.hh"
 #include "sim/byteswap.hh"
+#include "sim/pseudo_inst.hh"
 #include "sim/sim_exit.hh"
 #include "sim/system.hh"

@@ -83,6 +84,9 @@
     { SYS_ELAPSED,  { "SYS_ELAPSED", &ArmSemihosting::callElapsed32,
                                      &ArmSemihosting::callElapsed64 } },
     { SYS_TICKFREQ, { "SYS_TICKFREQ", &ArmSemihosting::callTickFreq } },
+    { SYS_GEM5_PSEUDO_OP,
+        { "SYS_GEM5_PSEUDO_OP", &ArmSemihosting::callGem5PseudoOp32,
+                                &ArmSemihosting::callGem5PseudoOp64 } },
 };

 const std::vector<const char *> ArmSemihosting::fmodes{
@@ -653,6 +657,87 @@
     return retOK(semiTick(SimClock::Frequency));
 }

+
+struct SemiPseudoAbi32 : public ArmSemihosting::Abi32
+{
+    class State : public ArmSemihosting::Abi32::State
+    {
+      public:
+        State(const ThreadContext *tc) : ArmSemihosting::Abi32::State(tc)
+        {
+            // Use getAddr() to skip the func number in the first slot.
+            getAddr();
+        }
+    };
+};
+
+struct SemiPseudoAbi64 : public ArmSemihosting::Abi64
+{
+    class State : public ArmSemihosting::Abi64::State
+    {
+      public:
+        State(const ThreadContext *tc) : ArmSemihosting::Abi64::State(tc)
+        {
+            // Use getAddr() to skip the func number in the first slot.
+            getAddr();
+        }
+    };
+};
+
+namespace GuestABI
+{
+
+// Ignore return values since those will be handled by semihosting.
+template <typename T>
+struct Result<SemiPseudoAbi32, T>
+{
+    static void store(ThreadContext *tc, const T &ret) {}
+};
+template <typename T>
+struct Result<SemiPseudoAbi64, T>
+{
+    static void store(ThreadContext *tc, const T &ret) {}
+};
+
+// Handle arguments the same as for semihosting operations. Skipping the first
+// slot is handled internally by the State type.
+template <typename T>
+struct Argument<SemiPseudoAbi32, T> :
+    public Argument<ArmSemihosting::Abi32, T>
+{};
+template <typename T>
+struct Argument<SemiPseudoAbi64, T> :
+    public Argument<ArmSemihosting::Abi64, T>
+{};
+
+} // namespace GuestABI
+
+ArmSemihosting::RetErrno
+ArmSemihosting::callGem5PseudoOp32(ThreadContext *tc, uint32_t encoded_func)
+{
+    uint8_t func;
+    PseudoInst::decodeAddrOffset(encoded_func, func);
+
+    uint64_t ret;
+    if (PseudoInst::pseudoInst<SemiPseudoAbi32>(tc, func, ret))
+        return retOK(ret);
+    else
+        return retError(EINVAL);
+}
+
+ArmSemihosting::RetErrno
+ArmSemihosting::callGem5PseudoOp64(ThreadContext *tc, uint64_t encoded_func)
+{
+    uint8_t func;
+    PseudoInst::decodeAddrOffset(encoded_func, func);
+
+    uint64_t ret;
+    if (PseudoInst::pseudoInst<SemiPseudoAbi64>(tc, func, ret))
+        return retOK(ret);
+    else
+        return retError(EINVAL);
+}
+
 FILE *
 ArmSemihosting::getSTDIO(const char *stream_name,
                          const std::string &name, const char *mode)
diff --git a/src/arch/arm/semihosting.hh b/src/arch/arm/semihosting.hh
index 5884349..e255d20 100644
--- a/src/arch/arm/semihosting.hh
+++ b/src/arch/arm/semihosting.hh
@@ -208,7 +208,9 @@
         SYS_ELAPSED = 0x30,
         SYS_TICKFREQ = 0x31,

-        MaxStandardOp = 0xFF
+        MaxStandardOp = 0xFF,
+
+        SYS_GEM5_PSEUDO_OP = 0x100
     };

     ArmSemihosting(const ArmSemihostingParams *p);
@@ -547,6 +549,9 @@
     RetErrno callElapsed64(ThreadContext *tc, InPlaceArg ticks);
     RetErrno callTickFreq(ThreadContext *tc);

+    RetErrno callGem5PseudoOp32(ThreadContext *tc, uint32_t encoded_func);
+    RetErrno callGem5PseudoOp64(ThreadContext *tc, uint64_t encoded_func);
+
     template <typename Abi>
     void
     unrecognizedCall(ThreadContext *tc, const char *format, uint64_t op)

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/25950
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ic4817f2b1e6aad7784af77a1a494cf614d4d4c6c
Gerrit-Change-Number: 25950
Gerrit-PatchSet: 15
Gerrit-Owner: Gabe Black <gabebl...@google.com>
Gerrit-Reviewer: Chun-Chen TK Hsu <chunchen...@google.com>
Gerrit-Reviewer: Gabe Black <gabebl...@google.com>
Gerrit-Reviewer: Gem5 Cloud Project GCB service account <345032938...@cloudbuild.gserviceaccount.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to