[PATCH 7/9] semihosting: Implement SYS_ELAPSED and SYS_TICKFREQ

2021-01-07 Thread Keith Packard via
These are part of Semihosting for AArch32 and AArch64 Release 2.0

Signed-off-by: Keith Packard 
Message-Id: <20201214200713.3886611-8-kei...@keithp.com>
---
 hw/semihosting/common-semi.c | 16 
 include/qemu/timer.h |  2 ++
 util/qemu-timer-common.c |  4 
 3 files changed, 22 insertions(+)

diff --git a/hw/semihosting/common-semi.c b/hw/semihosting/common-semi.c
index f0cf5f10f5..b1368d945c 100644
--- a/hw/semihosting/common-semi.c
+++ b/hw/semihosting/common-semi.c
@@ -38,6 +38,7 @@
 #include "hw/semihosting/console.h"
 #include "hw/semihosting/common-semi.h"
 #include "qemu/log.h"
+#include "qemu/timer.h"
 #ifdef CONFIG_USER_ONLY
 #include "qemu.h"
 
@@ -73,6 +74,8 @@
 #define TARGET_SYS_EXIT0x18
 #define TARGET_SYS_SYNCCACHE   0x19
 #define TARGET_SYS_EXIT_EXTENDED 0x20
+#define TARGET_SYS_ELAPSED 0x30
+#define TARGET_SYS_TICKFREQ0x31
 
 /* ADP_Stopped_ApplicationExit is used for exit(0),
  * anything else is implemented as exit(1) */
@@ -837,6 +840,7 @@ target_ulong do_common_semihosting(CPUState *cs)
 uint32_t ret;
 uint32_t len;
 GuestFD *gf;
+int64_t elapsed;
 
 (void) env; /* Used implicitly by arm lock_user macro */
 nr = common_semi_arg(cs, 0) & 0xU;
@@ -1246,6 +1250,18 @@ target_ulong do_common_semihosting(CPUState *cs)
 }
 gdb_exit(cs->env_ptr, ret);
 exit(ret);
+case TARGET_SYS_ELAPSED:
+elapsed = get_clock() - clock_start;
+if (sizeof(target_ulong) == 8) {
+SET_ARG(0, elapsed);
+} else {
+SET_ARG(0, (uint32_t) elapsed);
+SET_ARG(1, (uint32_t) (elapsed >> 32));
+}
+return 0;
+case TARGET_SYS_TICKFREQ:
+/* qemu always uses nsec */
+return 10;
 case TARGET_SYS_SYNCCACHE:
 /*
  * Clean the D-cache and invalidate the I-cache for the specified
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index bdecc5b41f..ca6fae51f1 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -806,6 +806,8 @@ static inline int64_t get_clock_realtime(void)
 return tv.tv_sec * 10LL + (tv.tv_usec * 1000);
 }
 
+extern int64_t clock_start;
+
 /* Warning: don't insert tracepoints into these functions, they are
also used by simpletrace backend and tracepoints would cause
an infinite recursion! */
diff --git a/util/qemu-timer-common.c b/util/qemu-timer-common.c
index baf3317f74..cc1326f726 100644
--- a/util/qemu-timer-common.c
+++ b/util/qemu-timer-common.c
@@ -27,6 +27,8 @@
 /***/
 /* real time host monotonic timer */
 
+int64_t clock_start;
+
 #ifdef _WIN32
 
 int64_t clock_freq;
@@ -41,6 +43,7 @@ static void __attribute__((constructor)) init_get_clock(void)
 exit(1);
 }
 clock_freq = freq.QuadPart;
+clock_start = get_clock();
 }
 
 #else
@@ -55,5 +58,6 @@ static void __attribute__((constructor)) init_get_clock(void)
 if (clock_gettime(CLOCK_MONOTONIC, ) == 0) {
 use_rt_clock = 1;
 }
+clock_start = get_clock();
 }
 #endif
-- 
2.29.2




[PATCH 7/9] semihosting: Implement SYS_ELAPSED and SYS_TICKFREQ

2020-12-14 Thread Keith Packard via
These are part of Semihosting for AArch32 and AArch64 Release 2.0

Signed-off-by: Keith Packard 
---
 hw/semihosting/common-semi.c | 16 
 include/qemu/timer.h |  2 ++
 util/qemu-timer-common.c |  4 
 3 files changed, 22 insertions(+)

diff --git a/hw/semihosting/common-semi.c b/hw/semihosting/common-semi.c
index f0cf5f10f5..b1368d945c 100644
--- a/hw/semihosting/common-semi.c
+++ b/hw/semihosting/common-semi.c
@@ -38,6 +38,7 @@
 #include "hw/semihosting/console.h"
 #include "hw/semihosting/common-semi.h"
 #include "qemu/log.h"
+#include "qemu/timer.h"
 #ifdef CONFIG_USER_ONLY
 #include "qemu.h"
 
@@ -73,6 +74,8 @@
 #define TARGET_SYS_EXIT0x18
 #define TARGET_SYS_SYNCCACHE   0x19
 #define TARGET_SYS_EXIT_EXTENDED 0x20
+#define TARGET_SYS_ELAPSED 0x30
+#define TARGET_SYS_TICKFREQ0x31
 
 /* ADP_Stopped_ApplicationExit is used for exit(0),
  * anything else is implemented as exit(1) */
@@ -837,6 +840,7 @@ target_ulong do_common_semihosting(CPUState *cs)
 uint32_t ret;
 uint32_t len;
 GuestFD *gf;
+int64_t elapsed;
 
 (void) env; /* Used implicitly by arm lock_user macro */
 nr = common_semi_arg(cs, 0) & 0xU;
@@ -1246,6 +1250,18 @@ target_ulong do_common_semihosting(CPUState *cs)
 }
 gdb_exit(cs->env_ptr, ret);
 exit(ret);
+case TARGET_SYS_ELAPSED:
+elapsed = get_clock() - clock_start;
+if (sizeof(target_ulong) == 8) {
+SET_ARG(0, elapsed);
+} else {
+SET_ARG(0, (uint32_t) elapsed);
+SET_ARG(1, (uint32_t) (elapsed >> 32));
+}
+return 0;
+case TARGET_SYS_TICKFREQ:
+/* qemu always uses nsec */
+return 10;
 case TARGET_SYS_SYNCCACHE:
 /*
  * Clean the D-cache and invalidate the I-cache for the specified
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index bdecc5b41f..ca6fae51f1 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -806,6 +806,8 @@ static inline int64_t get_clock_realtime(void)
 return tv.tv_sec * 10LL + (tv.tv_usec * 1000);
 }
 
+extern int64_t clock_start;
+
 /* Warning: don't insert tracepoints into these functions, they are
also used by simpletrace backend and tracepoints would cause
an infinite recursion! */
diff --git a/util/qemu-timer-common.c b/util/qemu-timer-common.c
index baf3317f74..cc1326f726 100644
--- a/util/qemu-timer-common.c
+++ b/util/qemu-timer-common.c
@@ -27,6 +27,8 @@
 /***/
 /* real time host monotonic timer */
 
+int64_t clock_start;
+
 #ifdef _WIN32
 
 int64_t clock_freq;
@@ -41,6 +43,7 @@ static void __attribute__((constructor)) init_get_clock(void)
 exit(1);
 }
 clock_freq = freq.QuadPart;
+clock_start = get_clock();
 }
 
 #else
@@ -55,5 +58,6 @@ static void __attribute__((constructor)) init_get_clock(void)
 if (clock_gettime(CLOCK_MONOTONIC, ) == 0) {
 use_rt_clock = 1;
 }
+clock_start = get_clock();
 }
 #endif
-- 
2.29.2