sptests/spcache01: New test

This commit is contained in:
Sebastian Huber
2014-02-17 08:16:54 +01:00
parent a4bc90af4e
commit 3378be955a
6 changed files with 426 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View 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

View 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>

View 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.

View 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 ***