forked from Imagelibrary/rtems
sptests/spcache01: New test
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
19
testsuites/sptests/spcache01/Makefile.am
Normal file
19
testsuites/sptests/spcache01/Makefile.am
Normal file
@@ -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@.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
|
||||
348
testsuites/sptests/spcache01/init.c
Normal file
348
testsuites/sptests/spcache01/init.c
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@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>
|
||||
19
testsuites/sptests/spcache01/spcache01.doc
Normal file
19
testsuites/sptests/spcache01/spcache01.doc
Normal file
@@ -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.
|
||||
38
testsuites/sptests/spcache01/spcache01.scn
Normal file
38
testsuites/sptests/spcache01/spcache01.scn
Normal file
@@ -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 ***
|
||||
Reference in New Issue
Block a user