test_fp_sharing: Enable for Cortex-M4
Update the FP sharing test project for use with the Cortex-M4. Change-Id: If04a191b26291058bd7002ce8a0939eda8a5eb48 Signed-off-by: Peter Mitsis <peter.mitsis@windriver.com>
This commit is contained in:
parent
3490627a97
commit
b4eee20e4b
|
@ -1,6 +1,6 @@
|
|||
MDEF_FILE = prj.mdef
|
||||
KERNEL_TYPE = micro
|
||||
BOARD ?= qemu_x86
|
||||
CONF_FILE = prj.conf
|
||||
CONF_FILE = prj_$(ARCH).conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.inc
|
||||
|
|
|
@ -35,6 +35,18 @@ or
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Advanced:
|
||||
|
||||
Depending upon the board's speed, the frequency of test output may range from
|
||||
every few seconds to every few minutes. The speed of the test can be controlled
|
||||
through the variable PI_NUM_ITERATIONS (default 700000). Lowering this value
|
||||
will increase the test's speed, but at the expense of the calculation's
|
||||
precision.
|
||||
|
||||
make qemu PI_NUM_ITERATIONS=100000
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Sample Output:
|
||||
|
||||
Floating point sharing tests started
|
||||
|
|
9
tests/kernel/test_fp_sharing/microkernel/prj_arm.conf
Normal file
9
tests/kernel/test_fp_sharing/microkernel/prj_arm.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
CONFIG_FLOAT=y
|
||||
CONFIG_FP_SHARING=y
|
||||
|
||||
CONFIG_STDOUT_CONSOLE=y
|
||||
|
||||
# Let stack canaries use non-random number generator.
|
||||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
|
@ -2,3 +2,11 @@ ccflags-y += -I${ZEPHYR_BASE}/tests/include
|
|||
|
||||
obj-y += main.o
|
||||
obj-$(CONFIG_MICROKERNEL) += pi.o
|
||||
|
||||
# Some boards are significantly slower than others resulting in the test
|
||||
# output being in the range of every few seconds to every few minutes. To
|
||||
# compensate for this, one can control the number of iterations in the PI
|
||||
# calculation through PI_NUM_ITERATIONS. Lowering this value will increase
|
||||
# the speed of the test but it will come at the expense of precision.
|
||||
PI_NUM_ITERATIONS ?= 700000
|
||||
ccflags-y += "-DPI_NUM_ITERATIONS=${PI_NUM_ITERATIONS}"
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
* _load_all_float_registers()
|
||||
* _load_then_store_all_float_registers()
|
||||
* _store_all_float_registers()
|
||||
* _store_non_volatile_float_registers()
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ISA_IA32)
|
||||
|
@ -74,7 +73,32 @@ struct fp_non_volatile_register_set {
|
|||
#define SIZEOF_FP_VOLATILE_REGISTER_SET sizeof(struct fp_volatile_register_set)
|
||||
#define SIZEOF_FP_NON_VOLATILE_REGISTER_SET 0
|
||||
|
||||
#else /* ! CONFIG_ISA_IA32 */
|
||||
#elif defined(CONFIG_CPU_CORTEX_M4)
|
||||
|
||||
#define FP_OPTION 0
|
||||
|
||||
/*
|
||||
* Registers s0..s15 are volatile and do not
|
||||
* need to be preserved across function calls.
|
||||
*/
|
||||
struct fp_volatile_register_set {
|
||||
float s[16];
|
||||
};
|
||||
|
||||
/*
|
||||
* Registers s16..s31 are non-volatile and
|
||||
* need to be preserved across function calls.
|
||||
*/
|
||||
struct fp_non_volatile_register_set {
|
||||
float s[16];
|
||||
};
|
||||
|
||||
#define SIZEOF_FP_VOLATILE_REGISTER_SET \
|
||||
sizeof(struct fp_volatile_register_set)
|
||||
#define SIZEOF_FP_NON_VOLATILE_REGISTER_SET \
|
||||
sizeof(struct fp_non_volatile_register_set)
|
||||
|
||||
#else
|
||||
|
||||
#error "Architecture must provide the following definitions:\n" \
|
||||
"\t'struct fp_volatile_registers'\n" \
|
||||
|
@ -101,8 +125,6 @@ struct fp_register_set {
|
|||
#define MAIN_FLOAT_REG_CHECK_BYTE (unsigned char)0xe5
|
||||
#define FIBER_FLOAT_REG_CHECK_BYTE (unsigned char)0xf9
|
||||
|
||||
void _store_non_volatile_float_registers(struct fp_non_volatile_register_set *regs);
|
||||
|
||||
extern int fpu_sharing_error;
|
||||
|
||||
#endif /* _FLOATCONTEXT_H */
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file
|
||||
* @brief ARM Cortex-M4 GCC specific floating point register macros
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _FLOAT_REGS_ARM_GCC_H
|
||||
#define _FLOAT_REGS_ARM_GCC_H
|
||||
|
||||
#if !defined(__GNUC__) || !defined(CONFIG_CPU_CORTEX_M4)
|
||||
#error __FILE__ goes only with Cortex-M4 GCC
|
||||
#endif
|
||||
|
||||
#include <toolchain.h>
|
||||
#include "float_context.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Load all floating point registers
|
||||
*
|
||||
* This function loads ALL floating point registers pointed to by @a regs.
|
||||
* It is expected that a subsequent call to _store_all_float_registers()
|
||||
* will be issued to dump the floating point registers to memory.
|
||||
*
|
||||
* The format/organization of 'struct fp_register_set'; the generic C test
|
||||
* code (main.c) merely treat the register set as an array of bytes.
|
||||
*
|
||||
* The only requirement is that the arch specific implementations of
|
||||
* _load_all_float_registers() and _store_all_float_registers() agree
|
||||
* on the format.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static inline void _load_all_float_registers(struct fp_register_set *regs)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"vldmia %0, {s0-s15};\n\t"
|
||||
"vldmia %1, {s16-s31};\n\t"
|
||||
:: "r" (®s->fp_volatile), "r" (®s->fp_non_volatile)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Dump all floating point registers to memory
|
||||
*
|
||||
* This function stores ALL floating point registers to the memory buffer
|
||||
* specified by @a regs. It is expected that a previous invocation of
|
||||
* _load_all_float_registers() occurred to load all the floating point
|
||||
* registers from a memory buffer.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static inline void _store_all_float_registers(struct fp_register_set *regs)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"vstmia %0, {s0-s15};\n\t"
|
||||
"vstmia %1, {s16-s31};\n\t"
|
||||
:: "r" (®s->fp_volatile), "r" (®s->fp_non_volatile)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Load then dump all float registers to memory
|
||||
*
|
||||
* This function loads ALL floating point registers from the memory buffer
|
||||
* specified by @a regs, and then stores them back to that buffer.
|
||||
*
|
||||
* This routine is called by a high priority thread prior to calling a primitive
|
||||
* that pends and triggers a co-operative context switch to a low priority
|
||||
* thread.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static inline void _load_then_store_all_float_registers(struct fp_register_set *regs)
|
||||
{
|
||||
_load_all_float_registers(regs);
|
||||
_store_all_float_registers(regs);
|
||||
}
|
||||
#endif /* _FLOAT_REGS_ARM_GCC_H */
|
|
@ -57,11 +57,19 @@ x87 FPU registers are being saved/restored.
|
|||
|
||||
#include <zephyr.h>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <float_regs_x86_gcc.h>
|
||||
#else
|
||||
#include <float_regs_x86_other.h>
|
||||
#endif /* __GNUC__ */
|
||||
#if defined(CONFIG_ISA_IA32)
|
||||
#if defined(__GNUC__)
|
||||
#include <float_regs_x86_gcc.h>
|
||||
#else
|
||||
#include <float_regs_x86_other.h>
|
||||
#endif /* __GNUC__ */
|
||||
#elif defined(CONFIG_CPU_CORTEX_M4)
|
||||
#if defined(__GNUC__)
|
||||
#include <float_regs_arm_gcc.h>
|
||||
#else
|
||||
#include <float_regs_arm_other.h>
|
||||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <tc_util.h>
|
||||
|
@ -244,6 +252,7 @@ void load_store_low(void)
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ISA_IA32)
|
||||
/*
|
||||
* After every 1000 iterations (arbitrarily chosen), explicitly
|
||||
* disable floating point operations for the task. The
|
||||
|
@ -258,6 +267,15 @@ void load_store_low(void)
|
|||
if ((load_store_low_count % 1000) == 0) {
|
||||
task_float_disable(sys_thread_self_get());
|
||||
}
|
||||
#elif defined(CONFIG_CPU_CORTEX_M4)
|
||||
/*
|
||||
* The routine task_float_disable() allows for thread-level
|
||||
* granularity for disabling floating point. Furthermore, it
|
||||
* is useful for testing on the fly thread enabling of floating
|
||||
* point. Neither of these capabilities are currently supported
|
||||
* for ARM.
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,7 +330,6 @@ void load_store_high(void)
|
|||
reg_set_ptr[i] = init_byte++;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ISA_IA32)
|
||||
/*
|
||||
* Utilize an architecture specific function to load all the
|
||||
* floating point registers with the contents of the
|
||||
|
@ -333,7 +350,6 @@ void load_store_high(void)
|
|||
*/
|
||||
|
||||
_load_then_store_all_float_registers(&float_reg_set);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Relinquish the processor for the remainder of the current
|
||||
|
|
|
@ -45,7 +45,10 @@ has occurred.
|
|||
|
||||
#include <float_context.h>
|
||||
|
||||
#define PI_NUM_ITERATIONS 700000
|
||||
/*
|
||||
* PI_NUM_ITERATIONS: This macro is defined in the project's Makefile and
|
||||
* is configurable from the command line.
|
||||
*/
|
||||
|
||||
static double reference_pi = 0.0f;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[test]
|
||||
[test_x86]
|
||||
tags = core
|
||||
platform_whitelist = qemu_x86
|
||||
slow = true
|
||||
|
@ -6,3 +6,10 @@ slow = true
|
|||
# under normal circumstances. On a heavily loaded machine, extra time
|
||||
# may be required--hence the 10 minute timeout.
|
||||
timeout = 600
|
||||
|
||||
[test_arm]
|
||||
tags = core
|
||||
platform_whitelist = frdm_k64f
|
||||
slow = true
|
||||
extra_args = PI_NUM_ITERATIONS=70000
|
||||
timeout = 600
|
||||
|
|
9
tests/kernel/test_fp_sharing/nanokernel/prj_arm.conf
Normal file
9
tests/kernel/test_fp_sharing/nanokernel/prj_arm.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
CONFIG_FLOAT=y
|
||||
CONFIG_FP_SHARING=y
|
||||
|
||||
CONFIG_STDOUT_CONSOLE=y
|
||||
|
||||
# Let stack canaries use non-random number generator.
|
||||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
|
@ -1,3 +1,7 @@
|
|||
[test]
|
||||
[test_x86]
|
||||
tags = core
|
||||
platform_whitelist = qemu_x86
|
||||
|
||||
[test_arm]
|
||||
tags = core
|
||||
platform_whitelist = frdm_k64f
|
||||
|
|
Loading…
Reference in a new issue