--- cpukit/score/Makefile.am | 10 ++ cpukit/score/include/rtems/score/timecounter.h | 23 +++ cpukit/score/include/sys/timeffc.h | 2 + cpukit/score/include/sys/timetc.h | 2 + cpukit/score/preinstall.am | 25 +++ cpukit/score/src/kern_tc.c | 171 ++++++++++++++++++++- testsuites/sptests/sptimecounter01/Makefile.am | 19 +++ testsuites/sptests/sptimecounter01/init.c | 130 ++++++++++++++++ .../sptests/sptimecounter01/sptimecounter01.doc | 11 ++ .../sptests/sptimecounter01/sptimecounter01.scn | 0 10 files changed, 390 insertions(+), 3 deletions(-) create mode 100644 cpukit/score/include/rtems/score/timecounter.h create mode 100644 testsuites/sptests/sptimecounter01/Makefile.am create mode 100644 testsuites/sptests/sptimecounter01/init.c create mode 100644 testsuites/sptests/sptimecounter01/sptimecounter01.doc create mode 100644 testsuites/sptests/sptimecounter01/sptimecounter01.scn
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 090f7f6..55fdc99 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -5,6 +5,15 @@ SUBDIRS = cpu ## include +include_sysdir = $(includedir)/sys + +include_sys_HEADERS = +include_sys_HEADERS += include/sys/_ffcounter.h +include_sys_HEADERS += include/sys/timeffc.h +include_sys_HEADERS += include/sys/timepps.h +include_sys_HEADERS += include/sys/timetc.h +include_sys_HEADERS += include/sys/timex.h + include_rtemsdir = $(includedir)/rtems include_rtems_HEADERS = include/rtems/debug.h @@ -343,6 +352,7 @@ libscore_a_SOURCES += src/profilingisrentryexit.c libscore_a_SOURCES += src/once.c libscore_a_SOURCES += src/resourceiterate.c libscore_a_SOURCES += src/smpbarrierwait.c +libscore_a_SOURCES += src/kern_tc.c EXTRA_DIST = src/Unlimited.txt diff --git a/cpukit/score/include/rtems/score/timecounter.h b/cpukit/score/include/rtems/score/timecounter.h new file mode 100644 index 0000000..3744a76 --- /dev/null +++ b/cpukit/score/include/rtems/score/timecounter.h @@ -0,0 +1,23 @@ + +#include <sys/time.h> + +void _Timecounter_Initialize(void); + +void _Timecounter_Set_clock(const struct timespec *ts); + +void _Timecounter_Ticktock(int cnt); + +void rtems_bintime(struct bintime *bt); +void rtems_nanotime(struct timespec *tsp); +void rtems_microtime(struct timeval *tvp); +void rtems_binuptime(struct bintime *bt); +void rtems_nanouptime(struct timespec *tsp); +void rtems_microuptime(struct timeval *tvp); +void rtems_getbintime(struct bintime *bt); +void rtems_getnanotime(struct timespec *tsp); +void rtems_getmicrotime(struct timeval *tvp); +void rtems_getbinuptime(struct bintime *bt); +void rtems_getnanouptime(struct timespec *tsp); +void rtems_getmicrouptime(struct timeval *tvp); + + diff --git a/cpukit/score/include/sys/timeffc.h b/cpukit/score/include/sys/timeffc.h index 3bda5d4..c3aed67 100644 --- a/cpukit/score/include/sys/timeffc.h +++ b/cpukit/score/include/sys/timeffc.h @@ -55,11 +55,13 @@ struct ffclock_estimate { #if __BSD_VISIBLE #ifdef _KERNEL +#ifndef __rtems__ /* Define the kern.sysclock sysctl tree. */ SYSCTL_DECL(_kern_sysclock); /* Define the kern.sysclock.ffclock sysctl tree. */ SYSCTL_DECL(_kern_sysclock_ffclock); +#endif /* __rtems__ */ /* * Index into the sysclocks array for obtaining the ASCII name of a particular diff --git a/cpukit/score/include/sys/timetc.h b/cpukit/score/include/sys/timetc.h index e68e327..1fed542 100644 --- a/cpukit/score/include/sys/timetc.h +++ b/cpukit/score/include/sys/timetc.h @@ -12,9 +12,11 @@ #ifndef _SYS_TIMETC_H_ #define _SYS_TIMETC_H_ +#ifndef __rtems__ #ifndef _KERNEL #error "no user-serviceable parts inside" #endif +#endif /* __rtems__ */ /*- * `struct timecounter' is the interface between the hardware which implements diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index 920c0d9..75c8be6 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -13,6 +13,31 @@ all-am: $(PREINSTALL_FILES) PREINSTALL_FILES = CLEANFILES = $(PREINSTALL_FILES) +$(PROJECT_INCLUDE)/sys/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/sys + @: > $(PROJECT_INCLUDE)/sys/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/sys/$(dirstamp) + +$(PROJECT_INCLUDE)/sys/_ffcounter.h: include/sys/_ffcounter.h $(PROJECT_INCLUDE)/sys/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/_ffcounter.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/_ffcounter.h + +$(PROJECT_INCLUDE)/sys/timeffc.h: include/sys/timeffc.h $(PROJECT_INCLUDE)/sys/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timeffc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timeffc.h + +$(PROJECT_INCLUDE)/sys/timepps.h: include/sys/timepps.h $(PROJECT_INCLUDE)/sys/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timepps.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timepps.h + +$(PROJECT_INCLUDE)/sys/timetc.h: include/sys/timetc.h $(PROJECT_INCLUDE)/sys/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timetc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timetc.h + +$(PROJECT_INCLUDE)/sys/timex.h: include/sys/timex.h $(PROJECT_INCLUDE)/sys/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timex.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timex.h + $(PROJECT_INCLUDE)/rtems/$(dirstamp): @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 1c29041..ba4396e 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -13,6 +13,23 @@ * of Melbourne under sponsorship from the FreeBSD Foundation. */ +#ifdef __rtems__ +#define _KERNEL +#define tc_init _Timecounter_Install +#define bintime _Timecounter_Bintime +#define nanotime _Timecounter_Nanotime +#define microtime _Timecounter_Microtime +#define binuptime _Timecounter_Binuptime +#define nanouptime _Timecounter_Nanouptime +#define microuptime _Timecounter_Microuptime +#define getbintime _Timecounter_Getbintime +#define getnanouptime _Timecounter_Getnanouptime +#define getmicrouptime _Timecounter_Getmicrouptime +#define getbinuptime _Timecounter_Getbinuptime +#define getnanouptime _Timecounter_Getnanouptime +#define getmicrouptime _Timecounter_Getmicrouptime +#include <rtems/score/timecounterimpl.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -21,20 +38,50 @@ __FBSDID("$FreeBSD$"); #include "opt_ffclock.h" #include <sys/param.h> +#ifndef __rtems__ #include <sys/kernel.h> #include <sys/limits.h> +#else /* __rtems__ */ +#include <limits.h> +#endif /* __rtems__ */ #ifdef FFCLOCK #include <sys/lock.h> #include <sys/mutex.h> #endif +#ifndef __rtems__ #include <sys/sysctl.h> #include <sys/syslog.h> #include <sys/systm.h> +#endif /* __rtems__ */ #include <sys/timeffc.h> #include <sys/timepps.h> #include <sys/timetc.h> #include <sys/timex.h> +#ifndef __rtems__ #include <sys/vdso.h> +#endif /* __rtems__ */ +#ifdef __rtems__ +#include <rtems.h> +ISR_LOCK_DEFINE(static, _Timecounter_Lock, "Timecounter"); +#define hz rtems_clock_get_ticks_per_second() +#define bootverbose 0 +#define printf(...) +#define log(...) +/* FIXME */ +static inline int +fls(int x) +{ + return x ? sizeof(x) * 8 - __builtin_clz(x) : 0; +} +/* FIXME */ +static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); } +/* FIXME */ +struct bintime tick_bt; /* bintime per tick (1s / hz) */ +/* FIXME */ +sbintime_t tick_sbt; +/* FIXME */ +#define ntp_update_second(a, b) do { (void) a; (void) b; } while (0) +#endif /* __rtems__ */ /* * A large step happens on boot. This constant detects such steps. @@ -76,6 +123,7 @@ struct timehands { struct timehands *th_next; }; +#if defined(RTEMS_SMP) static struct timehands th0; static struct timehands th9 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th0}; static struct timehands th8 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th9}; @@ -86,6 +134,7 @@ static struct timehands th4 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th5}; static struct timehands th3 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th4}; static struct timehands th2 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th3}; static struct timehands th1 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th2}; +#endif static struct timehands th0 = { &dummy_timecounter, 0, @@ -95,7 +144,11 @@ static struct timehands th0 = { {0, 0}, {0, 0}, 1, +#if defined(RTEMS_SMP) &th1 +#else + &th0 +#endif }; static struct timehands *volatile timehands = &th0; @@ -108,6 +161,7 @@ volatile time_t time_second = 1; volatile time_t time_uptime = 1; struct bintime boottimebin; +#ifndef __rtems__ struct timeval boottime; static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS); SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD, @@ -119,6 +173,7 @@ static SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, CTLFLAG_RW, 0, ""); static int timestepwarnings; SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, ×tepwarnings, 0, "Log time steps"); +#endif /* __rtems__ */ struct bintime bt_timethreshold; struct bintime bt_tickthreshold; @@ -128,17 +183,22 @@ struct bintime tc_tick_bt; sbintime_t tc_tick_sbt; int tc_precexp; int tc_timepercentage = TC_DEFAULTPERC; +#ifndef __rtems__ static int sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS); SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation, CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_timecounter_adjprecision, "I", "Allowed time interval deviation in percents"); +#endif /* __rtems__ */ static void tc_windup(void); +#ifndef __rtems__ static void cpu_tick_calibrate(int); +#endif /* __rtems__ */ void dtrace_getnanotime(struct timespec *tsp); +#ifndef __rtems__ static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) { @@ -175,6 +235,7 @@ sysctl_kern_timecounter_freq(SYSCTL_HANDLER_ARGS) freq = tc->tc_frequency; return sysctl_handle_64(oidp, &freq, 0, req); } +#endif /* __rtems__ */ /* * Return the difference between the timehands' counter value now and what @@ -994,16 +1055,19 @@ dtrace_getnanotime(struct timespec *tsp) } while (gen == 0 || gen != th->th_generation); } +#ifdef FFCLOCK /* * System clock currently providing time to the system. Modifiable via sysctl * when the FFCLOCK option is defined. */ int sysclock_active = SYSCLOCK_FBCK; +#endif /* Internal NTP status and error estimates. */ extern int time_status; extern long time_esterror; +#ifndef __rtems__ /* * Take a snapshot of sysclock data which can be used to compare system clocks * and generate timestamps after the fact. @@ -1046,7 +1110,9 @@ sysclock_getsnapshot(struct sysclock_snap *clock_snap, int fast) } while (gen == 0 || gen != th->th_generation); clock_snap->delta = delta; +#ifdef FFCLOCK clock_snap->sysclock_active = sysclock_active; +#endif /* Record feedback clock status and error. */ clock_snap->fb_info.status = time_status; @@ -1133,6 +1199,7 @@ sysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt, return (0); } +#endif /* __rtems__ */ /* * Initialize a new timecounter and possibly use it. @@ -1140,9 +1207,11 @@ sysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt, void tc_init(struct timecounter *tc) { - u_int u; +// u_int u; +#ifndef __rtems__ struct sysctl_oid *tc_root; - +#endif /* __rtems__ */ +#if 0 u = tc->tc_frequency / tc->tc_counter_mask; /* XXX: We need some margin here, 10% is a guess */ u *= 11; @@ -1159,9 +1228,10 @@ tc_init(struct timecounter *tc) tc->tc_name, (uintmax_t)tc->tc_frequency, tc->tc_quality); } - +#endif tc->tc_next = timecounters; timecounters = tc; +#ifndef __rtems__ /* * Set up sysctl tree for this counter. */ @@ -1180,11 +1250,13 @@ tc_init(struct timecounter *tc) SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, "quality", CTLFLAG_RD, &(tc->tc_quality), 0, "goodness of time counter"); +#endif /* __rtems__ */ /* * Never automatically use a timecounter with negative quality. * Even though we run on the dummy counter, switching here may be * worse since this timecounter may not be monotonous. */ +#if 0 if (tc->tc_quality < 0) return; if (tc->tc_quality < timecounter->tc_quality) @@ -1192,9 +1264,13 @@ tc_init(struct timecounter *tc) if (tc->tc_quality == timecounter->tc_quality && tc->tc_frequency < timecounter->tc_frequency) return; +#endif (void)tc->tc_get_timecount(tc); (void)tc->tc_get_timecount(tc); timecounter = tc; +#ifdef __rtems__ + tc_windup(); +#endif /* __rtems__ */ } /* Report the frequency of the current timecounter. */ @@ -1210,23 +1286,36 @@ tc_getfrequency(void) * when we booted. * XXX: not locked. */ + +#ifndef __rtems__ void tc_setclock(struct timespec *ts) +#else /* __rtems__ */ +void +_Timecounter_Set_clock(const struct timespec *ts) +#endif /* __rtems__ */ { +#ifndef __rtems__ struct timespec tbef, taft; +#endif /* __rtems__ */ struct bintime bt, bt2; +#ifndef __rtems__ cpu_tick_calibrate(1); nanotime(&tbef); +#endif /* __rtems__ */ timespec2bintime(ts, &bt); binuptime(&bt2); bintime_sub(&bt, &bt2); bintime_add(&bt2, &boottimebin); boottimebin = bt; +#ifndef __rtems__ bintime2timeval(&bt, &boottime); +#endif /* __rtems__ */ /* XXX fiddle all the little crinkly bits around the fiords... */ tc_windup(); +#ifndef __rtems__ nanotime(&taft); if (timestepwarnings) { log(LOG_INFO, @@ -1236,6 +1325,7 @@ tc_setclock(struct timespec *ts) (intmax_t)ts->tv_sec, ts->tv_nsec); } cpu_tick_calibrate(1); +#endif /* __rtems__ */ } /* @@ -1243,6 +1333,7 @@ tc_setclock(struct timespec *ts) * it the active timehands. Along the way we might switch to a different * timecounter and/or do seconds processing in NTP. Slightly magic. */ + static void tc_windup(void) { @@ -1252,6 +1343,11 @@ tc_windup(void) u_int delta, ncount, ogen; int i; time_t t; +#ifdef __rtems__ + ISR_lock_Context lock_context; + + _ISR_lock_ISR_disable_and_acquire(_Timecounter_Lock, &lock_context); +#endif /* __rtems__ */ /* * Make the next timehands a copy of the current one, but do not @@ -1329,12 +1425,14 @@ tc_windup(void) /* Now is a good time to change timecounters. */ if (th->th_counter != timecounter) { +#ifndef __rtems__ #ifndef __arm__ if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0) cpu_disable_c2_sleep++; if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0) cpu_disable_c2_sleep--; #endif +#endif /* __rtems__ */ th->th_counter = timecounter; th->th_offset_count = ncount; tc_min_ticktock_freq = max(1, timecounter->tc_frequency / @@ -1397,9 +1495,17 @@ tc_windup(void) #endif timehands = th; +#ifndef __rtems__ timekeep_push_vdso(); +#endif /* __rtems__ */ +#ifdef __rtems__ + _ISR_lock_Release_and_ISR_enable(_Timecounter_Lock, &lock_context); +#endif /* __rtems__ */ } + + +#ifndef __rtems__ /* Report or change the active timecounter hardware. */ static int sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) @@ -1464,7 +1570,9 @@ sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD, 0, 0, sysctl_kern_timecounter_choice, "A", "Timecounter hardware detected"); +#endif /* __rtems__ */ +#ifndef __rtems__ /* * RFC 2783 PPS-API implementation. */ @@ -1745,6 +1853,7 @@ pps_event(struct pps_state *pps, int event) /* Wakeup anyone sleeping in pps_fetch(). */ wakeup(pps); } +#endif /* __rtems__ */ /* * Timecounters need to be updated every so often to prevent the hardware @@ -1754,12 +1863,21 @@ pps_event(struct pps_state *pps, int event) */ static int tc_tick; +#ifndef __rtems__ SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tc_tick, 0, "Approximate number of hardclock ticks in a millisecond"); +#endif /* __rtems__ */ +#ifndef __rtems__ void tc_ticktock(int cnt) { +#else /* __rtems__ */ +void +_Timecounter_Tick(void) +{ + int cnt = 1; +#endif /* __rtems__ */ static int count; count += cnt; @@ -1768,6 +1886,37 @@ tc_ticktock(int cnt) count = 0; tc_windup(); } +#ifdef __rtems__ +void +_Timecounter_Tick_simple(u_int delta, u_int offset) +{ + struct timehands *th; + u_int ogen; + ISR_lock_Context lock_context; + + _ISR_lock_ISR_disable_and_acquire(_Timecounter_Lock, &lock_context); + + th = timehands; + ogen = th->th_generation; + th->th_offset_count = offset; + bintime_addx(&th->th_offset, th->th_scale * delta); + + /* Update the UTC timestamps used by the get*() functions. */ + /* XXX shouldn't do this here. Should force non-`get' versions. */ + bintime2timeval(&th->th_offset, &th->th_microtime); + bintime2timespec(&th->th_offset, &th->th_nanotime); + + /* + * Now that the struct timehands is again consistent, set the new + * generation number, making sure to not make it zero. + */ + if (++ogen == 0) + ogen = 1; + th->th_generation = ogen; + + _ISR_lock_Release_and_ISR_enable(_Timecounter_Lock, &lock_context); +} +#endif /* __rtems__ */ static void __inline tc_adjprecision(void) @@ -1791,6 +1940,7 @@ tc_adjprecision(void) sbt_tickthreshold = bttosbt(bt_tickthreshold); } +#ifndef __rtems__ static int sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS) { @@ -1807,9 +1957,15 @@ sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS) done: return (0); } +#endif /* __rtems__ */ +#ifndef __rtems__ static void inittimecounter(void *dummy) +#else /* __rtems__ */ +void +_Timecounter_Initialize(void) +#endif /* __rtems__ */ { u_int p; int tick_rate; @@ -1834,6 +1990,9 @@ inittimecounter(void *dummy) tc_tick_sbt = bttosbt(tc_tick_bt); p = (tc_tick * 1000000) / hz; printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000); +#ifdef __rtems__ + (void) p; +#endif /* __rtems__ */ #ifdef FFCLOCK ffclock_init(); @@ -1844,8 +2003,11 @@ inittimecounter(void *dummy) tc_windup(); } +#ifndef __rtems__ SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL); +#endif /* __rtems__ */ +#ifndef __rtems__ /* Cpu tick handling -------------------------------------------------*/ static int cpu_tick_variable; @@ -1978,7 +2140,9 @@ cputick2usec(uint64_t tick) } cpu_tick_f *cpu_ticks = tc_cpu_ticks; +#endif /* __rtems__ */ +#ifndef __rtems__ static int vdso_th_enable = 1; static int sysctl_fast_gettime(SYSCTL_HANDLER_ARGS) @@ -2014,6 +2178,7 @@ tc_fill_vdso_timehands(struct vdso_timehands *vdso_th) enabled = 0; return (enabled); } +#endif /* __rtems__ */ #ifdef COMPAT_FREEBSD32 uint32_t diff --git a/testsuites/sptests/sptimecounter01/Makefile.am b/testsuites/sptests/sptimecounter01/Makefile.am new file mode 100644 index 0000000..b231088 --- /dev/null +++ b/testsuites/sptests/sptimecounter01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = sptimecounter01 +sptimecounter01_SOURCES = init.c + +dist_rtems_tests_DATA = sptimecounter01.scn sptimecounter01.doc + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(sptimecounter01_OBJECTS) +LINK_LIBS = $(sptimecounter01_LDLIBS) + +sptimecounter01$(EXEEXT): $(sptimecounter01_OBJECTS) $(sptimecounter01_DEPENDENCIES) + @rm -f sptimecounter01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c new file mode 100644 index 0000000..e698761 --- /dev/null +++ b/testsuites/sptests/sptimecounter01/init.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rt...@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include <assert.h> + +#include <bsp/bootcard.h> + +#include <rtems/test.h> + +#include <rtems/score/timecounterimpl.h> +#include <rtems/timecounter.h> + +const char rtems_test_name[] = "SPTIMECOUNTER_1"; + +typedef struct { + struct timecounter tc_soft; + u_int tc_soft_counter; +} test_context; + +static test_context test_instance; + +static u_int test_get_timecount_soft(struct timecounter *tc) +{ + test_context *ctx = tc->tc_priv; + + ++ctx->tc_soft_counter; + + return ctx->tc_soft_counter; +} + +void boot_card(const char *cmdline) +{ + test_context *ctx = &test_instance; + struct timecounter *tc_soft = &ctx->tc_soft; + uint64_t soft_freq = 1000000; + struct bintime bt; + + rtems_test_begink(); + + _Timecounter_Initialize(); + + rtems_binuptime(&bt); + assert(bt.sec == 1); + assert(bt.frac== 73786976294835); + + rtems_binuptime(&bt); + assert(bt.sec == 1); + assert(bt.frac == 92233720368543); + + _Timecounter_Tick(); + rtems_binuptime(&bt); + assert(bt.sec == 1); + assert(bt.frac == 129127208515959); + + ctx->tc_soft_counter = 0; + tc_soft->tc_get_timecount = test_get_timecount_soft; + tc_soft->tc_counter_mask = 0x0fffffff; + tc_soft->tc_frequency = soft_freq; + tc_soft->tc_quality = 1234; + tc_soft->tc_priv = ctx; + _Timecounter_Install(tc_soft); + assert(ctx->tc_soft_counter == 3); + + rtems_binuptime(&bt); + assert(ctx->tc_soft_counter == 4); + + assert(bt.sec == 1); + assert(bt.frac == 166020696663375); + + ctx->tc_soft_counter = 0xf0000000 | 3; + rtems_binuptime(&bt); + assert(ctx->tc_soft_counter == (0xf0000000 | 4)); + + assert(bt.sec == 1); + assert(bt.frac == 166020696663375); + + /* Ensure that the fraction overflows and the second remains constant */ + ctx->tc_soft_counter = (0xf0000000 | 3) + soft_freq; + rtems_binuptime(&bt); + assert(ctx->tc_soft_counter == (0xf0000000 | 4) + soft_freq); + assert(bt.sec == 1); + assert(bt.frac == 166020695111759); + + rtems_test_endk(); + + _Terminate(RTEMS_FATAL_SOURCE_EXIT, false, 0); +} + +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER + +#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + +#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY + +#define CONFIGURE_SCHEDULER_USER + +#define CONFIGURE_SCHEDULER_CONTEXT + +#define CONFIGURE_SCHEDULER_CONTROLS { } + +#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER 0 + +#define CONFIGURE_TASK_STACK_ALLOCATOR NULL + +#define CONFIGURE_TASK_STACK_DEALLOCATOR NULL + +#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION + +#define CONFIGURE_IDLE_TASK_BODY NULL + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_INIT + +#include <rtems/confdefs.h> diff --git a/testsuites/sptests/sptimecounter01/sptimecounter01.doc b/testsuites/sptests/sptimecounter01/sptimecounter01.doc new file mode 100644 index 0000000..3568f72 --- /dev/null +++ b/testsuites/sptests/sptimecounter01/sptimecounter01.doc @@ -0,0 +1,11 @@ +This file describes the directives and concepts tested by this test set. + +test set name: sptimecounter01 + +directives: + + TBD + +concepts: + + TBD diff --git a/testsuites/sptests/sptimecounter01/sptimecounter01.scn b/testsuites/sptests/sptimecounter01/sptimecounter01.scn new file mode 100644 index 0000000..e69de29 -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel