tricore: Add fpu init to open FZ trap.

Initialize the FPU and enable the FZ (flush-to-zero) trap for
TriCore TC4xx processors. This ensures floating-point divide-by-zero
exceptions are properly caught and reported via the trap handler.

Signed-off-by: zhangyuan29 <zhangyuan29@xiaomi.com>
This commit is contained in:
zhangyuan29 2026-05-20 20:06:29 +08:00 committed by Xiang Xiao
parent 980b7b1e27
commit 51ebb21474
9 changed files with 107 additions and 0 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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 <nuttx/config.h>
#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));
}

View file

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

View file

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

View file

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

View file

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