forked from Imagelibrary/rtems
sptests/spcache01: New test
This commit is contained in:
@@ -30,6 +30,7 @@ SUBDIRS = \
|
|||||||
spsimplesched03 spnsext01 spedfsched01 spedfsched02 spedfsched03 \
|
spsimplesched03 spnsext01 spedfsched01 spedfsched02 spedfsched03 \
|
||||||
spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \
|
spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \
|
||||||
spregion_err01 sppartition_err01
|
spregion_err01 sppartition_err01
|
||||||
|
SUBDIRS += spcache01
|
||||||
SUBDIRS += sptls03
|
SUBDIRS += sptls03
|
||||||
SUBDIRS += spcpucounter01
|
SUBDIRS += spcpucounter01
|
||||||
if HAS_CPLUSPLUS
|
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
|
# Explicitly list all Makefiles here
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
|
spcache01/Makefile
|
||||||
sptls03/Makefile
|
sptls03/Makefile
|
||||||
spcpucounter01/Makefile
|
spcpucounter01/Makefile
|
||||||
sptls02/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