diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2018-01-23 12:50:56 +0100 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2020-09-02 10:53:07 +0200 |
commit | c451018877f3539d775ca0e1fee24ad896e66b68 (patch) | |
tree | 18705dcadd09ed9b8447952ddf8144b979ece178 | |
parent | c3ef58c1ade42a479d411e9e7389ce0a8db422c3 (diff) |
sparc: auto detect FPU present in HW or not
When kernel is built soft-float this patch allows to kernel to use
the HW/FPU for tasks enabling floating point context.
If FPU is not present the floating point task attribute will always
be zero, meaning that no floating point context is available.
With this patch the per-cpu and task structures will be of equal sizes
and field offsets regardless of soft/hard float compiliation settings.
As consequence compiling parts of the application with soft-float will
not crash looking up RTEMS task/per-cpu structures wrongly. However, it
is not recommended to link soft and hard float code togerther since
they are not ABI compliant when it comes to functions returning
floats/doubles (stored in %f0/%f1 FPU register).
-rw-r--r-- | bsps/sparc/shared/start/bsp_fpu_detection.c | 20 | ||||
-rw-r--r-- | bsps/sparc/shared/start/start.S | 13 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/erc32/Makefile.am | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/Makefile.am | 1 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/Makefile.am | 1 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/include/rtems/score/sparc.h | 21 | ||||
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 11 |
7 files changed, 65 insertions, 4 deletions
diff --git a/bsps/sparc/shared/start/bsp_fpu_detection.c b/bsps/sparc/shared/start/bsp_fpu_detection.c new file mode 100644 index 0000000000..f6130a2062 --- /dev/null +++ b/bsps/sparc/shared/start/bsp_fpu_detection.c @@ -0,0 +1,20 @@ +/** + * @file + * @ingroup sparc_bsp + * @brief ERC32/LEON2/LEON3 BSP FPU run-time detection. + */ + +/* + * COPYRIGHT (c) 2018. + * Cobham Gaisler AB. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <rtems/score/cpu.h> + +#ifdef SPARC_DYNAMIC_FPU_DETECTION +int sparc_fpu_present; +#endif diff --git a/bsps/sparc/shared/start/start.S b/bsps/sparc/shared/start/start.S index 5fc1248a24..a43e00e212 100644 --- a/bsps/sparc/shared/start/start.S +++ b/bsps/sparc/shared/start/start.S @@ -282,12 +282,20 @@ SYM(hard_reset): mov %g3, %wim or %g1, 0xf20, %g1 + sethi %hi(0x1000), %g6 + or %g1, %g6, %g1 ! enable FPU if present in HW wr %g1, %psr ! enable traps and disable ints nop nop nop +#if SPARC_DYNAMIC_FPU_DETECTION + mov %psr, %g7 + and %g7, %g6, %g7 + srl %g7, 12, %g7 ! save PSR.EF for later in g7 +#endif + sethi %hi(_Per_CPU_Information), %g6 ! get per-CPU control add %g6, %lo(_Per_CPU_Information), %g6 @@ -374,6 +382,11 @@ zerobss: bleu,a zerobss nop +#if SPARC_DYNAMIC_FPU_DETECTION + sethi %hi(sparc_fpu_present), %g3 ! Save FPU.EF in memory + st %g7, [%g3 + %lo(sparc_fpu_present)] +#endif + mov %g0, %o0 ! command line call SYM(boot_card) ! does not return sub %sp, 0x60, %sp ! room for boot_card to save args diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am index 8cdd4581bf..d6860c1842 100644 --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am @@ -34,6 +34,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/bspidle.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/bspdelay.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fatal_exit.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fatal_halt.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fpu_detection.c + # gnatsupp librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/gnatsupp/gnatsupp.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/gnatcommon.c diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am index 8ab87e5191..946a7d4664 100644 --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am @@ -34,6 +34,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/bspidle.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/bspdelay.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fatal_exit.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fatal_halt.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fpu_detection.c # gnatsupp librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/gnatsupp/gnatsupp.c diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am index 7933a48024..dae4873f55 100644 --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am @@ -38,6 +38,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/cpucounter.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fatal_exit.c librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/bsp_fatal_halt.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fpu_detection.c # gnatsupp librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/gnatsupp/gnatsupp.c diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparc.h b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h index 4846520b46..7821c0455f 100644 --- a/cpukit/score/cpu/sparc/include/rtems/score/sparc.h +++ b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h @@ -72,12 +72,23 @@ extern "C" { #define SPARC_LEON3FT_B2BST_NOP #endif +/* + * Compile the SPARC kernel with runtime FPU detection. This is used + * by RTEMS kernels built without FPU but still need to be able to + * run tasks with FPU enabled. This way the kernel is SPARC (v7/v8) + * with or without FPU compatible. + */ + +#define SPARC_DYNAMIC_FPU_DETECTION 1 + /** * This macro indicates whether this multilib variation has hardware * floating point or not. We use the gcc cpp predefine _SOFT_FLOAT * to determine that. */ -#if defined(_SOFT_FLOAT) +#if SPARC_DYNAMIC_FPU_DETECTION + #define SPARC_HAS_FPU 1 +#elif defined(_SOFT_FLOAT) #define SPARC_HAS_FPU 0 #else #define SPARC_HAS_FPU 1 @@ -87,7 +98,9 @@ extern "C" { * This macro contains a string describing the multilib variant being * build. */ -#if SPARC_HAS_FPU +#if SPARC_DYNAMIC_FPU_DETECTION + #define CPU_MODEL_NAME "w/FPU-detect" +#elif SPARC_HAS_FPU #define CPU_MODEL_NAME "w/FPU" #else #define CPU_MODEL_NAME "w/soft-float" @@ -245,6 +258,10 @@ uint32_t _SPARC_Get_TBR( void ); #endif /* RTEMS_PARAVIRT */ +#ifdef SPARC_DYNAMIC_FPU_DETECTION +extern int sparc_fpu_present; +#endif + /** * @brief Macro to set the TBR. * diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 691f56388e..3f4565e095 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -44,6 +44,13 @@ bool _Thread_Initialize( #endif size_t scheduler_index; Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 ); + bool is_fp = config->is_fp; + +#if SPARC_DYNAMIC_FPU_DETECTION + /* Always disable FPU context on systems without FPU in HW */ + if (sparc_fpu_present == 0) + is_fp = 0; +#endif memset( &the_thread->Join_queue, @@ -87,7 +94,7 @@ bool _Thread_Initialize( /* Allocate floating-point context in stack area */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) - if ( config->is_fp ) { + if ( is_fp ) { the_thread->fp_context = ( Context_Control_fp *) stack_area; the_thread->Start.fp_context = ( Context_Control_fp *) stack_area; stack_size -= CONTEXT_FP_SIZE; @@ -126,7 +133,7 @@ bool _Thread_Initialize( * General initialization */ - the_thread->is_fp = config->is_fp; + the_thread->is_fp = is_fp; the_thread->Start.isr_level = config->isr_level; the_thread->Start.is_preemptible = config->is_preemptible; the_thread->Start.budget_algorithm = config->budget_algorithm; |