[rtems commit] sptests/spcache01: New test

Sebastian Huber sebh at rtems.org
Mon Feb 24 15:06:30 UTC 2014


Module:    rtems
Branch:    master
Commit:    3378be955aebaff4f2bbab8dda38231871dc211d
Changeset: http://git.rtems.org/rtems/commit/?id=3378be955aebaff4f2bbab8dda38231871dc211d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Feb 17 08:16:54 2014 +0100

sptests/spcache01: New test

---

 testsuites/sptests/Makefile.am             |    1 +
 testsuites/sptests/configure.ac            |    1 +
 testsuites/sptests/spcache01/Makefile.am   |   19 ++
 testsuites/sptests/spcache01/init.c        |  348 ++++++++++++++++++++++++++++
 testsuites/sptests/spcache01/spcache01.doc |   19 ++
 testsuites/sptests/spcache01/spcache01.scn |   38 +++
 6 files changed, 426 insertions(+), 0 deletions(-)

diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index c9f0182..3aa1330 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -30,6 +30,7 @@ SUBDIRS = \
     spsimplesched03 spnsext01 spedfsched01 spedfsched02 spedfsched03 \
     spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \
     spregion_err01 sppartition_err01
+SUBDIRS += spcache01
 SUBDIRS += sptls03
 SUBDIRS += spcpucounter01
 if HAS_CPLUSPLUS
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 1ef58cc..fe9f816 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -36,6 +36,7 @@ AM_CONDITIONAL(HAS_CPUSET,test x"${ac_cv_header_sys_cpuset_h}" = x"yes")
 
 # Explicitly list all Makefiles here
 AC_CONFIG_FILES([Makefile
+spcache01/Makefile
 sptls03/Makefile
 spcpucounter01/Makefile
 sptls02/Makefile
diff --git a/testsuites/sptests/spcache01/Makefile.am b/testsuites/sptests/spcache01/Makefile.am
new file mode 100644
index 0000000..6a839ee
--- /dev/null
+++ b/testsuites/sptests/spcache01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = spcache01
+spcache01_SOURCES = init.c
+
+dist_rtems_tests_DATA = spcache01.scn spcache01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(spcache01_OBJECTS)
+LINK_LIBS = $(spcache01_LDLIBS)
+
+spcache01$(EXEEXT): $(spcache01_OBJECTS) $(spcache01_DEPENDENCIES)
+	@rm -f spcache01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/spcache01/init.c b/testsuites/sptests/spcache01/init.c
new file mode 100644
index 0000000..9f27a79
--- /dev/null
+++ b/testsuites/sptests/spcache01/init.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <rtems.h>
+#include <rtems/counter.h>
+
+#define TESTS_USE_PRINTF
+#include "tmacros.h"
+
+#define I() __asm__ volatile ("nop")
+
+#define I8() I(); I(); I(); I(); I(); I(); I(); I()
+
+#define I64() I8(); I8(); I8(); I8(); I8(); I8(); I8(); I8()
+
+#define I512() I64(); I64(); I64(); I64(); I64(); I64(); I64(); I64()
+
+CPU_STRUCTURE_ALIGNMENT static int data[1024];
+
+static void test_data_flush_and_invalidate(void)
+{
+  if (rtems_cache_get_data_line_size() > 0) {
+    rtems_interrupt_level level;
+    rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
+    volatile int *vdata = &data[0];
+    int n = 32;
+    int i;
+    size_t data_size = n * sizeof(data[0]);
+
+    printf("data cache flush and invalidate test\n");
+
+    rtems_interrupt_lock_acquire(&lock, level);
+
+    for (i = 0; i < n; ++i) {
+      vdata[i] = i;
+    }
+
+    rtems_cache_flush_multiple_data_lines(&data[0], data_size);
+
+    for (i = 0; i < n; ++i) {
+      rtems_test_assert(vdata[i] == i);
+    }
+
+    for (i = 0; i < n; ++i) {
+      vdata[i] = ~i;
+    }
+
+    rtems_cache_invalidate_multiple_data_lines(&data[0], data_size);
+
+    for (i = 0; i < n; ++i) {
+      rtems_test_assert(vdata[i] == i);
+    }
+
+    for (i = 0; i < n; ++i) {
+      vdata[i] = ~i;
+    }
+
+    rtems_cache_flush_multiple_data_lines(&data[0], data_size);
+    rtems_cache_invalidate_multiple_data_lines(&data[0], data_size);
+
+    for (i = 0; i < n; ++i) {
+      rtems_test_assert(vdata[i] == ~i);
+    }
+
+    rtems_interrupt_lock_release(&lock, level);
+
+    printf("data cache operations by line passed the test\n");
+  } else {
+    printf(
+      "skip data cache flush and invalidate test"
+        " due to cache line size of zero\n"
+    );
+  }
+}
+
+static uint64_t do_some_work(void)
+{
+  rtems_counter_ticks a;
+  rtems_counter_ticks b;
+  rtems_counter_ticks d;
+
+  /* This gives 1024 nop instructions */
+  a = rtems_counter_read();
+  I512();
+  I512();
+  b = rtems_counter_read();
+
+  d = rtems_counter_difference(b, a);
+
+  return rtems_counter_ticks_to_nanoseconds(d);
+}
+
+static uint64_t load(void)
+{
+  rtems_counter_ticks a;
+  rtems_counter_ticks b;
+  rtems_counter_ticks d;
+  size_t i;
+  volatile int *vdata = &data[0];
+
+  a = rtems_counter_read();
+  for (i = 0; i < RTEMS_ARRAY_SIZE(data); ++i) {
+    vdata[i];
+  }
+  b = rtems_counter_read();
+
+  d = rtems_counter_difference(b, a);
+
+  return rtems_counter_ticks_to_nanoseconds(d);
+}
+
+static uint64_t store(void)
+{
+  rtems_counter_ticks a;
+  rtems_counter_ticks b;
+  rtems_counter_ticks d;
+  size_t i;
+  volatile int *vdata = &data[0];
+
+  a = rtems_counter_read();
+  for (i = 0; i < RTEMS_ARRAY_SIZE(data); ++i) {
+    vdata[i] = 0;
+  }
+  b = rtems_counter_read();
+
+  d = rtems_counter_difference(b, a);
+
+  return rtems_counter_ticks_to_nanoseconds(d);
+}
+
+static void test_timing(void)
+{
+  rtems_interrupt_level level;
+  rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
+  size_t data_size = sizeof(data);
+  uint64_t d[3];
+
+  printf(
+    "data cache line size %i bytes\n",
+    rtems_cache_get_data_line_size()
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = load();
+  d[1] = load();
+  rtems_cache_flush_entire_data();
+  d[2] = load();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "load %zi bytes with flush entire data\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with flushed cache %" PRIu64 " ns\n",
+    data_size,
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = load();
+  d[1] = load();
+  rtems_cache_flush_multiple_data_lines(&data[0], sizeof(data));
+  d[2] = load();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "load %zi bytes with flush multiple data\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with flushed cache %" PRIu64 " ns\n",
+    data_size,
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = load();
+  d[1] = load();
+  rtems_cache_invalidate_multiple_data_lines(&data[0], sizeof(data));
+  d[2] = load();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "load %zi bytes with invalidate multiple data\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with invalidated cache %" PRIu64 " ns\n",
+    data_size,
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = store();
+  d[1] = store();
+  rtems_cache_flush_entire_data();
+  d[2] = store();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "store %zi bytes with flush entire data\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with flushed cache %" PRIu64 " ns\n",
+    data_size,
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = store();
+  d[1] = store();
+  rtems_cache_flush_multiple_data_lines(&data[0], sizeof(data));
+  d[2] = store();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "store %zi bytes with flush multiple data\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with flushed cache %" PRIu64 " ns\n",
+    data_size,
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = store();
+  d[1] = store();
+  rtems_cache_invalidate_multiple_data_lines(&data[0], sizeof(data));
+  d[2] = store();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "store %zi bytes with invalidate multiple data\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with invalidated cache %" PRIu64 " ns\n",
+    data_size,
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  printf(
+    "instruction cache line size %i bytes\n",
+    rtems_cache_get_instruction_line_size()
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = do_some_work();
+  d[1] = do_some_work();
+  rtems_cache_invalidate_entire_instruction();
+  d[2] = do_some_work();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "invalidate entire instruction\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with invalidated cache %" PRIu64 " ns\n",
+    d[0],
+    d[1],
+    d[2]
+  );
+
+  rtems_interrupt_lock_acquire(&lock, level);
+
+  d[0] = do_some_work();
+  d[1] = do_some_work();
+  rtems_cache_invalidate_multiple_instruction_lines(do_some_work, 4096);
+  d[2] = do_some_work();
+
+  rtems_interrupt_lock_release(&lock, level);
+
+  printf(
+    "invalidate multiple instruction\n"
+    "  duration with normal cache %" PRIu64 " ns\n"
+    "  duration with warm cache %" PRIu64 " ns\n"
+    "  duration with invalidated cache %" PRIu64 " ns\n",
+    d[0],
+    d[1],
+    d[2]
+  );
+}
+
+static void Init(rtems_task_argument arg)
+{
+  puts("\n\n*** TEST SPCACHE 1 ***");
+
+  test_data_flush_and_invalidate();
+  test_timing();
+
+  puts("*** END OF TEST SPCACHE 1 ***");
+
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/spcache01/spcache01.doc b/testsuites/sptests/spcache01/spcache01.doc
new file mode 100644
index 0000000..bbc8f25
--- /dev/null
+++ b/testsuites/sptests/spcache01/spcache01.doc
@@ -0,0 +1,19 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: spcache01
+
+The screen file was obtained on a PowerPC QorIQ P1020E target running with a
+processor frequency of 800MHz.
+
+directives:
+
+  - rtems_cache_flush_multiple_data_lines()
+  - rtems_cache_get_data_line_size()
+  - rtems_cache_get_instruction_line_size()
+  - rtems_cache_invalidate_entire_instruction()
+  - rtems_cache_invalidate_multiple_data_lines()
+  - rtems_cache_invalidate_multiple_instruction_lines()
+
+concepts:
+
+  - Ensure that some cache manager functions work.
diff --git a/testsuites/sptests/spcache01/spcache01.scn b/testsuites/sptests/spcache01/spcache01.scn
new file mode 100644
index 0000000..45ea3e5
--- /dev/null
+++ b/testsuites/sptests/spcache01/spcache01.scn
@@ -0,0 +1,38 @@
+*** TEST SPCACHE 1 ***
+data cache flush and invalidate test
+data cache operations by line passed the test
+data cache line size 32 bytes
+load 4096 bytes with flush entire data
+  duration with normal cache 12660 ns
+  duration with warm cache 2580 ns
+  duration with flushed cache 2580 ns
+load 4096 bytes with flush multiple data
+  duration with normal cache 2600 ns
+  duration with warm cache 2580 ns
+  duration with flushed cache 11400 ns
+load 4096 bytes with invalidate multiple data
+  duration with normal cache 2580 ns
+  duration with warm cache 2580 ns
+  duration with invalidated cache 11620 ns
+store 4096 bytes with flush entire data
+  duration with normal cache 2600 ns
+  duration with warm cache 2580 ns
+  duration with flushed cache 2580 ns
+store 4096 bytes with flush multiple data
+  duration with normal cache 2580 ns
+  duration with warm cache 2580 ns
+  duration with flushed cache 3000 ns
+store 4096 bytes with invalidate multiple data
+  duration with normal cache 2580 ns
+  duration with warm cache 2580 ns
+  duration with invalidated cache 2640 ns
+instruction cache line size 32 bytes
+invalidate entire instruction
+  duration with normal cache 5780 ns
+  duration with warm cache 640 ns
+  duration with invalidated cache 640 ns
+invalidate multiple instruction
+  duration with normal cache 680 ns
+  duration with warm cache 640 ns
+  duration with invalidated cache 2600 ns
+*** END OF TEST SPCACHE 1 ***




More information about the vc mailing list