This is an automated email from the ASF dual-hosted git repository.
lupyuen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new f401467a94e arch/tricore: add TriCore up_backtrace() support
f401467a94e is described below
commit f401467a94e81332506fa9c3e1a3f53d2facbfb8
Author: donghaokun <[email protected]>
AuthorDate: Tue May 19 11:14:26 2026 +0800
arch/tricore: add TriCore up_backtrace() support
Implement up_backtrace() for TriCore by walking the CSA chain and
collecting return addresses from upper CSA A11 register.
Signed-off-by: LukeKun <[email protected]>
---
arch/Kconfig | 1 +
arch/tricore/src/common/CMakeLists.txt | 1 +
arch/tricore/src/common/Make.defs | 1 +
arch/tricore/src/common/tricore_backtrace.c | 132 ++++++++++++++++++++++++++++
4 files changed, 135 insertions(+)
diff --git a/arch/Kconfig b/arch/Kconfig
index 8f3e23dd9c0..7cd6ec4f10d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -197,6 +197,7 @@ config ARCH_SPARC
config ARCH_TRICORE
bool "Infineon TriCore"
+ select ARCH_HAVE_BACKTRACE
select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_SYSCALL_HOOKS
diff --git a/arch/tricore/src/common/CMakeLists.txt
b/arch/tricore/src/common/CMakeLists.txt
index 6832abebe62..19bcfe4f7eb 100644
--- a/arch/tricore/src/common/CMakeLists.txt
+++ b/arch/tricore/src/common/CMakeLists.txt
@@ -22,6 +22,7 @@
set(SRCS
tricore_allocateheap.c
+ tricore_backtrace.c
tricore_cache.c
tricore_checkstack.c
tricore_createstack.c
diff --git a/arch/tricore/src/common/Make.defs
b/arch/tricore/src/common/Make.defs
index ccff2af627d..4817dc830c0 100644
--- a/arch/tricore/src/common/Make.defs
+++ b/arch/tricore/src/common/Make.defs
@@ -23,6 +23,7 @@
HEAD_CSRC += tricore_doirq.c
CMN_CSRCS += tricore_allocateheap.c
+CMN_CSRCS += tricore_backtrace.c
CMN_CSRCS += tricore_cache.c
CMN_CSRCS += tricore_checkstack.c
CMN_CSRCS += tricore_createstack.c
diff --git a/arch/tricore/src/common/tricore_backtrace.c
b/arch/tricore/src/common/tricore_backtrace.c
new file mode 100644
index 00000000000..11679ca74e8
--- /dev/null
+++ b/arch/tricore/src/common/tricore_backtrace.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * arch/tricore/src/common/tricore_backtrace.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 <nuttx/arch.h>
+#include "sched/sched.h"
+#include "tricore_internal.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: backtrace
+ *
+ * Description:
+ * backtrace() parsing the return address through A11 register
+ *
+ ****************************************************************************/
+
+nosanitize_address
+static int backtrace(uintptr_t pcxi, void **buffer, int size, int *skip)
+{
+ int i = 0;
+
+ for (; ((pcxi & FCX_FREE) != 0U) && (i < size); )
+ {
+ uintptr_t *csa;
+
+ csa = tricore_csa2addr(pcxi);
+ if (csa == NULL)
+ {
+ break;
+ }
+
+ if ((pcxi & PCXI_UL) != 0U)
+ {
+ if ((*skip)-- <= 0)
+ {
+ buffer[i++] = (void *)csa[REG_UA11];
+ }
+ }
+
+ pcxi = csa[0];
+ }
+
+ return i;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace
+ *
+ * Description:
+ * up_backtrace() returns a backtrace for the TCB, in the array
+ * pointed to by buffer. A backtrace is the series of currently active
+ * function calls for the program. Each item in the array pointed to by
+ * buffer is of type void *, and is the return address from the
+ * corresponding stack frame. The size argument specifies the maximum
+ * number of addresses that can be stored in buffer. If the backtrace is
+ * larger than size, then the addresses corresponding to the size most
+ * recent function calls are returned; to obtain the complete backtrace,
+ * make sure that buffer and size are large enough.
+ *
+ * Input Parameters:
+ * tcb - Address of the task's TCB
+ * buffer - Return address from the corresponding stack frame
+ * size - Maximum number of addresses that can be stored in buffer
+ * skip - number of addresses to be skipped
+ *
+ * Returned Value:
+ * up_backtrace() returns the number of addresses returned in buffer
+ *
+ * Assumptions:
+ * Have to make sure tcb keep safe during function executing, it means
+ * 1. Tcb have to be self or not-running. In SMP case, the running task
+ * PC & SP cannot be backtrace, as whose get from tcb is not the newest.
+ * 2. Tcb have to keep not be freed. In task exiting case, have to
+ * make sure the tcb get from pid and up_backtrace in one critical
+ * section procedure.
+ *
+ ****************************************************************************/
+
+int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
+{
+ struct tcb_s *rtcb = running_task();
+ int ret;
+
+ if (size <= 0 || !buffer)
+ {
+ return 0;
+ }
+
+ if (tcb == NULL || tcb == rtcb)
+ {
+ ret = backtrace((uintptr_t)__mfcr(CPU_PCXI),
+ buffer, size, &skip);
+ }
+ else
+ {
+ ret = backtrace(tricore_addr2csa(tcb->xcp.regs),
+ buffer, size, &skip);
+ }
+
+ return ret;
+}