diff --git a/libgloss/Makefile.in b/libgloss/Makefile.in index b799cd3b7..40613820f 100644 --- a/libgloss/Makefile.in +++ b/libgloss/Makefile.in @@ -1244,6 +1244,7 @@ riscv_libsemihost_a_LIBADD = @CONFIG_RISCV_TRUE@ riscv/riscv_libsemihost_a-semihost-sys_sbrk.$(OBJEXT) \ @CONFIG_RISCV_TRUE@ riscv/riscv_libsemihost_a-semihost-sys_stat.$(OBJEXT) \ @CONFIG_RISCV_TRUE@ riscv/riscv_libsemihost_a-semihost-sys_stat_common.$(OBJEXT) \ +@CONFIG_RISCV_TRUE@ riscv/riscv_libsemihost_a-semihost-sys_times.$(OBJEXT) \ @CONFIG_RISCV_TRUE@ riscv/riscv_libsemihost_a-semihost-sys_unlink.$(OBJEXT) \ @CONFIG_RISCV_TRUE@ riscv/riscv_libsemihost_a-semihost-sys_write.$(OBJEXT) riscv_libsemihost_a_OBJECTS = $(am_riscv_libsemihost_a_OBJECTS) @@ -2611,6 +2612,7 @@ TEXINFO_TEX = ../texinfo/texinfo.tex @CONFIG_RISCV_TRUE@ riscv/semihost-sys_sbrk.c \ @CONFIG_RISCV_TRUE@ riscv/semihost-sys_stat.c \ @CONFIG_RISCV_TRUE@ riscv/semihost-sys_stat_common.c \ +@CONFIG_RISCV_TRUE@ riscv/semihost-sys_times.c \ @CONFIG_RISCV_TRUE@ riscv/semihost-sys_unlink.c \ @CONFIG_RISCV_TRUE@ riscv/semihost-sys_write.c @@ -4538,6 +4540,8 @@ riscv/riscv_libsemihost_a-semihost-sys_stat.$(OBJEXT): \ riscv/$(am__dirstamp) riscv/$(DEPDIR)/$(am__dirstamp) riscv/riscv_libsemihost_a-semihost-sys_stat_common.$(OBJEXT): \ riscv/$(am__dirstamp) riscv/$(DEPDIR)/$(am__dirstamp) +riscv/riscv_libsemihost_a-semihost-sys_times.$(OBJEXT): \ + riscv/$(am__dirstamp) riscv/$(DEPDIR)/$(am__dirstamp) riscv/riscv_libsemihost_a-semihost-sys_unlink.$(OBJEXT): \ riscv/$(am__dirstamp) riscv/$(DEPDIR)/$(am__dirstamp) riscv/riscv_libsemihost_a-semihost-sys_write.$(OBJEXT): \ @@ -5768,6 +5772,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_sbrk.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_stat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_stat_common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_unlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@riscv/$(DEPDIR)/riscv_libsemihost_a-sys_chdir.Po@am__quote@ @@ -7799,6 +7804,20 @@ riscv/riscv_libsemihost_a-semihost-sys_stat_common.obj: riscv/semihost-sys_stat_ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(riscv_libsemihost_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o riscv/riscv_libsemihost_a-semihost-sys_stat_common.obj `if test -f 'riscv/semihost-sys_stat_common.c'; then $(CYGPATH_W) 'riscv/semihost-sys_stat_common.c'; else $(CYGPATH_W) '$(srcdir)/riscv/semihost-sys_stat_common.c'; fi` +riscv/riscv_libsemihost_a-semihost-sys_times.o: riscv/semihost-sys_times.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(riscv_libsemihost_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT riscv/riscv_libsemihost_a-semihost-sys_times.o -MD -MP -MF riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Tpo -c -o riscv/riscv_libsemihost_a-semihost-sys_times.o `test -f 'riscv/semihost-sys_times.c' || echo '$(srcdir)/'`riscv/semihost-sys_times.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Tpo riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='riscv/semihost-sys_times.c' object='riscv/riscv_libsemihost_a-semihost-sys_times.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(riscv_libsemihost_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o riscv/riscv_libsemihost_a-semihost-sys_times.o `test -f 'riscv/semihost-sys_times.c' || echo '$(srcdir)/'`riscv/semihost-sys_times.c + +riscv/riscv_libsemihost_a-semihost-sys_times.obj: riscv/semihost-sys_times.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(riscv_libsemihost_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT riscv/riscv_libsemihost_a-semihost-sys_times.obj -MD -MP -MF riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Tpo -c -o riscv/riscv_libsemihost_a-semihost-sys_times.obj `if test -f 'riscv/semihost-sys_times.c'; then $(CYGPATH_W) 'riscv/semihost-sys_times.c'; else $(CYGPATH_W) '$(srcdir)/riscv/semihost-sys_times.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Tpo riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_times.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='riscv/semihost-sys_times.c' object='riscv/riscv_libsemihost_a-semihost-sys_times.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(riscv_libsemihost_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o riscv/riscv_libsemihost_a-semihost-sys_times.obj `if test -f 'riscv/semihost-sys_times.c'; then $(CYGPATH_W) 'riscv/semihost-sys_times.c'; else $(CYGPATH_W) '$(srcdir)/riscv/semihost-sys_times.c'; fi` + riscv/riscv_libsemihost_a-semihost-sys_unlink.o: riscv/semihost-sys_unlink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(riscv_libsemihost_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT riscv/riscv_libsemihost_a-semihost-sys_unlink.o -MD -MP -MF riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_unlink.Tpo -c -o riscv/riscv_libsemihost_a-semihost-sys_unlink.o `test -f 'riscv/semihost-sys_unlink.c' || echo '$(srcdir)/'`riscv/semihost-sys_unlink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_unlink.Tpo riscv/$(DEPDIR)/riscv_libsemihost_a-semihost-sys_unlink.Po diff --git a/libgloss/riscv/Makefile.inc b/libgloss/riscv/Makefile.inc index 7218d7ac7..4d998cae3 100644 --- a/libgloss/riscv/Makefile.inc +++ b/libgloss/riscv/Makefile.inc @@ -74,6 +74,7 @@ multilibtool_LIBRARIES += %D%/libsemihost.a %D%/semihost-sys_sbrk.c \ %D%/semihost-sys_stat.c \ %D%/semihost-sys_stat_common.c \ + %D%/semihost-sys_times.c \ %D%/semihost-sys_unlink.c \ %D%/semihost-sys_write.c diff --git a/libgloss/riscv/semihost-sys_times.c b/libgloss/riscv/semihost-sys_times.c new file mode 100644 index 000000000..9e0ba51c5 --- /dev/null +++ b/libgloss/riscv/semihost-sys_times.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include "semihost_syscall.h" + +clock_t +_times(struct tms *buf) +{ + static bool initialized = false; + static clock_t semihosting_tick_freq = 0; + static bool semihosting_tick_freq_bigger = false; + static clock_t semihosting_tick_freq_multiplier = 0; + clock_t elapsed; + + /* SYS_ELAPSED semihosting call returns a single 64-bit value for 64-bit + targets and two 32-bit values for 32-bit targets. */ +#if __riscv_xlen == 32 + long data_block[2]; +#else + long data_block[1]; +#endif + + if (!initialized) + { + /* clock() function from libc must return value which gives us seconds + when it's multiplied by CLOCKS_PER_SEC. By default, CLOCKS_PER_SEC + is 10**6 for RISC-V. However, semihosting's tick frequency may + differ and usually it's 10**9. Thus, we have to obtain a real value + of the tick frequency for the current semihosting setup and + calculate a multiplier and use it for adjusting semihosting's + number of ticks. E.g., if semihosting's ticks frequency is 10**9 then + multiplier is 10**9 / 10**6 = 1000. */ + semihosting_tick_freq = syscall_errno (SEMIHOST_tickfreq, NULL); + + if (semihosting_tick_freq > CLOCKS_PER_SEC) + { + semihosting_tick_freq_multiplier = semihosting_tick_freq / CLOCKS_PER_SEC; + semihosting_tick_freq_bigger = true; + } + else + semihosting_tick_freq_multiplier = CLOCKS_PER_SEC / semihosting_tick_freq; + + initialized = true; + } + + /* SYS_ELAPSED semihosting call returns a number of ticks. */ + syscall_errno (SEMIHOST_elapsed, data_block); + +#if __riscv_xlen == 32 + elapsed = (((uint64_t) data_block[1]) << 32) | ((uint32_t) data_block[0]); +#else + elapsed = data_block[0]; +#endif + + /* Adjust the number of ticks to make it compatible with CLOCKS_PER_SEC. */ + if (semihosting_tick_freq_bigger) + elapsed /= semihosting_tick_freq_multiplier; + else + elapsed *= semihosting_tick_freq_multiplier; + + if (buf) + { + buf->tms_utime = elapsed; + buf->tms_stime = 0; + buf->tms_cutime = 0; + buf->tms_cstime = 0; + } + + return elapsed; +}