diff --git a/arch/tricore/Kconfig b/arch/tricore/Kconfig index d80cef7bbbf..3db57114fdf 100644 --- a/arch/tricore/Kconfig +++ b/arch/tricore/Kconfig @@ -70,6 +70,7 @@ config ARCH_CHIP_TC4XX bool select ARCH_TC1V8 select ARCH_HAVE_ADDRENV + select ARCH_HAVE_FPU if !TRICORE_CSRM select ARCH_HAVE_I2CRESET select ARCH_MINIMAL_VECTORTABLE select ARCH_MINIMAL_VECTORTABLE_DYNAMIC diff --git a/arch/tricore/include/irq.h b/arch/tricore/include/irq.h index 90f7d15ece3..f4109c6f5bd 100644 --- a/arch/tricore/include/irq.h +++ b/arch/tricore/include/irq.h @@ -144,6 +144,18 @@ #define STACKFRAME_ALIGN 8 +/* FPU registers */ + +#ifdef CONFIG_ARCH_TC1V6 +# define FPU_SYNC_TRAP_REG CPU_FPU_TRAP_CON +# define FPU_ASYNC_TRAP_REG CPU_FPU_TRAP_CON +#else +# define FPU_SYNC_TRAP_REG CPU_FPU_SYNC_TRAP_CON +# define FPU_ASYNC_TRAP_REG CPU_FPU_TRAP_CON +#endif +#define FPU_TRAP_FZE_SHIFT 20 +#define FPU_TRAP_TCL_SHIFT 1 + #ifndef __ASSEMBLY__ #ifdef __cplusplus diff --git a/arch/tricore/src/common/CMakeLists.txt b/arch/tricore/src/common/CMakeLists.txt index 68a7c3553e1..6072eda56a4 100644 --- a/arch/tricore/src/common/CMakeLists.txt +++ b/arch/tricore/src/common/CMakeLists.txt @@ -58,6 +58,10 @@ if(CONFIG_ARCH_USE_MPU) list(APPEND SRCS tricore_mpu.c) endif() +if(CONFIG_ARCH_HAVE_FPU) + list(APPEND SRCS tricore_fpu.c) +endif() + set(IFXFLAGS -DIFX_CFG_EXTEND_TRAP_HOOKS -DIFX_USE_SW_MANAGED_INT) target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/tricore/src/common/Make.defs b/arch/tricore/src/common/Make.defs index 2a02e7d736a..8707019f8cf 100644 --- a/arch/tricore/src/common/Make.defs +++ b/arch/tricore/src/common/Make.defs @@ -59,5 +59,9 @@ ifeq ($(CONFIG_ARCH_USE_MPU),y) CMN_CSRCS += tricore_mpu.c endif +ifeq ($(CONFIG_ARCH_HAVE_FPU),y) + CMN_CSRCS += tricore_fpu.c +endif + CFLAGS += -DIFX_CFG_EXTEND_TRAP_HOOKS CFLAGS += -DIFX_USE_SW_MANAGED_INT diff --git a/arch/tricore/src/common/tricore_fpu.c b/arch/tricore/src/common/tricore_fpu.c new file mode 100644 index 00000000000..6a28a6eaf91 --- /dev/null +++ b/arch/tricore/src/common/tricore_fpu.c @@ -0,0 +1,45 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_fpu.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_fpuinit + ****************************************************************************/ + +void tricore_fpuinit(void) +{ + /* FPU zero-divide trap enable */ + + __mtcr(FPU_SYNC_TRAP_REG, + __mfcr(FPU_SYNC_TRAP_REG) | (1U << FPU_TRAP_FZE_SHIFT)); +} diff --git a/arch/tricore/src/common/tricore_internal.h b/arch/tricore/src/common/tricore_internal.h index 71218d6c2fe..8c583d2ad0f 100644 --- a/arch/tricore/src/common/tricore_internal.h +++ b/arch/tricore/src/common/tricore_internal.h @@ -206,6 +206,12 @@ void tricore_serialinit(void); void tricore_earlyserialinit(void); #endif +/* FPU **********************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_FPU +void tricore_fpuinit(void); +#endif + /* System Timer *************************************************************/ struct oneshot_lowerhalf_s * diff --git a/arch/tricore/src/common/tricore_main.c b/arch/tricore/src/common/tricore_main.c index ed0d1d1bcc6..a297fd84383 100644 --- a/arch/tricore/src/common/tricore_main.c +++ b/arch/tricore/src/common/tricore_main.c @@ -44,6 +44,10 @@ static void core_main(void) { static IfxCpu_syncEvent g_sync_event = 0; +#ifdef CONFIG_ARCH_HAVE_FPU + tricore_fpuinit(); +#endif + /* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!! * Enable the watchdogs and service them periodically if it is required */ diff --git a/arch/tricore/src/common/tricore_trapcall.c b/arch/tricore/src/common/tricore_trapcall.c index 8afedb23fb1..673819e2bf1 100644 --- a/arch/tricore/src/common/tricore_trapcall.c +++ b/arch/tricore/src/common/tricore_trapcall.c @@ -179,6 +179,20 @@ int tricore_insterrorstrap(uint32_t tid, void *context, void *arg) _alert("\tInvalid Local Memory Address\n"); } +#ifdef CONFIG_ARCH_TC1V8 + if (tid == + IfxCpu_Trap_InstructionErrors_Id_CoprocessorTrapSynchronousError) + { + _alert("\tCoprocessor Trap Synchronous Error\n"); +# ifdef CONFIG_ARCH_HAVE_FPU + _alert("\tFPU_SYNC_TRAP:%" PRIX32 "\n\n", + (uint32_t)__mfcr(FPU_SYNC_TRAP_REG)); + __mtcr(FPU_SYNC_TRAP_REG, + __mfcr(FPU_SYNC_TRAP_REG) | (1U << FPU_TRAP_TCL_SHIFT)); +# endif + } +#endif + up_irq_save(); PANIC_WITH_REGS("panic", context); return OK; @@ -256,6 +270,12 @@ int tricore_bustrap(uint32_t tid, void *context, void *arg) if (tid == IfxCpu_Trap_Bus_Id_CoprocessorTrapAsynchronousError) { _alert("\tCoprocessor Trap Asynchronous Error\n"); +#ifdef CONFIG_ARCH_HAVE_FPU + _alert("\tFPU_ASYNC_TRAP:%" PRIX32 "\n\n", + (uint32_t)__mfcr(FPU_ASYNC_TRAP_REG)); + __mtcr(FPU_ASYNC_TRAP_REG, + __mfcr(FPU_ASYNC_TRAP_REG) | (1U << FPU_TRAP_TCL_SHIFT)); +#endif } if (tid == IfxCpu_Trap_Bus_Id_programMemoryIntegrityError) diff --git a/arch/tricore/src/illd/tc4xx/patches/add_coprocessor_trap_id.patch b/arch/tricore/src/illd/tc4xx/patches/add_coprocessor_trap_id.patch new file mode 100644 index 00000000000..4fcf2f103df --- /dev/null +++ b/arch/tricore/src/illd/tc4xx/patches/add_coprocessor_trap_id.patch @@ -0,0 +1,11 @@ +diff --git a/arch/tricore/src/illd/tc4xx/Libraries/src/Libraries/iLLD/TC4xx/Tricore/Cpu/Trap/IfxCpu_Trap.h b/arch/tricore/src/illd/tc4xx/Libraries/src/Libraries/iLLD/TC4xx/Tricore/Cpu/Trap/IfxCpu_Trap.h +--- a/arch/tricore/src/illd/tc4xx/Libraries/src/Libraries/iLLD/TC4xx/Tricore/Cpu/Trap/IfxCpu_Trap.h ++++ b/arch/tricore/src/illd/tc4xx/Libraries/src/Libraries/iLLD/TC4xx/Tricore/Cpu/Trap/IfxCpu_Trap.h +@@ -99,6 +99,7 @@ + IfxCpu_Trap_InstructionErrors_Id_invalidOperand = 3U, + IfxCpu_Trap_InstructionErrors_Id_dataAddressAlignment = 4U, + IfxCpu_Trap_InstructionErrors_Id_invalidMemoryAddress = 5U, ++ IfxCpu_Trap_InstructionErrors_Id_CoprocessorTrapSynchronousError = 6U, + } IfxCpu_Trap_InstructionErrors_Id; + + /** \brief Enum for available Identification numbers under Context Management Trap.