diff --git a/arch/Kconfig b/arch/Kconfig index ecab9fa69c..b953b5f302 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -174,6 +174,15 @@ config ARCH_SPARC ---help--- SPARC architectures (SPARC V8) +config ARCH_TRICORE + bool "Infineon TriCore" + select ARCH_HAVE_INTERRUPTSTACK + select ARCH_HAVE_STACKCHECK + select ARCH_HAVE_CUSTOMOPT + select ARCH_HAVE_TCBINFO + ---help--- + Infineon 32-bit AURIX TriCore architectures + endchoice config ARCH @@ -194,6 +203,7 @@ config ARCH default "z80" if ARCH_Z80 default "or1k" if ARCH_OR1K default "sparc" if ARCH_SPARC + default "tricore" if ARCH_TRICORE source "arch/arm/Kconfig" source "arch/arm64/Kconfig" @@ -211,6 +221,7 @@ source "arch/z16/Kconfig" source "arch/z80/Kconfig" source "arch/or1k/Kconfig" source "arch/sparc/Kconfig" +source "arch/tricore/Kconfig" config ARCH_CHIP_CUSTOM bool "Custom Chip Support" diff --git a/arch/tricore/Kconfig b/arch/tricore/Kconfig new file mode 100644 index 0000000000..4926bb84b4 --- /dev/null +++ b/arch/tricore/Kconfig @@ -0,0 +1,42 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_TRICORE +comment "Tricore Options" + +choice + prompt "Tricore Toolchain Selection" + default TRICORE_TOOLCHAIN_TASKING + +config TRICORE_TOOLCHAIN_TASKING + bool "AURIX Tasking C/C++ toolchain" + select ARCH_TOOLCHAIN_TASKING + +endchoice # Tricore Toolchain Selection + +config ARCH_TC3XX + bool + default n + +config ARCH_FAMILY + string + default "tc3xx" if ARCH_TC3XX + +config ARCH_CHIP + string + default "tc3xx" if ARCH_CHIP_TC397 + +config ARCH_CHIP_TC397 + bool "AURIX Family TC397" + select ARCH_TC3XX + select ALARM_ARCH + select ONESHOT + ---help--- + AURIX TC39x family: TC397 + +if ARCH_TC3XX +source "arch/tricore/src/tc3xx/Kconfig" +endif +endif # ARCH_TRICORE diff --git a/arch/tricore/include/.gitignore b/arch/tricore/include/.gitignore new file mode 100644 index 0000000000..af8911db06 --- /dev/null +++ b/arch/tricore/include/.gitignore @@ -0,0 +1,2 @@ +/board +/chip diff --git a/arch/tricore/include/arch.h b/arch/tricore/include/arch.h new file mode 100644 index 0000000000..f44a3976d1 --- /dev/null +++ b/arch/tricore/include/arch.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/tricore/include/arch.h + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_TRICORE_INCLUDE_ARCH_H +#define __ARCH_TRICORE_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_TRICORE_INCLUDE_ARCH_H */ diff --git a/arch/tricore/include/inttypes.h b/arch/tricore/include/inttypes.h new file mode 100644 index 0000000000..dc15bff5b6 --- /dev/null +++ b/arch/tricore/include/inttypes.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/tricore/include/inttypes.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_TRICORE_INCLUDE_INTTYPES_H +#define __ARCH_TRICORE_INCLUDE_INTTYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define INT32_C(x) x ## l +#define INT64_C(x) x ## ll +#define UINT32_C(x) x ## ul +#define UINT64_C(x) x ## ull + +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "ld" +#define PRId64 "lld" + +#define PRIdPTR "d" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "li" +#define PRIi64 "lli" + +#define PRIiPTR "i" + +#define PRIo8 "o" +#define PRIo16 "o" +#define PRIo32 "lo" +#define PRIo64 "llo" + +#define PRIoPTR "o" + +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "lu" +#define PRIu64 "llu" + +#define PRIuPTR "u" + +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "lx" +#define PRIx64 "llx" + +#define PRIxPTR "x" + +#define PRIX8 "X" +#define PRIX16 "X" +#define PRIX32 "lX" +#define PRIX64 "llX" + +#define PRIXPTR "X" + +#define SCNd8 "hhd" +#define SCNd16 "hd" +#define SCNd32 "ld" +#define SCNd64 "lld" + +#define SCNdPTR "d" + +#define SCNi8 "hhi" +#define SCNi16 "hi" +#define SCNi32 "li" +#define SCNi64 "lli" + +#define SCNiPTR "i" + +#define SCNo8 "hho" +#define SCNo16 "ho" +#define SCNo32 "lo" +#define SCNo64 "llo" + +#define SCNoPTR "o" + +#define SCNu8 "hhu" +#define SCNu16 "hu" +#define SCNu32 "lu" +#define SCNu64 "llu" + +#define SCNuPTR "u" + +#define SCNx8 "hhx" +#define SCNx16 "hx" +#define SCNx32 "lx" +#define SCNx64 "llx" + +#define SCNxPTR "x" + +#define INT8_C(x) x +#define INT16_C(x) x + +#define UINT8_C(x) x +#define UINT16_C(x) x + +#endif /* __ARCH_TRICORE_INCLUDE_INTTYPES_H */ diff --git a/arch/tricore/include/irq.h b/arch/tricore/include/irq.h new file mode 100644 index 0000000000..8e2f20f658 --- /dev/null +++ b/arch/tricore/include/irq.h @@ -0,0 +1,178 @@ +/**************************************************************************** + * arch/tricore/include/irq.h + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_TRICORE_INCLUDE_IRQ_H +#define __ARCH_TRICORE_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/* Include NuttX-specific IRQ definitions */ + +#include + +/* Include chip-specific IRQ definitions (including IRQ numbers) */ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +/* For the case of architectures with multiple CPUs, then there must be one + * such value for each processor that can receive an interrupt. + */ + +EXTERN volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; +#define CURRENT_REGS (g_current_regs[up_cpu_index()]) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_index + * + * Description: + * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + * Input Parameters: + * None + * + * Returned Value: + * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int up_cpu_index(void) noinstrument_function; +#else +# define up_cpu_index() (0) +#endif + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Enable interrupts globally. + * + ****************************************************************************/ + +void up_irq_enable(void); + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +noinstrument_function static inline uintptr_t up_getsp(void) +{ + return (uintptr_t)__get_sp(); +} + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Disable interrupts and return the previous value of the mstatus register + * + ****************************************************************************/ + +noinstrument_function static inline irqstate_t up_irq_save(void) +{ + return __disable_and_save(); +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore the value of the mstatus register + * + ****************************************************************************/ + +noinstrument_function static inline void up_irq_restore(irqstate_t flags) +{ + __restore(flags); +} + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: + * Return true is we are currently executing in the interrupt + * handler context. + * + ****************************************************************************/ + +noinstrument_function +static inline bool up_interrupt_context(void) +{ +#ifdef CONFIG_SMP + irqstate_t flags = up_irq_save(); +#endif + + bool ret = CURRENT_REGS != NULL; + +#ifdef CONFIG_SMP + up_irq_restore(flags); +#endif + + return ret; +} +#endif /* __ASSEMBLY__ */ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_TRICORE_INCLUDE_IRQ_H */ diff --git a/arch/tricore/include/limits.h b/arch/tricore/include/limits.h new file mode 100644 index 0000000000..3a68941f7f --- /dev/null +++ b/arch/tricore/include/limits.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/tricore/include/limits.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_TRICORE_INCLUDE_LIMITS_H +#define __ARCH_TRICORE_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +# define CHAR_MIN 0 +# define CHAR_MAX UCHAR_MAX +#else +# define CHAR_MIN SCHAR_MIN +# define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +# define LONG_MIN (-LONG_MAX - 1) +# define LONG_MAX 2147483647L +# define ULONG_MAX 4294967295UL + +# define LLONG_MIN (-LLONG_MAX - 1) +# define LLONG_MAX 9223372036854775807LL +# define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 bytes */ + +# define PTR_MIN (-PTR_MAX - 1) +# define PTR_MAX 2147483647 +# define UPTR_MAX 4294967295U + +#if !defined(__WCHAR_TYPE__) +# define WCHAR_MIN INT_MIN +# define WCHAR_MAX INT_MAX +#elif defined(__WCHAR_UNSIGNED__) +# define WCHAR_MIN 0 +# define WCHAR_MAX __WCHAR_MAX__ +#else +# define WCHAR_MIN (-__WCHAR_MAX__ - 1) +# define WCHAR_MAX __WCHAR_MAX__ +#endif + +#endif /* __ARCH_TRICORE_INCLUDE_LIMITS_H */ diff --git a/arch/tricore/include/syscall.h b/arch/tricore/include/syscall.h new file mode 100644 index 0000000000..5b1e9eccb4 --- /dev/null +++ b/arch/tricore/include/syscall.h @@ -0,0 +1,350 @@ +/**************************************************************************** + * arch/tricore/include/syscall.h + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_TRICORE_INCLUDE_SYSCALL_H +#define __ARCH_TRICORE_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +#define SYS_syscall 0x00 + +/* Configuration ************************************************************/ + +/* This logic uses three system calls {0,1,2} for context switching and one + * for the syscall return. + * So a minimum of four syscall values must be reserved. + * If CONFIG_BUILD_FLAT isn't defined, then four more syscall values must + * be reserved. + */ + +#ifndef CONFIG_BUILD_FLAT +# define CONFIG_SYS_RESERVED 8 +#else +# define CONFIG_SYS_RESERVED 4 +#endif + +/* Cortex-M system calls ****************************************************/ + +/* SYS call 1: + * + * void tricore_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_restore_context (1) + +/* SYS call 2: + * + * void tricore_switchcontext(uint32_t **saveregs, uint32_t *restoreregs); + */ + +#define SYS_switch_context (2) + +#ifdef CONFIG_LIB_SYSCALL +/* SYS call 3: + * + * void tricore_syscall_return(void); + */ + +#define SYS_syscall_return (3) +#endif /* CONFIG_LIB_SYSCALL */ + +#ifndef CONFIG_BUILD_FLAT +/* SYS call 4: + * + * void up_task_start(main_t taskentry, int argc, char *argv[]) + * noreturn_function; + */ + +#define SYS_task_start (4) + +/* SYS call 5: + * + * void up_pthread_start((pthread_startroutine_t startup, + * pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +/* SYS call 6: + * + * void signal_handler(_sa_sigaction_t sighand, + * int signo, siginfo_t *info, + * void *ucontext); + */ + +#define SYS_signal_handler (6) + +/* SYS call 7: + * + * void signal_handler_return(void); + */ + +#define SYS_signal_handler_return (7) +#endif /* !CONFIG_BUILD_FLAT */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* SVC with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + : + : "d"(nbr) + : "d8" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall), "d"(nbr) + : "memory", "a11" + ); + + return reg0; +} + +/* SVC with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + "mov d9, %1 \n\t" + : + : "d"(nbr), "d"(parm1) + : "d8", "d9" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall) + : "memory", "a11" + ); + + return reg0; +} + +/* SVC with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + "mov d9, %1 \n\t" + "mov d10, %2 \n\t" + : + : "d"(nbr), "d"(parm1), "d"(parm2) + : "d8", "d9", "d10" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall) + : "memory", "a11" + ); + + return reg0; +} + +/* SVC with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + "mov d9, %1 \n\t" + "mov d10, %2 \n\t" + "mov d11, %3 \n\t" + : + : "d"(nbr), "d"(parm1), "d"(parm2), "d"(parm3) + : "d8", "d9", "d10", "d11" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall) + : "memory", "a11" + ); + + return reg0; +} + +/* SVC with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + "mov d9, %1 \n\t" + "mov d10, %2 \n\t" + "mov d11, %3 \n\t" + "mov d12, %4 \n\t" + : + : "d"(nbr), "d"(parm1), "d"(parm2), "d"(parm3), "d"(parm4) + : "d8", "d9", "d10", "d11", "d12" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall) + : "memory", "a11" + ); + + return reg0; +} + +/* SVC with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + "mov d9, %1 \n\t" + "mov d10, %2 \n\t" + "mov d11, %3 \n\t" + "mov d12, %4 \n\t" + "mov d13, %5 \n\t" + : + : "d"(nbr), "d"(parm1), "d"(parm2), "d"(parm3), "d"(parm4), "d"(parm5) + : "d8", "d9", "d10", "d11", "d12", "d13" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall) + : "memory", "a11" + ); + + return reg0; +} + +/* SVC with SYS_ call number and six parameters */ + +static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6) +{ + register long reg0; + + __asm volatile + ( + "mov d8, %0 \n\t" + "mov d9, %1 \n\t" + "mov d10, %2 \n\t" + "mov d11, %3 \n\t" + "mov d12, %4 \n\t" + "mov d13, %5 \n\t" + "mov d14, %6 \n\t" + : + : "d"(nbr), "d"(parm1), "d"(parm2), + "d"(parm3), "d"(parm4), "d"(parm5), "d"(parm6) + : "d8", "d9", "d10", "d11", "d12", "d13", "d14" + ); + __asm volatile + ( + "syscall %1" + : "=d"(reg0) + : "i"(SYS_syscall) + : "memory", "a11" + ); + + return reg0; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_TRICORE_INCLUDE_SYSCALL_H */ diff --git a/arch/tricore/include/tc3xx/irq.h b/arch/tricore/include/tc3xx/irq.h new file mode 100644 index 0000000000..72ddfb2e48 --- /dev/null +++ b/arch/tricore/include/tc3xx/irq.h @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/tricore/include/tc3xx/irq.h + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_TRICORE_INCLUDE_TC3XX_IRQ_H +#define __ARCH_TRICORE_INCLUDE_TC3XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* Upper CSA */ + +#define REG_UPCXI 0 +#define REG_PSW 1 +#define REG_A10 2 +#define REG_UA11 3 +#define REG_D8 4 +#define REG_D9 5 +#define REG_D10 6 +#define REG_D11 7 +#define REG_A12 8 +#define REG_A13 9 +#define REG_A14 10 +#define REG_A15 11 +#define REG_D12 12 +#define REG_D13 13 +#define REG_D14 14 +#define REG_D15 15 + +/* Lower CSA */ + +#define REG_LPCXI 0 +#define REG_LA11 1 +#define REG_A2 2 +#define REG_A3 3 +#define REG_D0 4 +#define REG_D1 5 +#define REG_D2 6 +#define REG_D3 7 +#define REG_A4 8 +#define REG_A5 9 +#define REG_A6 10 +#define REG_A7 11 +#define REG_D4 12 +#define REG_D5 13 +#define REG_D6 14 +#define REG_D7 15 + +#define REG_RA REG_UA11 +#define REG_SP REG_A10 +#define REG_UPC REG_UA11 + +#define REG_LPC REG_LA11 + +#define TC_CONTEXT_REGS (16) + +#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS) +#define XCPTCONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) + +#define NR_IRQS (255) + +/* PSW: Program Status Word Register */ + +#define PSW_CDE (1 << 7) /* Bits 7: Call Depth Count Enable */ +#define PSW_IS (1 << 9) /* Bits 9: Interrupt Stack Control */ +#define PSW_IO (10) /* Bits 10-11: Access Privilege Level Control (I/O Privilege) */ +# define PSW_IO_USER0 (0 << PSW_IO) +# define PSW_IO_USER1 (1 << PSW_IO) +# define PSW_IO_SUPERVISOR (2 << PSW_IO) + +/* PCXI: Previous Context Information and Pointer Register */ + +#define PCXI_UL (1 << 20) /* Bits 20: Upper or Lower Context Tag */ +#define PCXI_PIE (1 << 21) /* Bits 21: Previous Interrupt Enable */ + +/* FCX: Free CSA List Head Pointer Register */ + +#define FCX_FCXO (0) /* Bits 0-15: FCX Offset Address */ +#define FCX_FCXS (16) /* Bits 16-19: FCX Segment Address */ +#define FCX_FCXO_MASK (0xffff << FCX_FCXO) +#define FCX_FCXS_MASK (0xf << FCX_FCXS) +#define FCX_FREE (FCX_FCXS_MASK | FCX_FCXO_MASK) /* Free CSA manipulation */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of the context used during + * signal processing. + */ + + uintptr_t *saved_regs; + + /* Register save area with XCPTCONTEXT_SIZE, only valid when: + * 1.The task isn't running or + * 2.The task is interrupted + * otherwise task is running, and regs contain the stale value. + */ + + uintptr_t *regs; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_TRICORE_INCLUDE_TC3XX_IRQ_H */ diff --git a/arch/tricore/include/types.h b/arch/tricore/include/types.h new file mode 100644 index 0000000000..0daba00006 --- /dev/null +++ b/arch/tricore/include/types.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/tricore/include/types.h + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_TRICORE_INCLUDE_TYPES_H +#define __ARCH_TRICORE_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed long _int32_t; +typedef unsigned long _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +typedef _int64_t _intmax_t; +typedef _uint64_t _uintmax_t; + +#if defined(__WCHAR_TYPE__) +typedef __WCHAR_TYPE__ _wchar_t; +#else +typedef int _wchar_t; +#endif + +/* A size is 4 bytes */ + +#if defined(__SIZE_TYPE__) +/* If __SIZE_TYPE__ is defined we define ssize_t based on size_t. + * We simply change "unsigned" to "signed" for this single definition + * to make sure ssize_t and size_t only differ by their signedness. + */ + +#define unsigned signed +typedef __SIZE_TYPE__ _ssize_t; +#undef unsigned +typedef __SIZE_TYPE__ _size_t; +#elif defined(CONFIG_ARCH_SIZET_LONG) +typedef signed long _ssize_t; +typedef unsigned long _size_t; +#else +typedef signed int _ssize_t; +typedef unsigned int _size_t; +#endif + +/* This is the size of the interrupt state save returned by irqsave(). */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_TRICORE_INCLUDE_TYPES_H */ diff --git a/arch/tricore/src/.gitignore b/arch/tricore/src/.gitignore new file mode 100644 index 0000000000..b7393142a4 --- /dev/null +++ b/arch/tricore/src/.gitignore @@ -0,0 +1,3 @@ +/board +/chip +/*.S diff --git a/arch/tricore/src/Makefile b/arch/tricore/src/Makefile new file mode 100644 index 0000000000..2b460ed7fc --- /dev/null +++ b/arch/tricore/src/Makefile @@ -0,0 +1,217 @@ +############################################################################ +# arch/tricore/src/Makefile +# +# 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. +# +############################################################################ + +include $(TOPDIR)/Make.defs +include chip/Make.defs + +ifeq ($(CONFIG_ARCH_TC3XX),y) +ARCH_SUBDIR = tc3xx +endif + +ARCH_SRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src + +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)chip +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)common +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)$(ARCH_SUBDIR) +INCLUDES += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched + +CPPFLAGS += $(INCLUDES) +CFLAGS += $(INCLUDES) +CXXFLAGS += $(INCLUDES) +AFLAGS += $(INCLUDES) + +NUTTX = $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx$(EXEEXT)) + +# Additional rules for system call wrapper + +ifeq ($(CONFIG_SCHED_INSTRUMENTATION_SYSCALL),y) + EXTRALINKCMDS += @$(TOPDIR)/syscall/syscall_wraps.ldcmd +endif + +# The "head" object + +HEAD_COBJ = $(HEAD_CSRC:.c=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_COBJ) + +# Flat build or kernel-mode objects + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +# User-mode objects + +UASRCS = $(CHIP_UASRCS) $(CMN_UASRCS) +UAOBJS = $(UASRCS:.S=$(OBJEXT)) + +UCSRCS = $(CHIP_UCSRCS) $(CMN_UCSRCS) +UCOBJS = $(UCSRCS:.c=$(OBJEXT)) + +USRCS = $(UASRCS) $(UCSRCS) +UOBJS = $(UAOBJS) $(UCOBJS) + +KBIN = libkarch$(LIBEXT) +BIN = libarch$(LIBEXT) + +$(foreach lib,$(notdir $(wildcard $(APPDIR)$(DELIM)staging$(DELIM)*$(LIBEXT))), \ + $(foreach elib,$(EXTRA_LIBS), \ + $(if $(filter $(notdir $(elib)),$(lib)), \ + $(eval NAMEFULL_LIBS+=$(elib)), \ + $(if $(filter $(notdir $(elib)),$(patsubst lib%$(LIBEXT),-l%,$(lib))), \ + $(eval NAMESPEC_LIBS+=$(elib)) \ + ) \ + ) \ + ) \ + ) + +EXTRA_LIBS := $(filter-out $(NAMEFULL_LIBS) $(NAMESPEC_LIBS),$(EXTRA_LIBS)) +EXTRA_LIBS += $(wildcard $(APPDIR)$(DELIM)staging$(DELIM)*$(LIBEXT)) + +LIBPATH_OPT = --library-directory= +SCRIPT_OPT = --lsl-file= +LIBRARY_OPT = -l + +LDFLAGS += $(addprefix $(SCRIPT_OPT),$(call CONVERT_PATH,$(ARCHSCRIPT))) $(EXTRALINKCMDS) +LIBPATHS += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)staging) + +BOARDMAKE = $(if $(wildcard board$(DELIM)Makefile),y,) +ifeq ($(BOARDMAKE),y) + LIBPATHS += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board) +endif + +LIBPATHS := $(addprefix $(LIBPATH_OPT),$(LIBPATHS)) + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,$(LIBRARY_OPT)%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += $(LIBRARY_OPT)board +endif + +VPATH += chip +VPATH += common +VPATH += $(ARCH_SUBDIR) + +all: $(HEAD_COBJ) $(BIN) + +.PHONY: board$(DELIM)libboard$(LIBEXT) + +$(AOBJS) $(UAOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(UCOBJS) $(HEAD_COBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +ifeq ($(CONFIG_BUILD_FLAT),y) +$(BIN): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) +else +$(BIN): $(UOBJS) + $(call ARCHIVE, $@, $(UOBJS)) +endif + +$(KBIN): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board$(DELIM)libboard$(LIBEXT): + $(Q) $(MAKE) -C board libboard$(LIBEXT) EXTRAFLAGS="$(EXTRAFLAGS)" + +define LINK_ALLSYMS + $(Q) $(TOPDIR)/tools/mkallsyms.py $(NUTTX) allsyms.tmp --orderbyname $(CONFIG_SYMTAB_ORDEREDBYNAME) + $(Q) $(call COMPILE, allsyms.tmp, allsyms$(OBJEXT), -x c) + $(Q) $(LD) $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \ + -o $(NUTTX) $(HEAD_COBJ) allsyms$(OBJEXT) $(EXTRA_OBJS) \ + $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP) + $(Q) $(call DELFILE, allsyms.tmp allsyms$(OBJEXT)) +endef + +nuttx$(EXEEXT): $(HEAD_COBJ) board$(DELIM)libboard$(LIBEXT) $(ARCHSCRIPT) $(EXTRA_LIBS) + $(Q) echo "LD: nuttx" +ifneq ($(CONFIG_ALLSYMS),y) + $(Q) $(LD) $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \ + -o $(NUTTX) $(HEAD_COBJ) $(EXTRA_OBJS) \ + $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP) +else + $(Q) # Link and generate default table + $(Q) $(if $(wildcard $(shell echo $(NUTTX))),,$(call LINK_ALLSYMS,$^)) + $(Q) # Extract all symbols + $(Q) $(call LINK_ALLSYMS, $^) + $(Q) # Extract again since the table offset may changed + $(Q) $(call LINK_ALLSYMS, $^) +endif +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)$(DELIM)System.map +endif + +# This is part of the top-level export target +# Note that there may not be a head object if layout is handled +# by the linker configuration. + +export_startup: $(STARTUP_OBJS) +ifneq ($(STARTUP_OBJS),) + $(Q) if [ -d "$(EXPORT_DIR)$(DELIM)startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)$(DELIM)startup$(DELIM)."; \ + else \ + echo "$(EXPORT_DIR)$(DELIM)startup does not exist"; \ + exit 1; \ + fi +endif + +# Dependencies + +makedepfile: $(CSRCS:.c=.ddc) $(ASRCS:.S=.dds) + $(call CATFILE, Make.dep, $^) + $(call DELFILE, $^) + +.depend: Makefile chip$(DELIM)Make.defs $(SRCS) $(TOPDIR)$(DELIM).config +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board depend +endif + $(Q) $(MAKE) makedepfile DEPPATH="$(patsubst %,--dep-path %,$(subst :, ,$(VPATH)))" + $(Q) touch $@ + +depend: .depend + +context:: + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board clean +endif + $(call DELFILE, $(KBIN)) + $(call DELFILE, $(BIN)) +ifneq ($(EXTRADELFILE),) + $(call DELFILE, $(EXTRADELFILE)) +endif + $(call CLEAN) + +distclean:: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/tricore/src/common/Ifx_Cfg_Trap.h b/arch/tricore/src/common/Ifx_Cfg_Trap.h new file mode 100644 index 0000000000..4a6e702c7f --- /dev/null +++ b/arch/tricore/src/common/Ifx_Cfg_Trap.h @@ -0,0 +1,60 @@ +/**************************************************************************** + * arch/tricore/src/common/Ifx_Cfg_Trap.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_TRICORE_SRC_COMMON_IFX_CFG_TRAP_H +#define __ARCH_TRICORE_SRC_COMMON_IFX_CFG_TRAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "tricore_internal.h" + +#if (IFX_CFG_EXTEND_TRAP_HOOKS == 1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Trap Hook defination */ + +/* Trap Call */ + +#define IFX_CFG_CPU_TRAP_TSR_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_NMI_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_MME_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_IPE_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_IE_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_CME_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_BE_HOOK(trapInfo) tricore_trapcall(&trapInfo) +#define IFX_CFG_CPU_TRAP_ASSERT_HOOK(trapInfo) tricore_trapcall(&trapInfo) + +#define IFX_CFG_CPU_TRAP_SYSCALL_CPU0_HOOK(trapWatch) tricore_svcall(&trapWatch) +#define IFX_CFG_CPU_TRAP_SYSCALL_CPU1_HOOK(trapWatch) tricore_svcall(&trapWatch) +#define IFX_CFG_CPU_TRAP_SYSCALL_CPU2_HOOK(trapWatch) tricore_svcall(&trapWatch) +#define IFX_CFG_CPU_TRAP_SYSCALL_CPU3_HOOK(trapWatch) tricore_svcall(&trapWatch) +#define IFX_CFG_CPU_TRAP_SYSCALL_CPU4_HOOK(trapWatch) tricore_svcall(&trapWatch) +#define IFX_CFG_CPU_TRAP_SYSCALL_CPU5_HOOK(trapWatch) tricore_svcall(&trapWatch) + +#endif /* IFX_CFG_EXTEND_TRAP_HOOKS */ + +#endif /* __ARCH_TRICORE_SRC_COMMON_IFX_CFG_TRAP_H */ diff --git a/arch/tricore/src/common/Make.defs b/arch/tricore/src/common/Make.defs new file mode 100644 index 0000000000..ba9610a227 --- /dev/null +++ b/arch/tricore/src/common/Make.defs @@ -0,0 +1,50 @@ +############################################################################ +# arch/tricore/src/common/Make.defs +# +# 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. +# +############################################################################ + +HEAD_CSRC += tricore_doirq.c + +CMN_CSRCS += tricore_allocateheap.c +CMN_CSRCS += tricore_checkstack.c +CMN_CSRCS += tricore_createstack.c +CMN_CSRCS += tricore_csa.c +CMN_CSRCS += tricore_exit.c +CMN_CSRCS += tricore_getintstack.c +CMN_CSRCS += tricore_idle.c +CMN_CSRCS += tricore_initialize.c +CMN_CSRCS += tricore_initialstate.c +CMN_CSRCS += tricore_irq.c +CMN_CSRCS += tricore_main.c +CMN_CSRCS += tricore_mdelay.c +CMN_CSRCS += tricore_nputs.c +CMN_CSRCS += tricore_registerdump.c +CMN_CSRCS += tricore_releasestack.c +CMN_CSRCS += tricore_saveusercontext.c +CMN_CSRCS += tricore_schedulesigaction.c +CMN_CSRCS += tricore_sigdeliver.c +CMN_CSRCS += tricore_stackframe.c +CMN_CSRCS += tricore_svcall.c +CMN_CSRCS += tricore_switchcontext.c +CMN_CSRCS += tricore_tcbinfo.c +CMN_CSRCS += tricore_trapcall.c +CMN_CSRCS += tricore_systimer.c +CMN_CSRCS += tricore_usestack.c + +CFLAGS += -DIFX_CFG_EXTEND_TRAP_HOOKS +CFLAGS += -DIFX_USE_SW_MANAGED_INT diff --git a/arch/tricore/src/common/Toolchain.defs b/arch/tricore/src/common/Toolchain.defs new file mode 100644 index 0000000000..895a8df48c --- /dev/null +++ b/arch/tricore/src/common/Toolchain.defs @@ -0,0 +1,127 @@ +############################################################################ +# arch/tricore/src/common/Toolchain.defs +# +# 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. +# +############################################################################ + +# +# Supported toolchains +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# ARCHOPTIMIZATION The optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + ARCHOPTIMIZATION += $(CONFIG_DEBUG_OPTLEVEL) +else ifeq ($(CONFIG_DEBUG_FULLOPT),y) + ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),y) + ARCHOPTIMIZATION += -Oz + else + ARCHOPTIMIZATION += -Os + endif +endif + +# Tasking toolchain + +CC = cctc +CXX = cctc +CPP = cctc $(ARCHOPTIMIZATION) +LD = cctc +STRIP = strip --strip-unneeded +AR = artc -r +NM = nm +OBJCOPY = echo +OBJDUMP = elfdump + +ARCHOPTIMIZATION += --lsl-core=vtc +LDFLAGS += --lsl-core=vtc +ARCHOPTIMIZATION += --iso=99 +ARCHOPTIMIZATION += --language=+gcc,+volatile,-strings,-kanji + +# pragma align <4> (default: 0) + +ARCHOPTIMIZATION += --align=4 + +# Always use 32-bit integers for enumeration + +ARCHOPTIMIZATION += --integer-enumeration + +# tradeoff between speed (-t0) and size (-t4) (default: 4) + +ARCHOPTIMIZATION += --tradeoff=2 + +# enable symbolic debug information + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION += --debug-info=default + ARCHOPTIMIZATION += --keep-temporary-files + LDFLAGS += -g +endif + +# merge source code with assembly output + +ARCHOPTIMIZATION += --source + +# generate alignment depending on assume_if hints + +ARCHOPTIMIZATION += --branch-target-align + + +# Since nuttx uses too many of GNU extensions in the implementation of +# FPU-related library functions, which is not supported in tasking, +# so currently we cannot use FPU-related configurations to manage it. +# +# Just set fp-model to Double Precision: +# --fp-model[=,...] floating-point model (default: cFlnrSTz) +# 0 alias for --fp-model=CFLNRStZ (strict) +# 1 alias for --fp-model=cFLNRSTZ (precise) +# 2 alias for --fp-model=cFlnrSTz (fast-dp) +# 3 alias for --fp-model=cflnrSTz (fast-sp) + +ARCHOPTIMIZATION += --fp-model=2 +LDFLAGS += --fp-model=2 +LDFLAGS += -lfp_fpu + +LDFLAGS += --hex-format=s -Wl-OtxYcL -Wl-mcrfiklsmnoduq +LDFLAGS += -lrt + +# ctc W500: ["stdio/lib_libvsprintf.c" 884/29] expression without effect +# ctc W507: ["mm_heap/mm_malloc.c" 238/64] variable "nodesize" is possibly uninitialized +# ctc W508: ["misc/lib_impure.c" 1/1] empty source file +# ctc W525: ["getopt.c" 678/3] discarded 'const' qualifier at assignment: conversion from char const * to char * +# ctc W527: ["stdlib/lib_strtold.c" 565/23] constant of type "double" saturated +# ctc W526: ["include/sys/epoll.h" 87/5] enumeration constant shall be representable as 'int' +# ctc W529: ["wchar/lib_mbrtowc.c" 88/35] overflow in constant expression of type "unsigned long int" +# ctc W544: ["wqueue/kwork_thread.c" 210/32] unreachable code +# ctc W549: ["unistd/lib_getopt_common.c" 544/15] condition is always true +# ctc W553: ["vfs/fs_fcntl.c" 231/7] no 'break' or comment before case label +# ctc W557: ["common/tricore_main.c" 58/11] possible infinite loop +# ctc W560: ["tmpfs/fs_tmpfs.c" 232/25] possible truncation at implicit conversion to type "unsigned short int" +# ctc W562: ["mm_heap/mm_memalign.c" 70/20] unary minus applied to unsigned value +# ctc W558: ["include/nuttx/power/regulator.h" 224/36] struct/union/enum definition in parameter declaration +# ctc W587: ["stdlib/lib_strtold.c" 571/23] underflow on constant of type "double" +# ctc W588: ["misc/lib_glob.c" 150/13] dead assignment to "i" eliminated +# ctc W589: ["inode/fs_inodesearch.c" 72/8] pointer assumed to be nonzero - test removed + +TASKING_WARNINGS = 500,507,508,525,526,527,529,544,549,553,560,562,557,558,587,588,589 + +ARCHOPTIMIZATION += --pass-c=--no-warnings=$(TASKING_WARNINGS) diff --git a/arch/tricore/src/common/tricore_allocateheap.c b/arch/tricore/src/common/tricore_allocateheap.c new file mode 100644 index 0000000000..c57de7d524 --- /dev/null +++ b/arch/tricore/src/common/tricore_allocateheap.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_allocateheap.c + * + * 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 +#include + +#include +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(void **heap_start, size_t *heap_size) +{ + *heap_start = _edata; + *heap_size = (size_t)((uintptr_t)_eheap - (uintptr_t)_edata); +} diff --git a/arch/tricore/src/common/tricore_checkstack.c b/arch/tricore/src/common/tricore_checkstack.c new file mode 100644 index 0000000000..f12fd84e4a --- /dev/null +++ b/arch/tricore/src/common/tricore_checkstack.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_checkstack.c + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "tricore_internal.h" + +#ifdef CONFIG_STACK_COLORATION + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_stack_check + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * alloc - Allocation base address of the stack + * size - The size of the stack in bytes + * + * Returned Value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +size_t tricore_stack_check(uintptr_t alloc, size_t size) +{ + uintptr_t start; + uintptr_t end; + uint32_t *ptr; + size_t mark; + + if (size == 0) + { + return 0; + } + + /* Get aligned addresses of the top and bottom of the stack */ + + start = (alloc + 3) & ~3; + end = (alloc + size) & ~3; + + /* Get the adjusted size based on the top and bottom of the stack */ + + size = end - start; + + /* RISC-V uses a push-down stack: the stack grows toward lower addresses + * in memory. We need to start at the lowest address in the stack memory + * allocation and search to higher addresses. The first word we encounter + * that does not have the magic value is the high water mark. + */ + + for (ptr = (uint32_t *)start, mark = (size >> 2); + *ptr == STACK_COLOR && mark > 0; + ptr++, mark--); + + /* Return our guess about how much stack space was used */ + + return mark << 2; +} + +/**************************************************************************** + * Name: up_check_tcbstack and friends + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * None + * + * Returned Value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +size_t up_check_tcbstack(struct tcb_s *tcb) +{ + size_t size; + +#ifdef CONFIG_ARCH_ADDRENV + struct addrenv_s *oldenv; + + if (tcb->addrenv_own != NULL) + { + addrenv_select(tcb->addrenv_own, &oldenv); + } +#endif + + size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr, + tcb->adj_stack_size); + +#ifdef CONFIG_ARCH_ADDRENV + if (tcb->addrenv_own != NULL) + { + addrenv_restore(oldenv); + } +#endif + + return size; +} + +#if CONFIG_ARCH_INTERRUPTSTACK > 15 +size_t up_check_intstack(void) +{ + return tricore_stack_check((uintptr_t)g_intstackalloc, + (CONFIG_ARCH_INTERRUPTSTACK & ~15)); +} +#endif + +#endif /* CONFIG_STACK_COLORATION */ diff --git a/arch/tricore/src/common/tricore_createstack.c b/arch/tricore/src/common/tricore_createstack.c new file mode 100644 index 0000000000..f485c548a6 --- /dev/null +++ b/arch/tricore/src/common/tricore_createstack.c @@ -0,0 +1,247 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_createstack.c + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. + * + * Input Parameters: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif + + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + * If TLS is enabled, then we must allocate aligned stacks. + */ + +#ifdef CONFIG_TLS_ALIGNED +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = kumm_malloc(stack_size); + } +#endif /* CONFIG_TLS_ALIGNED */ + +#ifdef CONFIG_DEBUG_FEATURES + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + serr("ERROR: Failed to allocate stack, size %zu\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + uintptr_t top_of_stack; + size_t size_of_stack; + + /* RISC-V uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register points to the + * lowest, valid working address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from SP. + */ + + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + + /* The RISC-V stack must be aligned at 128-bit (16-byte) boundaries. + * If necessary top_of_stack must be rounded down to the next boundary. + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = size_of_stack; + +#ifdef CONFIG_STACK_COLORATION + /* If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + + tricore_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); + +#endif /* CONFIG_STACK_COLORATION */ + tcb->flags |= TCB_FLAG_FREE_STACK; + + return OK; + } + + return ERROR; +} + +/**************************************************************************** + * Name: tricore_stack_color + * + * Description: + * Write a well know value into the stack + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +void tricore_stack_color(void *stackbase, size_t nbytes) +{ + uint32_t *stkptr; + uintptr_t stkend; + size_t nwords; + uintptr_t sp; + + /* Take extra care that we do not write outside the stack boundaries */ + + stkptr = (uint32_t *)STACK_ALIGN_UP((uintptr_t)stackbase); + + if (nbytes == 0) /* 0: colorize the running stack */ + { + stkend = up_getsp(); + if (stkend > (uintptr_t)&sp) + { + stkend = (uintptr_t)&sp; + } + } + else + { + stkend = (uintptr_t)stackbase + nbytes; + } + + stkend = STACK_ALIGN_DOWN(stkend); + nwords = (stkend - (uintptr_t)stkptr) >> 2; + + /* Set the entire stack to the coloration value */ + + while (nwords-- > 0) + { + *stkptr++ = STACK_COLOR; + } +} +#endif diff --git a/arch/tricore/src/common/tricore_csa.c b/arch/tricore/src/common/tricore_csa.c new file mode 100644 index 0000000000..cec39ccb8a --- /dev/null +++ b/arch/tricore/src/common/tricore_csa.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_csa.c + * + * 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 +#include +#include + +#include +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_alloc_csa + ****************************************************************************/ + +uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, + uintptr_t psw, bool irqsave) +{ + uintptr_t *plcsa; + uintptr_t *pucsa; + + plcsa = (uintptr_t *)tricore_csa2addr(__mfcr(CPU_FCX)); + + pucsa = (uintptr_t *)tricore_csa2addr(plcsa[REG_UPCXI]); + + __mtcr(CPU_FCX, pucsa[REG_UPCXI]); + + memset(pucsa, 0, XCPTCONTEXT_SIZE); + memset(plcsa, 0, XCPTCONTEXT_SIZE); + + pucsa[REG_SP] = sp; + pucsa[REG_PSW] = psw; + + /* Save the task entry point */ + + pucsa[REG_UPC] = pc; + plcsa[REG_LPC] = pc; + + plcsa[REG_LPCXI] = (PCXI_UL | tricore_addr2csa(pucsa)); + + if (!irqsave) + { + plcsa[REG_LPCXI] |= PCXI_PIE; + } + + return (uintptr_t *)tricore_addr2csa(plcsa); +} + +/**************************************************************************** + * Name: tricore_reclaim_csa + ****************************************************************************/ + +void tricore_reclaim_csa(uintptr_t pcxi) +{ + uintptr_t head, tail, free; + uintptr_t *next; + + /* A pointer to the first CSA in the list of CSAs consumed by the task is + * stored in the first element of the tasks TCB structure (where the stack + * pointer would be on a traditional stack based architecture). + */ + + head = pcxi & FCX_FREE; + + /* Mask off everything in the CSA link field other than the address. If + * the address is NULL, then the CSA is not linking anywhere and there is + * nothing to do. + */ + + tail = head; + + /* Convert the link value to contain just a raw address and store this + * in a local variable. + */ + + next = tricore_csa2addr(tail); + + /* Iterate over the CSAs that were consumed as part of the task. The + * first field in the CSA is the pointer to then next CSA. Mask off + * everything in the pointer to the next CSA, other than the link address. + * If this is NULL, then the CSA currently being pointed to is the last in + * the chain. + */ + + while ((next[0] & FCX_FREE) != 0) + { + /* Clear all bits of the pointer to the next in the chain, other + * than the address bits themselves. + */ + + next[0] = next[0] & FCX_FREE; + + /* Move the pointer to point to the next CSA in the list. */ + + tail = next[0]; + + /* Update the local pointer to the CSA. */ + + next = tricore_csa2addr(tail); + } + + /* Look up the current free CSA head. */ + + free = __mfcr(CPU_FCX); + + /* Join the current Free onto the Tail of what is being reclaimed. */ + + tricore_csa2addr(tail)[0] = free; + + /* Move the head of the reclaimed into the Free. */ + + __mtcr(CPU_FCX, head); +} diff --git a/arch/tricore/src/common/tricore_doirq.c b/arch/tricore/src/common/tricore_doirq.c new file mode 100644 index 0000000000..79224336a5 --- /dev/null +++ b/arch/tricore/src/common/tricore_doirq.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_doirq.c + * + * 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 +#include + +#include +#include +#include +#include + +#include + +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + Ifx_CPU_ICR icr; + uintptr_t *regs; + + icr.U = __mfcr(CPU_ICR); + regs = (uintptr_t *)__mfcr(CPU_PCXI); + + board_autoled_on(LED_INIRQ); + + /* Nested interrupts are not supported */ + + DEBUGASSERT(CURRENT_REGS == NULL); + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + CURRENT_REGS = regs; + + /* Deliver the IRQ */ + + irq_dispatch(icr.B.CCPN, regs); + + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + addrenv_switch(NULL); +#endif + + /* Record the new "running" task when context switch occurred. + * g_running_tasks[] is only used by assertion logic for reporting + * crashes. + */ + + g_running_tasks[this_cpu()] = this_task(); + + __mtcr(CPU_PCXI, (uintptr_t)CURRENT_REGS); + __isync(); + } + + /* Set CURRENT_REGS to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + CURRENT_REGS = NULL; + + board_autoled_off(LED_INIRQ); +#endif +} diff --git a/arch/tricore/src/common/tricore_exit.c b/arch/tricore/src/common/tricore_exit.c new file mode 100644 index 0000000000..9243021ba8 --- /dev/null +++ b/arch/tricore/src/common/tricore_exit.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_exit.c + * + * 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 +#include +#include +#include + +#include +#include + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void up_exit(int status) +{ + struct tcb_s *tcb = this_task(); + + /* Make sure that we are in a critical section with local interrupts. + * The IRQ state will be restored when the next task is started. + */ + + enter_critical_section(); + + nxsched_dumponexit(); + + /* Destroy the task at the head of the ready to run list. */ + + nxtask_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + + /* Adjusts time slice for SCHED_RR & SCHED_SPORADIC cases + * NOTE: the API also adjusts the global IRQ control for SMP + */ + + nxsched_resume_scheduler(tcb); + + /* Then switch contexts */ + + tricore_fullcontextrestore(tcb->xcp.regs); + + /* tricore_fullcontextrestore() should not return but could if the software + * interrupts are disabled. + */ + + PANIC(); +} diff --git a/arch/tricore/src/common/tricore_getintstack.c b/arch/tricore/src/common/tricore_getintstack.c new file mode 100644 index 0000000000..9fca8b9eaa --- /dev/null +++ b/arch/tricore/src/common/tricore_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_getintstack.c + * + * 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 + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/tricore/src/common/tricore_idle.c b/arch/tricore/src/common/tricore_idle.c new file mode 100644 index 0000000000..0ec6062c5c --- /dev/null +++ b/arch/tricore/src/common/tricore_idle.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_idle.c + * + * 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 +#include +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when there is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + + /* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#ifdef CONFIG_ARCH_LEDS_CPU_ACTIVITY + board_autoled_off(LED_CPU); +#endif + + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + */ + + Ifx_Ssw_infiniteLoop(); +#endif +} diff --git a/arch/tricore/src/common/tricore_initialize.c b/arch/tricore/src/common/tricore_initialize.c new file mode 100644 index 0000000000..1ee4f419dc --- /dev/null +++ b/arch/tricore/src/common/tricore_initialize.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_initialize.c + * + * 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 +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_color_intstack + * + * Description: + * Set the interrupt stack to a value so that later we can determine how + * much stack space was used by interrupt handling logic + * + ****************************************************************************/ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15 +static inline void up_color_intstack(void) +{ + uint32_t *ptr = (uint32_t *)g_intstackalloc; + ssize_t size; + + for (size = (CONFIG_ARCH_INTERRUPTSTACK & ~15); + size > 0; + size -= sizeof(uint32_t)) + { + *ptr++ = INTSTACK_COLOR; + } +} +#else +# define up_color_intstack() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Colorize the interrupt stack */ + + up_color_intstack(); + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + tricore_serialinit(); +#endif +} diff --git a/arch/tricore/src/common/tricore_initialstate.c b/arch/tricore/src/common/tricore_initialstate.c new file mode 100644 index 0000000000..f7d394c24f --- /dev/null +++ b/arch/tricore/src/common/tricore_initialstate.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_initialstate.c + * + * 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 +#include +#include + +#include +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the initial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Initialize the idle thread stack */ + + if (tcb->pid == IDLE_PROCESS_ID) + { + tcb->stack_alloc_ptr = (void *)((uintptr_t)g_idle_topstack - + CONFIG_IDLETHREAD_STACKSIZE); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; + +#ifdef CONFIG_STACK_COLORATION + /* If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + + tricore_stack_color(tcb->stack_alloc_ptr, 0); +#endif /* CONFIG_STACK_COLORATION */ + return; + } + + xcp->regs = tricore_alloc_csa((uintptr_t)tcb->start, + (uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size, + PSW_IO_SUPERVISOR | PSW_CDE, false); +} diff --git a/arch/tricore/src/common/tricore_internal.h b/arch/tricore/src/common/tricore_internal.h new file mode 100644 index 0000000000..e306f787a7 --- /dev/null +++ b/arch/tricore/src/common/tricore_internal.h @@ -0,0 +1,252 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_internal.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_TRICORE_SRC_COMMON_TRICORE_INTERNAL_H +#define __ARCH_TRICORE_SRC_COMMON_TRICORE_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +# include +# include + +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#ifndef CONFIG_DEV_CONSOLE +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +#else +# if defined(CONFIG_LWL_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# elif defined(CONFIG_CONSOLE_SYSLOG) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# elif defined(CONFIG_SERIAL_RTT_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# elif defined(CONFIG_RPMSG_UART_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* For use with EABI and floating point, the stack must be aligned to 8-byte + * addresses. + */ + +#define STACK_ALIGNMENT 8 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT - 1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +#define INTSTACK_SIZE (CONFIG_ARCH_INTERRUPTSTACK & ~STACK_ALIGN_MASK) + +/* This is the value used to mark the stack for subsequent stack monitoring + * logic. + */ + +#define STACK_COLOR 0xdeadbeef +#define INTSTACK_COLOR 0xdeadbeef +#define HEAP_COLOR 'h' + +#define getreg8(a) (*(volatile uint8_t *)(a)) +#define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +#define getreg16(a) (*(volatile uint16_t *)(a)) +#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +#define getreg32(a) (*(volatile uint32_t *)(a)) +#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) +#define getreg64(a) (*(volatile uint64_t *)(a)) +#define putreg64(v,a) (*(volatile uint64_t *)(a) = (v)) + +/* Non-atomic, but more effective modification of registers */ + +#define modreg8(v,m,a) putreg8((getreg8(a) & ~(m)) | ((v) & (m)), (a)) +#define modreg16(v,m,a) putreg16((getreg16(a) & ~(m)) | ((v) & (m)), (a)) +#define modreg32(v,m,a) putreg32((getreg32(a) & ~(m)) | ((v) & (m)), (a)) +#define modreg64(v,m,a) putreg64((getreg64(a) & ~(m)) | ((v) & (m)), (a)) + +/* Context switching */ + +#ifndef tricore_fullcontextrestore +# define tricore_fullcontextrestore(restoreregs) \ + sys_call1(SYS_restore_context, (uintptr_t)restoreregs); +#else +extern void tricore_fullcontextrestore(uintptr_t *restoreregs); +#endif + +#ifndef tricore_switchcontext +# define tricore_switchcontext(saveregs, restoreregs) \ + sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs); +#else +extern void tricore_switchcontext(uintptr_t **saveregs, + uintptr_t *restoreregs); +#endif + +/* Address <--> Context Save Areas */ + +#define tricore_csa2addr(csa) ((uintptr_t *)((((csa) & 0x000F0000) << 12) \ + | (((csa) & 0x0000FFFF) << 6))) +#define tricore_addr2csa(addr) ((uintptr_t)(((((uintptr_t)(addr)) & 0xF0000000) >> 12) \ + | (((uintptr_t)(addr) & 0x003FFFC0) >> 6))) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This is the beginning of heap as provided from up_head.S. This is the + * first address in DRAM after the loaded program+bss+idle stack. The + * end of the heap is CONFIG_RAM_END + */ + +extern uintptr_t __USTACK0_END[]; +extern uintptr_t __USTACK0[]; +#define g_idle_topstack __USTACK0 + +/* Address of the saved user stack pointer */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +extern uintptr_t __ISTACK0_END[]; +extern uintptr_t __ISTACK0[]; +#define g_intstackalloc __ISTACK0_END +#define g_intstacktop __ISTACK0 +#endif + +/* These symbols are setup by the linker script. */ + +extern uintptr_t _lc_gb_data[]; /* Start of .data */ +extern uintptr_t _lc_ge_data[]; /* End+1 of .data */ +#define _sdata _lc_gb_data +#define _edata _lc_ge_data +#define _eheap __USTACK0_END +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#define tricore_savecontext(regs) (regs = (uintptr_t *)CURRENT_REGS) +#define tricore_restorecontext(regs) (CURRENT_REGS = regs) + +/* Macros to handle saving and restoring interrupt state. */ + +#define tricore_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS) +#define tricore_restorestate(regs) (CURRENT_REGS = regs) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Signal handling **********************************************************/ + +void tricore_sigdeliver(void); + +/* Exception Handler ********************************************************/ + +void tricore_svcall(volatile void *trap); +void tricore_trapcall(volatile void *trap); + +/* Context Save Areas *******************************************************/ + +uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, + uintptr_t psw, bool irqsave); +void tricore_reclaim_csa(uintptr_t pcxi); + +/* Low level serial output **************************************************/ + +void tricore_lowputc(char ch); +void tricore_lowputs(const char *str); + +#ifdef USE_SERIALDRIVER +void tricore_serialinit(void); +#endif + +#ifdef USE_EARLYSERIALINIT +void tricore_earlyserialinit(void); +#endif + +/* System Timer *************************************************************/ + +struct oneshot_lowerhalf_s * +tricore_systimer_initialize(void *tbase, int irq, uint64_t freq); + +/* Debug ********************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +size_t tricore_stack_check(uintptr_t alloc, size_t size); +void tricore_stack_color(void *stackbase, size_t nbytes); +#endif + +#endif /* __ARCH_TRICORE_SRC_COMMON_TRICORE_INTERNAL_H */ diff --git a/arch/tricore/src/common/tricore_irq.c b/arch/tricore/src/common/tricore_irq.c new file mode 100644 index 0000000000..6c87de493b --- /dev/null +++ b/arch/tricore/src/common/tricore_irq.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_irq.c + * + * 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 +#include +#include + +#include +#include + +#include "tricore_internal.h" + +#include "IfxSrc.h" +#include "IfxCpu.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Enable interrupts globally. + * + ****************************************************************************/ + +void up_irq_enable(void) +{ + IfxCpu_enableInterrupts(); +} + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + up_irq_enable(); +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq; + + IfxSrc_disable(src); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq; + + IfxSrc_init(src, IfxSrc_Tos_cpu0, irq); + IfxSrc_enable(src); +} + +/**************************************************************************** + * Name: tricore_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void tricore_ack_irq(int irq) +{ +} diff --git a/arch/tricore/src/common/tricore_main.c b/arch/tricore/src/common/tricore_main.c new file mode 100644 index 0000000000..b62107cd05 --- /dev/null +++ b/arch/tricore/src/common/tricore_main.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_main.c + * + * 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 + +#include "Ifx_Types.h" +#include "IfxScuWdt.h" +#include "IfxCpu.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void core_main(void) +{ + static IfxCpu_syncEvent g_sync_event = 0; + + /* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!! + * Enable the watchdogs and service them periodically if it is required + */ + + IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword()); + IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword()); + + /* Wait for CPU sync event */ + + IfxCpu_emitEvent(&g_sync_event); + IfxCpu_waitEvent(&g_sync_event, 1); + + if (IfxCpu_getCoreIndex() == 0) + { + tricore_earlyserialinit(); + nx_start(); + } + + while (1); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void core0_main(void) +{ + core_main(); +} + +void core1_main(void) +{ + core_main(); +} + +void core2_main(void) +{ + core_main(); +} + +void core3_main(void) +{ + core_main(); +} + +void core4_main(void) +{ + core_main(); +} + +void core5_main(void) +{ + core_main(); +} diff --git a/arch/tricore/src/common/tricore_mdelay.c b/arch/tricore/src/common/tricore_mdelay.c new file mode 100644 index 0000000000..57c5f4c382 --- /dev/null +++ b/arch/tricore/src/common/tricore_mdelay.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_mdelay.c + * + * 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile unsigned int i; + volatile unsigned int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/tricore/src/common/tricore_nputs.c b/arch/tricore/src/common/tricore_nputs.c new file mode 100644 index 0000000000..421e2b9f89 --- /dev/null +++ b/arch/tricore/src/common/tricore_nputs.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_nputs.c + * + * 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_nputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_nputs(const char *str, size_t len) +{ + while (len-- > 0 && *str) + { + up_putc(*str++); + } +} diff --git a/arch/tricore/src/common/tricore_registerdump.c b/arch/tricore/src/common/tricore_registerdump.c new file mode 100644 index 0000000000..e1dcddfe1e --- /dev/null +++ b/arch/tricore/src/common/tricore_registerdump.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_registerdump.c + * + * 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 +#include +#include + +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void *regs) +{ + uintptr_t *csa = regs; + + while (((uintptr_t)csa & PCXI_UL) == 0) + { + csa = tricore_csa2addr((uintptr_t)csa); + csa = (uintptr_t *)csa[0]; + } + + csa = tricore_csa2addr((uintptr_t)csa); + + return csa[REG_SP]; +} + +/**************************************************************************** + * Name: up_dump_register + ****************************************************************************/ + +void up_dump_register(void *dumpregs) +{ +} diff --git a/arch/tricore/src/common/tricore_releasestack.c b/arch/tricore/src/common/tricore_releasestack.c new file mode 100644 index 0000000000..28f4da8cb0 --- /dev/null +++ b/arch/tricore/src/common/tricore_releasestack.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_releasestack.c + * + * 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 +#include + +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parameters: + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr && (dtcb->flags & TCB_FLAG_FREE_STACK)) + { +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + kmm_free(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + kumm_free(dtcb->stack_alloc_ptr); + } + } + + /* Mark the stack freed */ + + dtcb->flags &= ~TCB_FLAG_FREE_STACK; + dtcb->stack_alloc_ptr = NULL; + dtcb->stack_base_ptr = NULL; + dtcb->adj_stack_size = 0; +} diff --git a/arch/tricore/src/common/tricore_saveusercontext.c b/arch/tricore/src/common/tricore_saveusercontext.c new file mode 100644 index 0000000000..6b9d6b0853 --- /dev/null +++ b/arch/tricore/src/common/tricore_saveusercontext.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_saveusercontext.c + * + * 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" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_saveusercontext + * + * Description: + * Save the current thread context + * + ****************************************************************************/ + +int up_saveusercontext(void *saveregs) +{ + uintptr_t *regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + memcpy(saveregs, regs, XCPTCONTEXT_SIZE); + return 0; +} diff --git a/arch/tricore/src/common/tricore_schedulesigaction.c b/arch/tricore/src/common/tricore_schedulesigaction.c new file mode 100644 index 0000000000..cde5214005 --- /dev/null +++ b/arch/tricore/src/common/tricore_schedulesigaction.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_schedulesigaction.c + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'sigdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + * Assumptions: + * Called from critical section + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + /* Refuse to handle nested signal actions */ + + if (tcb->xcp.sigdeliver == NULL) + { + tcb->xcp.sigdeliver = sigdeliver; + + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (CURRENT_REGS == NULL) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + tcb->xcp.sigdeliver = NULL; + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * CURRENT_REGS does not refer to the thread of this_task()! + */ + + else + { + /* Save the context registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tricore_savestate(tcb->xcp.saved_regs); + + /* Create a new CSA for signal delivery. The new context + * will borrow the process stack of the current tcb. + */ + + CURRENT_REGS = tricore_alloc_csa((uintptr_t)tricore_sigdeliver, + STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), + PSW_IO_SUPERVISOR | PSW_CDE, true); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + /* Save the current register context location */ + + tcb->xcp.saved_regs = tcb->xcp.regs; + + /* Create a new CSA for signal delivery. The new context + * will borrow the process stack of the current tcb. + */ + + tcb->xcp.regs = tricore_alloc_csa((uintptr_t)tricore_sigdeliver, + STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), + PSW_IO_SUPERVISOR | PSW_CDE, true); + } + } +} diff --git a/arch/tricore/src/common/tricore_sigdeliver.c b/arch/tricore/src/common/tricore_sigdeliver.c new file mode 100644 index 0000000000..9888597b9b --- /dev/null +++ b/arch/tricore/src/common/tricore_sigdeliver.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_sigdeliver.c + * + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void tricore_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uintptr_t *regs = rtcb->xcp.saved_regs; + + board_autoled_on(LED_SIGNAL); + + sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + DEBUGASSERT(rtcb->xcp.sigdeliver != NULL); + +retry: + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Then make sure that interrupts are enabled. Signal handlers must always + * run with interrupts enabled. + */ + + up_irq_enable(); +#endif + + /* Deliver the signal */ + + ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + * + * I would prefer that all interrupts are disabled when + * tricore_fullcontextrestore() is called, but that may not be necessary. + */ + + sinfo("Resuming\n"); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_save(); +#endif + + if (!sq_empty(&rtcb->sigpendactionq) && + (rtcb->flags & TCB_FLAG_SIGNAL_ACTION) == 0) + { + goto retry; + } + + /* Modify the saved return state with the actual saved values in the + * TCB. This depends on the fact that nested signal handling is + * not supported. Therefore, these values will persist throughout the + * signal handling action. + * + * Keeping this data in the TCB resolves a security problem in protected + * and kernel mode: The regs[] array is visible on the user stack and + * could be modified by a hostile program. + */ + + rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */ + + /* Then restore the correct state for this thread of + * execution. + */ + + board_autoled_off(LED_SIGNAL); + + tricore_fullcontextrestore(regs); +} diff --git a/arch/tricore/src/common/tricore_stackframe.c b/arch/tricore/src/common/tricore_stackframe.c new file mode 100644 index 0000000000..93a1a51283 --- /dev/null +++ b/arch/tricore/src/common/tricore_stackframe.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_stackframe.c + * + * 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 +#include +#include +#include + +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. + * + * Input Parameters: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +void *up_stack_frame(struct tcb_s *tcb, size_t frame_size) +{ + void *ret; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->stack_base_ptr = (uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; + + /* And return the pointer to the allocated region */ + + return ret; +} diff --git a/arch/tricore/src/common/tricore_svcall.c b/arch/tricore/src/common/tricore_svcall.c new file mode 100644 index 0000000000..6628e89a51 --- /dev/null +++ b/arch/tricore/src/common/tricore_svcall.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_svcall.c + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_svcall + * + * Description: + * This is SVCall exception handler that performs context switching + * + ****************************************************************************/ + +void tricore_svcall(volatile void *trap) +{ + uintptr_t *regs; + uint32_t cmd; + + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + + CURRENT_REGS = regs; + + cmd = regs[REG_D8]; + + /* Handle the SVCall according to the command in R0 */ + + switch (cmd) + { + /* R0=SYS_restore_context: This a restore context command: + * + * void tricore_fullcontextrestore(uint32_t *restoreregs) + * noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_restore_context + * R1 = restoreregs + * + * In this case, we simply need to set CURRENT_REGS to restore + * register area referenced in the saved R1. context == CURRENT_REGS + * is the normal exception return. By setting CURRENT_REGS = + * context[R1], we force the return to the saved context referenced + * in R1. + */ + + case SYS_restore_context: + { + tricore_reclaim_csa(regs[REG_UPCXI]); + CURRENT_REGS = (uintptr_t *)regs[REG_D9]; + } + break; + + case SYS_switch_context: + { + *(uintptr_t **)regs[REG_D9] = (uintptr_t *)regs[REG_UPCXI]; + CURRENT_REGS = (uintptr_t *)regs[REG_D10]; + } + break; + + default: + { + svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]); + } + break; + } + + if (regs != CURRENT_REGS) + { + /* Record the new "running" task when context switch occurred. + * g_running_tasks[] is only used by assertion logic for reporting + * crashes. + */ + + g_running_tasks[this_cpu()] = this_task(); + + regs[REG_UPCXI] = (uintptr_t)CURRENT_REGS; + + __isync(); + } + + CURRENT_REGS = NULL; +} diff --git a/arch/tricore/src/common/tricore_switchcontext.c b/arch/tricore/src/common/tricore_switchcontext.c new file mode 100644 index 0000000000..1f195bda72 --- /dev/null +++ b/arch/tricore/src/common/tricore_switchcontext.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_switchcontext.c + * + * 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 +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_switch_context + * + * Description: + * A task is currently in the ready-to-run list but has been prepped + * to execute. Restore its context, and start execution. + * + * Input Parameters: + * tcb: Refers to the head task of the ready-to-run list + * which will be executed. + * rtcb: Refers to the running task which will be blocked. + * + ****************************************************************************/ + +void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb) +{ + /* Update scheduler parameters */ + + nxsched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + tricore_savecontext(rtcb->xcp.regs); + + /* Update scheduler parameters */ + + nxsched_resume_scheduler(tcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + tricore_restorecontext(tcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Update scheduler parameters */ + + nxsched_resume_scheduler(tcb); + + /* Then switch contexts */ + + tricore_switchcontext(&rtcb->xcp.regs, tcb->xcp.regs); + + /* tricore_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } +} diff --git a/arch/tricore/src/common/tricore_systimer.c b/arch/tricore/src/common/tricore_systimer.c new file mode 100644 index 0000000000..5547a84f5e --- /dev/null +++ b/arch/tricore/src/common/tricore_systimer.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_systimer.c + * + * 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 + +#include +#include + +#include "tricore_internal.h" + +#include "IfxStm.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * oneshot_lowerhalf_s structure. + */ + +struct tricore_systimer_lowerhalf_s +{ + struct oneshot_lowerhalf_s lower; + void *tbase; + uint64_t freq; + uint64_t alarm; + oneshot_callback_t callback; + void *arg; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int tricore_systimer_max_delay(struct oneshot_lowerhalf_s *lower, + struct timespec *ts); +static int tricore_systimer_start(struct oneshot_lowerhalf_s *lower, + oneshot_callback_t callback, void *arg, + const struct timespec *ts); +static int tricore_systimer_cancel(struct oneshot_lowerhalf_s *lower, + struct timespec *ts); +static int tricore_systimer_current(struct oneshot_lowerhalf_s *lower, + struct timespec *ts); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct oneshot_operations_s g_tricore_systimer_ops = +{ + .max_delay = tricore_systimer_max_delay, + .start = tricore_systimer_start, + .cancel = tricore_systimer_cancel, + .current = tricore_systimer_current, +}; + +static struct tricore_systimer_lowerhalf_s g_systimer_lower = +{ + .lower.ops = &g_tricore_systimer_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static uint64_t +tricore_systimer_get_time(struct tricore_systimer_lowerhalf_s *priv) +{ + irqstate_t flags; + uint64_t ticks; + + flags = enter_critical_section(); + + ticks = IfxStm_get(priv->tbase); + + leave_critical_section(flags); + + return ticks; +} + +static void +tricore_systimer_set_timecmp(struct tricore_systimer_lowerhalf_s *priv, + uint64_t value) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + IfxStm_updateCompare(priv->tbase, IfxStm_Comparator_0, value); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: tricore_systimer_max_delay + * + * Description: + * Determine the maximum delay of the one-shot timer + * + * Input Parameters: + * lower An instance of the lower-half oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * ts The location in which to return the maximum delay. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int tricore_systimer_max_delay(struct oneshot_lowerhalf_s *lower, + struct timespec *ts) +{ + ts->tv_sec = UINT32_MAX; + ts->tv_nsec = NSEC_PER_SEC - 1; + + return 0; +} + +/**************************************************************************** + * Name: tricore_systimer_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * lower An instance of the lower-half oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int tricore_systimer_start(struct oneshot_lowerhalf_s *lower, + oneshot_callback_t callback, void *arg, + const struct timespec *ts) +{ + struct tricore_systimer_lowerhalf_s *priv = + (struct tricore_systimer_lowerhalf_s *)lower; + uint64_t mtime = tricore_systimer_get_time(priv); + + priv->alarm = mtime + ts->tv_sec * priv->freq + + ts->tv_nsec * priv->freq / NSEC_PER_SEC; + if (priv->alarm < mtime) + { + priv->alarm = UINT64_MAX; + } + + priv->callback = callback; + priv->arg = arg; + + tricore_systimer_set_timecmp(priv, priv->alarm); + return 0; +} + +/**************************************************************************** + * Name: tricore_systimer_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * lower Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +static int tricore_systimer_cancel(struct oneshot_lowerhalf_s *lower, + struct timespec *ts) +{ + struct tricore_systimer_lowerhalf_s *priv = + (struct tricore_systimer_lowerhalf_s *)lower; + uint64_t mtime; + + tricore_systimer_set_timecmp(priv, UINT64_MAX); + + mtime = tricore_systimer_get_time(priv); + if (priv->alarm > mtime) + { + uint64_t nsec = (priv->alarm - mtime) * + NSEC_PER_SEC / priv->freq; + + ts->tv_sec = nsec / NSEC_PER_SEC; + ts->tv_nsec = nsec % NSEC_PER_SEC; + } + else + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + + priv->alarm = 0; + priv->callback = NULL; + priv->arg = NULL; + + return 0; +} + +/**************************************************************************** + * Name: tricore_systimer_current + * + * Description: + * Get the current time. + * + * Input Parameters: + * lower Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * ts The location in which to return the current time. A time of zero + * is returned for the initialization moment. + * + * Returned Value: + * Zero (OK) is returned on success, a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +static int tricore_systimer_current(struct oneshot_lowerhalf_s *lower, + struct timespec *ts) +{ + struct tricore_systimer_lowerhalf_s *priv = + (struct tricore_systimer_lowerhalf_s *)lower; + uint64_t mtime = tricore_systimer_get_time(priv); + uint64_t nsec = mtime / (priv->freq / USEC_PER_SEC) * NSEC_PER_USEC; + + ts->tv_sec = nsec / NSEC_PER_SEC; + ts->tv_nsec = nsec % NSEC_PER_SEC; + + return 0; +} + +/**************************************************************************** + * Name: tricore_systimer_interrupt + * + * Description: + * This function is software interrupt handler to proceed + * the system timer interrupt. + * + ****************************************************************************/ + +static int tricore_systimer_interrupt(int irq, void *context, void *arg) +{ + struct tricore_systimer_lowerhalf_s *priv = arg; + + tricore_systimer_set_timecmp(priv, UINT64_MAX); + if (priv->callback != NULL) + { + priv->callback(&priv->lower, priv->arg); + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_systimer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +struct oneshot_lowerhalf_s * +tricore_systimer_initialize(void *tbase, int irq, uint64_t freq) +{ + struct tricore_systimer_lowerhalf_s *priv = &g_systimer_lower; + + priv->tbase = tbase; + priv->freq = freq; + + IfxStm_setCompareControl(tbase, + IfxStm_Comparator_0, + IfxStm_ComparatorOffset_0, + IfxStm_ComparatorSize_32Bits, + IfxStm_ComparatorInterrupt_ir0); + + IfxStm_clearCompareFlag(tbase, IfxStm_Comparator_0); + tricore_systimer_set_timecmp(priv, UINT64_MAX); + IfxStm_enableComparatorInterrupt(tbase, IfxStm_Comparator_0); + + irq_attach(irq, tricore_systimer_interrupt, priv); + up_enable_irq(irq); + + return (struct oneshot_lowerhalf_s *)priv; +} diff --git a/arch/tricore/src/common/tricore_tcbinfo.c b/arch/tricore/src/common/tricore_tcbinfo.c new file mode 100644 index 0000000000..15d9fd6e76 --- /dev/null +++ b/arch/tricore/src/common/tricore_tcbinfo.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_tcbinfo.c + * + * 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 +#include +#include + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint16_t g_reg_offs[1]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct tcbinfo_s g_tcbinfo used_data = +{ + .pid_off = TCB_PID_OFF, + .state_off = TCB_STATE_OFF, + .pri_off = TCB_PRI_OFF, + .name_off = TCB_NAME_OFF, + .stack_off = TCB_STACK_OFF, + .stack_size_off = TCB_STACK_SIZE_OFF, + .regs_off = TCB_REGS_OFF, + .regs_num = nitems(g_reg_offs), + { + .p = g_reg_offs, + }, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/tricore/src/common/tricore_trapcall.c b/arch/tricore/src/common/tricore_trapcall.c new file mode 100644 index 0000000000..88fa318543 --- /dev/null +++ b/arch/tricore/src/common/tricore_trapcall.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_trapcall.c + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#include "tricore_internal.h" + +#include "IfxCpu_Trap.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tricore_trapcall + * + * Description: + * This is Trap exception handler + * + ****************************************************************************/ + +void tricore_trapcall(volatile void *trap) +{ + uintptr_t *regs; + + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + + CURRENT_REGS = regs; + + up_irq_save(); + PANIC_WITH_REGS("Trap", CURRENT_REGS); +} diff --git a/arch/tricore/src/common/tricore_usestack.c b/arch/tricore/src/common/tricore_usestack.c new file mode 100644 index 0000000000..5952fbf611 --- /dev/null +++ b/arch/tricore/src/common/tricore_usestack.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/tricore/src/common/tricore_usestack.c + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from nxtask_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. + * + * Input Parameters: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + uintptr_t top_of_stack; + size_t size_of_stack; + +#ifdef CONFIG_TLS_ALIGNED + /* Make certain that the user provided stack is properly aligned */ + + DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0); +#endif + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* RISC-V uses a push-down stack: the stack grows toward lower addresses in + * memory. The stack pointer register, points to the lowest, valid work + * address (the "top" of the stack). Items on the stack are referenced + * as positive word offsets from SP. + */ + + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + + /* The RISC-V stack must be aligned at 128-bit (16-byte) boundaries. + * If necessary top_of_stack must be rounded down to the next boundary. + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = size_of_stack; + +#if defined(CONFIG_STACK_COLORATION) + /* If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + + tricore_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); +#endif + + return OK; +} diff --git a/arch/tricore/src/tc3xx/.gitignore b/arch/tricore/src/tc3xx/.gitignore new file mode 100644 index 0000000000..6e279e3dd9 --- /dev/null +++ b/arch/tricore/src/tc3xx/.gitignore @@ -0,0 +1,3 @@ +/*_unpack +/tc397 +/*tar.gz diff --git a/arch/tricore/src/tc3xx/Kconfig b/arch/tricore/src/tc3xx/Kconfig new file mode 100644 index 0000000000..1c3f45744d --- /dev/null +++ b/arch/tricore/src/tc3xx/Kconfig @@ -0,0 +1,18 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "TC3XX Configuration Options" + +menu "TC3XX Peripheral Support" + +# These are the peripheral selections proper + +config TC3XX_UART0 + bool "TC3XX UART0" + default y + select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +endmenu diff --git a/arch/tricore/src/tc3xx/Make.defs b/arch/tricore/src/tc3xx/Make.defs new file mode 100644 index 0000000000..81ae83f6df --- /dev/null +++ b/arch/tricore/src/tc3xx/Make.defs @@ -0,0 +1,62 @@ +############################################################################ +# arch/tricore/src/tc3xx/Make.defs +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_ARCH_CHIP_TC397),y) + -include tc3xx/tc397/Make.defs +endif + +CHIP_CSRCS += tc3xx_timerisr.c +CHIP_CSRCS += tc3xx_serial.c + +VPATH += tc3xx + +tc3xx_libc$(OBJEXT): tc3xx_libc.c + $(call COMPILE, $<, $@) + +libc_fpu$(LIBEXT): tc3xx_libc$(OBJEXT) + $(call ARCHIVE, $@, $<) + +EXTRA_LIBS += libc_fpu$(LIBEXT) +LIBPATHS += $(CURDIR) + +TC397_UNPACK = tc397 +TC397_COMMIT = master +TC397_URL = https://github.com/anchao/tc397_sdk/archive/refs/heads +TC397_TARBALL = tc3xx/$(TC397_UNPACK).tar.gz +TC397_DIR = tc397_sdk-master + +$(TC397_TARBALL): + $(call DOWNLOAD,$(TC397_URL),$(TC397_COMMIT).tar.gz,$(TC397_TARBALL)) + +tc3xx/.tc397_unpack: $(TC397_TARBALL) + $(Q) echo "Unpacking: TC397" + $(Q) tar xzf $(TC397_TARBALL) -C tc3xx + $(Q) mv tc3xx/$(TC397_DIR) tc3xx/$(TC397_UNPACK) + $(Q) touch tc3xx/.tc397_unpack + + +ifeq ($(wildcard tc3xx/$(TC397_UNPACK)/.git),) +context:: .tc397_unpack + +distclean:: + $(call DELFILE, tc3xx/.tc397_unpack) + $(call DELFILE, $(TC397_TARBALL)) + $(call DELDIR, tc3xx/$(TC397_UNPACK)) +endif diff --git a/arch/tricore/src/tc3xx/Toolchain.defs b/arch/tricore/src/tc3xx/Toolchain.defs new file mode 100644 index 0000000000..6b709b738f --- /dev/null +++ b/arch/tricore/src/tc3xx/Toolchain.defs @@ -0,0 +1,26 @@ +############################################################################ +# arch/tricore/src/tc3xx/Toolchain.defs +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_ARCH_CHIP_TC397),y) + ARCHOPTIMIZATION += --cpu=tc39xb + LDFLAGS += -Ctc39xb +endif + +include $(TOPDIR)/arch/tricore/src/common/Toolchain.defs diff --git a/arch/tricore/src/tc3xx/chip.h b/arch/tricore/src/tc3xx/chip.h new file mode 100644 index 0000000000..b190de4512 --- /dev/null +++ b/arch/tricore/src/tc3xx/chip.h @@ -0,0 +1,28 @@ +/**************************************************************************** + * arch/tricore/src/tc3xx/chip.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_TRICORE_SRC_TC3XX_CHIP_H +#define __ARCH_TRICORE_SRC_TC3XX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#endif /* __ARCH_TRICORE_SRC_TC3XX_CHIP_H */ diff --git a/arch/tricore/src/tc3xx/tc3xx_libc.c b/arch/tricore/src/tc3xx/tc3xx_libc.c new file mode 100644 index 0000000000..177f8ab474 --- /dev/null +++ b/arch/tricore/src/tc3xx/tc3xx_libc.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/tricore/src/tc3xx/tc3xx_libc.c + * + * 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 + +#include "tricore_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* TODO: + * The data copy from flash to ram reuses the implementation in tricore sdk. + * The next update will reimplement _c_init() to abandon the copy code. + * + * Usage: ltc [options] files + * -i --user-provided-initialization-code + * + * the user provides his own initialization + * routine, do not emit the copytable + * + * void _c_init(void) + * { + * } + */ + +/* The implementation of libc is introduced by default in the Tricore + * toolchain, in nuttx we made a fake libc_fpu.a library to bypass + * this issue, but the linker will still generate markup code, + * add a few definitions to fool the linker. + */ + +void __printf_float(void) +{ +} + +void __printf_int(void) +{ +} + +void __printf_llong(void) +{ +} + +void _main(void) +{ +} + +void _doexit(void) +{ +} + +/* BUG, Workaroud for tasking compiler: + * + * ltc E106: unresolved external: regulator_gpio_init - + * (drivers_initialize.o) + * ltc F019: unrecoverable error: fatal link error + * + */ + +int regulator_gpio_init(void *iodev, void *desc) +{ + return 0; +} diff --git a/arch/tricore/src/tc3xx/tc3xx_serial.c b/arch/tricore/src/tc3xx/tc3xx_serial.c new file mode 100644 index 0000000000..cf6e87bbfc --- /dev/null +++ b/arch/tricore/src/tc3xx/tc3xx_serial.c @@ -0,0 +1,741 @@ +/**************************************************************************** + * arch/tricore/src/tc3xx/tc3xx_serial.c + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "tricore_internal.h" + +#include "Asclin/Asc/IfxAsclin_Asc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_TC3XX_UART0) +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define SERIAL_CONSOLE 1 +# else +# error "I'm confused... Do we have a serial console or not?" +# endif +#else +# undef CONSOLE_DEV /* No console */ +# undef CONFIG_UART0_SERIAL_CONSOLE +# if defined(CONFIG_TC3XX_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define SERIAL_CONSOLE 1 +# else +# undef TTYS0_DEV +# endif +#endif + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_TC3XX_UART0) +# define HAVE_UART_DEVICE 1 +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of tricore_earlyserialinit(), + * tricore_serialinit(), and up_putc(). + */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + void *uartbase; /* Base address of UART registers */ + void *pins; /* Pin configuration */ + uint32_t baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this UART */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Serial driver methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context, void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_TC3XX_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_TC3XX_UART0 + +#define UART_PIN_RX IfxAsclin0_RXA_P14_1_IN /* UART receive port pin */ +#define UART_PIN_TX IfxAsclin0_TX_P14_0_OUT /* UART transmit port pin */ + +/* Pin configuration */ + +static const IfxAsclin_Asc_Pins g_uart0_pins = +{ + NULL, IfxPort_InputMode_pullUp, /* CTS pin not used */ + &UART_PIN_RX, IfxPort_InputMode_pullUp, /* RX pin */ + NULL, IfxPort_OutputMode_pushPull, /* RTS pin not used */ + &UART_PIN_TX, IfxPort_OutputMode_pushPull, /* TX pin */ + IfxPort_PadDriver_cmosAutomotiveSpeed1 +}; + +static struct up_dev_s g_uart0priv = +{ + .uartbase = &MODULE_ASCLIN0, + .pins = &g_uart0_pins, + .baud = CONFIG_UART0_BAUD, + .irq = 21, +}; + +static uart_dev_t g_uart0port = +{ +#if SERIAL_CONSOLE == 1 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: asclin_init + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static void asclin_init(struct up_dev_s *priv) +{ + Ifx_ASCLIN *asclin = priv->uartbase; + const IfxAsclin_Asc_Pins *pins = priv->pins; + + /* enabling the module */ + + IfxAsclin_enableModule(asclin); + + /* disabling the clock */ + + IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_noClock); + + /* setting the module in Initialise mode */ + + IfxAsclin_setFrameMode(asclin, IfxAsclin_FrameMode_initialise); + + /* sets the prescaler */ + + IfxAsclin_setPrescaler(asclin, 1); + + /* temporary set the clock source for baudrate configuration */ + + IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_ascFastClock); + + /* setting the baudrate bit fields to generate the required baudrate */ + + IfxAsclin_setBitTiming(asclin, priv->baud, + IfxAsclin_OversamplingFactor_16, + IfxAsclin_SamplePointPosition_8, + IfxAsclin_SamplesPerBit_three); + + /* disabling the clock again */ + + IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_noClock); + + /* selecting the loopback mode */ + + IfxAsclin_enableLoopBackMode(asclin, false); + + /* setting parity enable */ + + IfxAsclin_enableParity(asclin, false); + + /* setting parity type (odd/even) */ + + IfxAsclin_setParityType(asclin, IfxAsclin_ParityType_even); + + /* setting the stop bit */ + + IfxAsclin_setStopBit(asclin, IfxAsclin_StopBit_1); + + /* setting the shift direction */ + + IfxAsclin_setShiftDirection(asclin, + IfxAsclin_ShiftDirection_lsbFirst); + + /* setting the data length */ + + IfxAsclin_setDataLength(asclin, IfxAsclin_DataLength_8); + + /* setting Tx FIFO inlet width */ + + IfxAsclin_setTxFifoInletWidth(asclin, + IfxAsclin_TxFifoInletWidth_1); + + /* setting Rx FIFO outlet width */ + + IfxAsclin_setRxFifoOutletWidth(asclin, + IfxAsclin_RxFifoOutletWidth_1); + + /* setting idle delay */ + + IfxAsclin_setIdleDelay(asclin, IfxAsclin_IdleDelay_0); + + /* setting Tx FIFO level at which a Tx interrupt will be triggered */ + + IfxAsclin_setTxFifoInterruptLevel(asclin, + IfxAsclin_TxFifoInterruptLevel_0); + + /* setting Rx FIFO interrupt level at which a Rx + * interrupt will be triggered + */ + + IfxAsclin_setRxFifoInterruptLevel(asclin, + IfxAsclin_RxFifoInterruptLevel_1); + + /* setting Tx FIFO interrupt generation mode */ + + IfxAsclin_setTxFifoInterruptMode(asclin, + IfxAsclin_FifoInterruptMode_combined); + + /* setting Rx FIFO interrupt generation mode */ + + IfxAsclin_setRxFifoInterruptMode(asclin, + IfxAsclin_FifoInterruptMode_combined); + + /* selecting the frame mode */ + + IfxAsclin_setFrameMode(asclin, IfxAsclin_FrameMode_asc); + + /* Pin mapping */ + + if (pins != NULL) + { + IfxAsclin_Cts_In *cts = pins->cts; + + if (cts != NULL) + { + IfxAsclin_initCtsPin(cts, pins->ctsMode, pins->pinDriver); + } + + IfxAsclin_Rx_In *rx = pins->rx; + + if (rx != NULL) + { + IfxAsclin_initRxPin(rx, pins->rxMode, pins->pinDriver); + } + + IfxAsclin_Rts_Out *rts = pins->rts; + + if (rts != NULL) + { + IfxAsclin_initRtsPin(rts, pins->rtsMode, pins->pinDriver); + } + + IfxAsclin_Tx_Out *tx = pins->tx; + + if (tx != NULL) + { + IfxAsclin_initTxPin(tx, pins->txMode, pins->pinDriver); + } + } + + /* select the clock source */ + + IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_ascFastClock); + + /* disable all flags */ + + IfxAsclin_disableAllFlags(asclin); + + /* clear all flags */ + + IfxAsclin_clearAllFlags(asclin); + + /* HW error flags */ + + IfxAsclin_enableParityErrorFlag(asclin, true); + IfxAsclin_enableFrameErrorFlag(asclin, true); + IfxAsclin_enableRxFifoOverflowFlag(asclin, true); + IfxAsclin_enableRxFifoUnderflowFlag(asclin, true); + IfxAsclin_enableTxFifoOverflowFlag(asclin, true); + + /* enable transfers */ + + IfxAsclin_enableRxFifoInlet(asclin, true); + IfxAsclin_enableTxFifoOutlet(asclin, true); + + IfxAsclin_flushRxFifo(asclin); + IfxAsclin_flushTxFifo(asclin); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + asclin_init(dev->priv); + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + int ret; + + /* Initialize interrupt generation on the peripheral */ + + ret = irq_attach(priv->irq, up_interrupt, dev); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt is received on the 'irq'. It should call uart_xmitchars or + * uart_recvchars to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'arg' to the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context, void *arg) +{ + struct uart_dev_s *dev = arg; + + if (up_rxavailable(dev)) + { + uart_recvchars(dev); + } + + if (up_txready(dev)) + { + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = dev->priv; + + return IfxAsclin_readRxData(priv->uartbase); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = dev->priv; + irqstate_t flags = enter_critical_section(); + + IfxAsclin_enableRxFifoFillLevelFlag(priv->uartbase, enable); + IfxAsclin_enableRxFifoInlet(priv->uartbase, enable); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + + return IfxAsclin_getRxFifoFillLevel(priv->uartbase) > 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = dev->priv; + + /* Wait for FIFO */ + + if (dev == &CONSOLE_DEV) + { + up_putc(ch); + return; + } + + while (IfxAsclin_getTxFifoFillLevel(priv->uartbase) != 0); + + IfxAsclin_clearAllFlags(priv->uartbase); + IfxAsclin_writeTxData(priv->uartbase, ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + if (enable) + { + /* Enable the TX interrupt */ + + uart_xmitchars(dev); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + return true; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + + /* Return true if the TX wartermak is pending */ + + return IfxAsclin_getTxFifoFillLevel(priv->uartbase) != 0; +} + +/**************************************************************************** + * Name: tricore_lowputc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +void tricore_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = CONSOLE_DEV.priv; + + /* Wait for FIFO */ + + while (IfxAsclin_getTxFifoFillLevel(priv->uartbase) != 0); + + IfxAsclin_clearAllFlags(priv->uartbase); + IfxAsclin_writeTxData(priv->uartbase, ch); +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: tricore_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before tricore_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock + * initialization performed in up_clkinitialize(). + * + ****************************************************************************/ + +void tricore_earlyserialinit(void) +{ + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: tricore_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that tricore_earlyserialinit was called previously. + * + ****************************************************************************/ + +void tricore_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + uart_register("/dev/ttyS0", &TTYS0_DEV); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + tricore_lowputc('\r'); + } + + tricore_lowputc(ch); +#endif + return ch; +} +#endif /* USE_SERIALDRIVER */ diff --git a/arch/tricore/src/tc3xx/tc3xx_timerisr.c b/arch/tricore/src/tc3xx/tc3xx_timerisr.c new file mode 100644 index 0000000000..4fcab8b5b2 --- /dev/null +++ b/arch/tricore/src/tc3xx/tc3xx_timerisr.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/tricore/src/tc3xx/tc3xx_timerisr.c + * + * 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 + +#include +#include + +#include "tricore_internal.h" + +#include "IfxStm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SCU_FREQUENCY 100000000UL + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + struct oneshot_lowerhalf_s *lower; + + lower = tricore_systimer_initialize(&MODULE_STM0, 192, SCU_FREQUENCY); + + DEBUGASSERT(lower != NULL); + + up_alarm_set_lowerhalf(lower); +} diff --git a/boards/Kconfig b/boards/Kconfig index 1af977a691..bedb93ad4e 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -2040,6 +2040,12 @@ config ARCH_BOARD_SABRE_6QUAD This options selects support for NuttX on the NXP/Freescale Sabre board featuring the iMX 6Quad CPU. +config ARCH_BOARD_TC397 + bool "Infineon's AURIX TC397 board: KIT_A2G_TC397_5V_TFT" + ---help--- + This options selects support for NuttX on the Infineon's AURIX board + board featuring the TC397 6Quad CPU. + config ARCH_BOARD_QEMU_ARMV7A bool "Qemu ARMv7a CPUs board" depends on ARCH_CHIP_QEMU_ARM @@ -3284,6 +3290,7 @@ config ARCH_BOARD default "canmv230" if ARCH_BOARD_K230_CANMV default "ox64" if ARCH_BOARD_BL808_OX64 default "sabre-6quad" if ARCH_BOARD_SABRE_6QUAD + default "tc397" if ARCH_BOARD_TC397 default "qemu-armv7a" if ARCH_BOARD_QEMU_ARMV7A default "qemu-armv8a" if ARCH_BOARD_QEMU_ARMV8A default "pinephone" if ARCH_BOARD_PINEPHONE @@ -3486,6 +3493,9 @@ endif if ARCH_BOARD_SABRE_6QUAD source "boards/arm/imx6/sabre-6quad/Kconfig" endif +if ARCH_BOARD_TC397 +source "boards/tricore/tc3xx/tc397/Kconfig" +endif if ARCH_BOARD_QEMU_ARMV7A source "boards/arm/qemu/qemu-armv7a/Kconfig" endif diff --git a/boards/tricore/tc3xx/tc397/Kconfig b/boards/tricore/tc3xx/tc397/Kconfig new file mode 100644 index 0000000000..b262f16c87 --- /dev/null +++ b/boards/tricore/tc3xx/tc397/Kconfig @@ -0,0 +1,7 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_TC397 +endif diff --git a/boards/tricore/tc3xx/tc397/configs/nsh/defconfig b/boards/tricore/tc3xx/tc397/configs/nsh/defconfig new file mode 100644 index 0000000000..f2bef67c2f --- /dev/null +++ b/boards/tricore/tc3xx/tc397/configs/nsh/defconfig @@ -0,0 +1,54 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="tricore" +CONFIG_ARCH_BOARD="tc397" +CONFIG_ARCH_BOARD_TC397=y +CONFIG_ARCH_CHIP="tc3xx" +CONFIG_ARCH_CHIP_TC397=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_TRICORE=y +CONFIG_BOARD_LOOPSPERMSEC=99369 +CONFIG_BOOT_RUNFROMSDRAM=y +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEV_ZERO=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXPERIMENTAL=y +CONFIG_FS_PROCFS=y +CONFIG_FS_TMPFS=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_LIBC_MEMFD_ERROR=y +CONFIG_NDEBUG=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x70000000 +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_MONTH=3 +CONFIG_START_YEAR=2016 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSLOG_BUFFER=y +CONFIG_SYSLOG_DEVPATH="/dev/ttyS0" +CONFIG_SYSLOG_INTBUFFER=y +CONFIG_SYSLOG_MAX_CHANNELS=2 +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/tricore/tc3xx/tc397/include/board.h b/boards/tricore/tc3xx/tc397/include/board.h new file mode 100644 index 0000000000..0100cc08f8 --- /dev/null +++ b/boards/tricore/tc3xx/tc397/include/board.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/include/board.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __BOARDS_TRICORE_TC3XX_TC397_INCLUDE_BOARD_H +#define __BOARDS_TRICORE_TC3XX_TC397_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +#endif /* __BOARDS_TRICORE_TC3XX_TC397_INCLUDE_BOARD_H */ diff --git a/boards/tricore/tc3xx/tc397/include/board_memorymap.h b/boards/tricore/tc3xx/tc397/include/board_memorymap.h new file mode 100644 index 0000000000..16c40b3653 --- /dev/null +++ b/boards/tricore/tc3xx/tc397/include/board_memorymap.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/include/board_memorymap.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __BOARDS_TRICORE_TC3XX_TC397_INCLUDE_BOARD_MEMORYMAP_H +#define __BOARDS_TRICORE_TC3XX_TC397_INCLUDE_BOARD_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_TRICORE_TC3XX_TC397_INCLUDE_BOARD_MEMORYMAP_H */ diff --git a/boards/tricore/tc3xx/tc397/scripts/Lcf_Tasking_Tricore_Tc.lsl b/boards/tricore/tc3xx/tc397/scripts/Lcf_Tasking_Tricore_Tc.lsl new file mode 100644 index 0000000000..22da9c0779 --- /dev/null +++ b/boards/tricore/tc3xx/tc397/scripts/Lcf_Tasking_Tricore_Tc.lsl @@ -0,0 +1,1476 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/scripts/Lcf_Tasking_Tricore_Tc.lsl + * + * 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. + * + ****************************************************************************/ + +#include "../../../include/nuttx/config.h" + +#define LCF_CSA0_SIZE 40k +#define LCF_USTACK0_SIZE CONFIG_IDLETHREAD_STACKSIZE +#define LCF_ISTACK0_SIZE CONFIG_ARCH_INTERRUPTSTACK + +#define LCF_CSA1_SIZE 40k +#define LCF_USTACK1_SIZE CONFIG_IDLETHREAD_STACKSIZE +#define LCF_ISTACK1_SIZE CONFIG_ARCH_INTERRUPTSTACK + +#define LCF_CSA2_SIZE 40k +#define LCF_USTACK2_SIZE CONFIG_IDLETHREAD_STACKSIZE +#define LCF_ISTACK2_SIZE CONFIG_ARCH_INTERRUPTSTACK + +#define LCF_CSA3_SIZE 40k +#define LCF_USTACK3_SIZE CONFIG_IDLETHREAD_STACKSIZE +#define LCF_ISTACK3_SIZE CONFIG_ARCH_INTERRUPTSTACK + +#define LCF_CSA4_SIZE 40k +#define LCF_USTACK4_SIZE CONFIG_IDLETHREAD_STACKSIZE +#define LCF_ISTACK4_SIZE CONFIG_ARCH_INTERRUPTSTACK + +#define LCF_CSA5_SIZE 40k +#define LCF_USTACK5_SIZE CONFIG_IDLETHREAD_STACKSIZE +#define LCF_ISTACK5_SIZE CONFIG_ARCH_INTERRUPTSTACK + +#define LCF_HEAP_SIZE 4k + +#define LCF_CPU0 0 +#define LCF_CPU1 1 +#define LCF_CPU2 2 +#define LCF_CPU3 3 +#define LCF_CPU4 4 +#define LCF_CPU5 5 + + +/*Un comment one of the below statements to enable CpuX DMI RAM to hold global variables*/ +#define LCF_DEFAULT_HOST LCF_CPU0 +/*#define LCF_DEFAULT_HOST LCF_CPU1*/ +/*#define LCF_DEFAULT_HOST LCF_CPU2*/ +/*#define LCF_DEFAULT_HOST LCF_CPU3*/ +/*#define LCF_DEFAULT_HOST LCF_CPU4*/ +/*#define LCF_DEFAULT_HOST LCF_CPU5*/ + +#define LCF_DSPR5_START 0x10000000 +#define LCF_DSPR5_SIZE 96k + +#define LCF_DSPR4_START 0x30000000 +#define LCF_DSPR4_SIZE 96k + +#define LCF_DSPR3_START 0x40000000 +#define LCF_DSPR3_SIZE 96k + +#define LCF_DSPR2_START 0x50000000 +#define LCF_DSPR2_SIZE 96k + +#define LCF_DSPR1_START 0x60000000 +#define LCF_DSPR1_SIZE 240k + +#define LCF_DSPR0_START 0x70000000 +#define LCF_DSPR0_SIZE 240k + +#define LCF_CSA5_OFFSET (LCF_DSPR5_SIZE - 1k - LCF_CSA5_SIZE) +#define LCF_ISTACK5_OFFSET (LCF_CSA5_OFFSET - 256 - LCF_ISTACK5_SIZE) +#define LCF_USTACK5_OFFSET (LCF_ISTACK5_OFFSET - 256 - LCF_USTACK5_SIZE) + +#define LCF_CSA4_OFFSET (LCF_DSPR4_SIZE - 1k - LCF_CSA4_SIZE) +#define LCF_ISTACK4_OFFSET (LCF_CSA4_OFFSET - 256 - LCF_ISTACK4_SIZE) +#define LCF_USTACK4_OFFSET (LCF_ISTACK4_OFFSET - 256 - LCF_USTACK4_SIZE) + +#define LCF_CSA3_OFFSET (LCF_DSPR3_SIZE - 1k - LCF_CSA3_SIZE) +#define LCF_ISTACK3_OFFSET (LCF_CSA3_OFFSET - 256 - LCF_ISTACK3_SIZE) +#define LCF_USTACK3_OFFSET (LCF_ISTACK3_OFFSET - 256 - LCF_USTACK3_SIZE) + +#define LCF_CSA2_OFFSET (LCF_DSPR2_SIZE - 1k - LCF_CSA2_SIZE) +#define LCF_ISTACK2_OFFSET (LCF_CSA2_OFFSET - 256 - LCF_ISTACK2_SIZE) +#define LCF_USTACK2_OFFSET (LCF_ISTACK2_OFFSET - 256 - LCF_USTACK2_SIZE) + +#define LCF_CSA1_OFFSET (LCF_DSPR1_SIZE - 1k - LCF_CSA1_SIZE) +#define LCF_ISTACK1_OFFSET (LCF_CSA1_OFFSET - 256 - LCF_ISTACK1_SIZE) +#define LCF_USTACK1_OFFSET (LCF_ISTACK1_OFFSET - 256 - LCF_USTACK1_SIZE) + +#define LCF_CSA0_OFFSET (LCF_DSPR0_SIZE - 1k - LCF_CSA0_SIZE) +#define LCF_ISTACK0_OFFSET (LCF_CSA0_OFFSET - 256 - LCF_ISTACK0_SIZE) +#define LCF_USTACK0_OFFSET (LCF_ISTACK0_OFFSET - 256 - LCF_USTACK0_SIZE) + +#define LCF_HEAP0_OFFSET (LCF_USTACK0_OFFSET - LCF_HEAP_SIZE) +#define LCF_HEAP1_OFFSET (LCF_USTACK1_OFFSET - LCF_HEAP_SIZE) +#define LCF_HEAP2_OFFSET (LCF_USTACK2_OFFSET - LCF_HEAP_SIZE) +#define LCF_HEAP3_OFFSET (LCF_USTACK3_OFFSET - LCF_HEAP_SIZE) +#define LCF_HEAP4_OFFSET (LCF_USTACK4_OFFSET - LCF_HEAP_SIZE) +#define LCF_HEAP5_OFFSET (LCF_USTACK5_OFFSET - LCF_HEAP_SIZE) + +#define LCF_INTVEC0_START 0x802FE000 +#define LCF_INTVEC1_START 0x805FE000 +#define LCF_INTVEC2_START 0x808FE000 +#define LCF_INTVEC3_START 0x80BFE000 +#define LCF_INTVEC4_START 0x80EFE000 +#define LCF_INTVEC5_START 0x80FFE000 + +#define LCF_TRAPVEC0_START 0x80000100 +#define LCF_TRAPVEC1_START 0x80300000 +#define LCF_TRAPVEC2_START 0x80600000 +#define LCF_TRAPVEC3_START 0x80900000 +#define LCF_TRAPVEC4_START 0x80C00000 +#define LCF_TRAPVEC5_START 0x80F00000 + +#define LCF_STARTPTR_CPU0 0x80000000 +#define LCF_STARTPTR_CPU1 0x80300100 +#define LCF_STARTPTR_CPU2 0x80600100 +#define LCF_STARTPTR_CPU3 0x80900100 +#define LCF_STARTPTR_CPU4 0x80C00100 +#define LCF_STARTPTR_CPU5 0x80F00100 + +#define LCF_STARTPTR_NC_CPU0 0xA0000000 +#define LCF_STARTPTR_NC_CPU1 0xA0300100 +#define LCF_STARTPTR_NC_CPU2 0xA0600100 +#define LCF_STARTPTR_NC_CPU3 0xA0900100 +#define LCF_STARTPTR_NC_CPU4 0xA0C00100 +#define LCF_STARTPTR_NC_CPU5 0xA0F00100 + +#define INTTAB0 (LCF_INTVEC0_START) +#define INTTAB1 (LCF_INTVEC1_START) +#define INTTAB2 (LCF_INTVEC2_START) +#define INTTAB3 (LCF_INTVEC3_START) +#define INTTAB4 (LCF_INTVEC4_START) +#define INTTAB5 (LCF_INTVEC5_START) +#define TRAPTAB0 (LCF_TRAPVEC0_START) +#define TRAPTAB1 (LCF_TRAPVEC1_START) +#define TRAPTAB2 (LCF_TRAPVEC2_START) +#define TRAPTAB3 (LCF_TRAPVEC3_START) +#define TRAPTAB4 (LCF_TRAPVEC4_START) +#define TRAPTAB5 (LCF_TRAPVEC5_START) + +#define RESET LCF_STARTPTR_NC_CPU0 + +#include "tc1v1_6_2.lsl" + +// Specify a multi-core processor environment (mpe) + +processor mpe +{ + derivative = tc39; +} + +derivative tc39 +{ + core tc0 + { + architecture = TC1V1.6.2; + space_id_offset = 100; // add 100 to all space IDs in the architecture definition + copytable_space = vtc:linear; // use the copy table in the virtual core for 'bss' and initialized data sections + } + + core tc1 // core 1 TC16E + { + architecture = TC1V1.6.2; + space_id_offset = 200; // add 200 to all space IDs in the architecture definition + copytable_space = vtc:linear; // use the copy table in the virtual core for 'bss' and initialized data sections + } + + core tc2 // core 2 TC16P + { + architecture = TC1V1.6.2; + space_id_offset = 300; // add 300 to all space IDs in the architecture definition + copytable_space = vtc:linear; // use the copy table in the virtual core for 'bss' and initialized data sections + } + + core tc3 // core 3 TC16P + { + architecture = TC1V1.6.2; + space_id_offset = 400; // add 300 to all space IDs in the architecture definition + copytable_space = vtc:linear; // use the copy table in the virtual core for 'bss' and initialized data sections + } + + core tc4 // core 4 TC16P + { + architecture = TC1V1.6.2; + space_id_offset = 500; // add 300 to all space IDs in the architecture definition + copytable_space = vtc:linear; // use the copy table in the virtual core for 'bss' and initialized data sections + } + + core tc5 // core 5 TC16P + { + architecture = TC1V1.6.2; + space_id_offset = 600; // add 300 to all space IDs in the architecture definition + copytable_space = vtc:linear; // use the copy table in the virtual core for 'bss' and initialized data sections + } + + core vtc + { + architecture = TC1V1.6.2; + import tc0; // add all address spaces of core tc0 to core vtc for linking and locating + import tc1; // tc1 + import tc2; // tc2 + import tc3; // tc3 + import tc4; // tc4 + import tc5; // tc5 + } + + bus sri + { + mau = 8; + width = 32; + + // map shared addresses one-to-one to real cores and virtual cores + map (dest=bus:tc0:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + map (dest=bus:tc1:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + map (dest=bus:tc2:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + map (dest=bus:tc3:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + map (dest=bus:tc4:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + map (dest=bus:tc5:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + map (dest=bus:vtc:fpi_bus, src_offset=0, dest_offset=0, size=0xc0000000); + } + + memory dsram5 // Data Scratch Pad Ram + { + mau = 8; + size = 96k; + type = ram; + map (dest=bus:tc5:fpi_bus, dest_offset=0xd0000000, size=96k, priority=8); + map (dest=bus:sri, dest_offset=0x10000000, size=96k); + } + + memory psram5 // Program Scratch Pad Ram + { + mau = 8; + size = 64k; + type = ram; + map (dest=bus:tc5:fpi_bus, dest_offset=0xc0000000, size=64k, priority=8); + map (dest=bus:sri, dest_offset=0x10100000, size=64k); + } + + memory dsram4 // Data Scratch Pad Ram + { + mau = 8; + size = 96k; + type = ram; + map (dest=bus:tc4:fpi_bus, dest_offset=0xd0000000, size=96k, priority=8); + map (dest=bus:sri, dest_offset=0x30000000, size=96k); + } + + memory psram4 // Program Scratch Pad Ram + { + mau = 8; + size = 64k; + type = ram; + map (dest=bus:tc4:fpi_bus, dest_offset=0xc0000000, size=64k, priority=8); + map (dest=bus:sri, dest_offset=0x30100000, size=64k); + } + + memory dsram3 // Data Scratch Pad Ram + { + mau = 8; + size = 96k; + type = ram; + map (dest=bus:tc3:fpi_bus, dest_offset=0xd0000000, size=96k, priority=8); + map (dest=bus:sri, dest_offset=0x40000000, size=96k); + } + + memory psram3 // Program Scratch Pad Ram + { + mau = 8; + size = 64k; + type = ram; + map (dest=bus:tc3:fpi_bus, dest_offset=0xc0000000, size=64k, priority=8); + map (dest=bus:sri, dest_offset=0x40100000, size=64k); + } + + memory dsram2 // Data Scratch Pad Ram + { + mau = 8; + size = 96k; + type = ram; + map (dest=bus:tc2:fpi_bus, dest_offset=0xd0000000, size=96k, priority=8); + map (dest=bus:sri, dest_offset=0x50000000, size=96k); + } + + memory psram2 // Program Scratch Pad Ram + { + mau = 8; + size = 64k; + type = ram; + map (dest=bus:tc2:fpi_bus, dest_offset=0xc0000000, size=64k, priority=8); + map (dest=bus:sri, dest_offset=0x50100000, size=64k); + } + + memory dsram1 // Data Scratch Pad Ram + { + mau = 8; + size = 240k; + type = ram; + map (dest=bus:tc1:fpi_bus, dest_offset=0xd0000000, size=240k, priority=8); + map (dest=bus:sri, dest_offset=0x60000000, size=240k); + } + + memory psram1 // Program Scratch Pad Ram + { + mau = 8; + size = 64k; + type = ram; + map (dest=bus:tc1:fpi_bus, dest_offset=0xc0000000, size=64k, priority=8); + map (dest=bus:sri, dest_offset=0x60100000, size=64k); + } + + memory dsram0 // Data Scratch Pad Ram + { + mau = 8; + size = 240k; + type = ram; + map (dest=bus:tc0:fpi_bus, dest_offset=0xd0000000, size=240k, priority=8); + map (dest=bus:sri, dest_offset=0x70000000, size=240k); + } + + memory psram0 // Program Scratch Pad Ram + { + mau = 8; + size = 64k; + type = ram; + map (dest=bus:tc0:fpi_bus, dest_offset=0xc0000000, size=64k, priority=8); + map (dest=bus:sri, dest_offset=0x70100000, size=64k); + } + + memory pfls0 + { + mau = 8; + size = 3M; + type = rom; + map cached (dest=bus:sri, dest_offset=0x80000000, size=3M); + map not_cached (dest=bus:sri, dest_offset=0xa0000000, reserved, size=3M); + } + + memory pfls1 + { + mau = 8; + size = 3M; + type = rom; + map cached (dest=bus:sri, dest_offset=0x80300000, size=3M); + map not_cached (dest=bus:sri, dest_offset=0xa0300000, reserved, size=3M); + } + + memory pfls2 + { + mau = 8; + size = 3M; + type = rom; + map cached (dest=bus:sri, dest_offset=0x80600000, size=3M); + map not_cached (dest=bus:sri, dest_offset=0xa0600000, reserved, size=3M); + } + + memory pfls3 + { + mau = 8; + size = 3M; + type = rom; + map cached (dest=bus:sri, dest_offset=0x80900000, size=3M); + map not_cached (dest=bus:sri, dest_offset=0xa0900000, reserved, size=3M); + } + + memory pfls4 + { + mau = 8; + size = 3M; + type = rom; + map cached (dest=bus:sri, dest_offset=0x80c00000, size=3M); + map not_cached (dest=bus:sri, dest_offset=0xa0c00000, reserved, size=3M); + } + + memory pfls5 + { + mau = 8; + size = 1M; + type = rom; + map cached (dest=bus:sri, dest_offset=0x80f00000, size=1M); + map not_cached (dest=bus:sri, dest_offset=0xa0f00000, reserved, size=1M); + } + + memory dfls0 + { + mau = 8; + size = 1M; + type = reserved nvram; + map (dest=bus:sri, dest_offset=0xaf000000, size=1M ); + } + + memory ucb + { + mau = 8; + size = 24k; + type = rom; + map (dest=bus:sri, dest_offset=0xaf400000, reserved, size=24k); + } + + memory cpu0_dlmu + { + mau = 8; + size = 64k; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90000000, size=64k); + map not_cached (dest=bus:sri, dest_offset=0xb0000000, reserved, size=64k); + } + + memory cpu1_dlmu + { + mau = 8; + size = 64k; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90010000, size=64k); + map not_cached (dest=bus:sri, dest_offset=0xb0010000, reserved, size=64k); + } + + memory cpu2_dlmu + { + mau = 8; + size = 64k; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90020000, size=64k); + map not_cached (dest=bus:sri, dest_offset=0xb0020000, reserved, size=64k); + } + + memory cpu3_dlmu + { + mau = 8; + size = 64k; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90030000, size=64k); + map not_cached (dest=bus:sri, dest_offset=0xb0030000, reserved, size=64k); + } + + memory lmuram + { + mau = 8; + size = 768K; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90040000, size=768K); + map not_cached (dest=bus:sri, dest_offset=0xb0040000, reserved, size=768K); + } + + memory cpu4_dlmu + { + mau = 8; + size = 64k; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90100000, size=64k); + map not_cached (dest=bus:sri, dest_offset=0xb0100000, reserved, size=64k); + } + + memory cpu5_dlmu + { + mau = 8; + size = 64k; + type = ram; + map cached (dest=bus:sri, dest_offset=0x90110000, size=64k); + map not_cached (dest=bus:sri, dest_offset=0xb0110000, reserved, size=64k); + } + + memory edmem + { + mau = 8; + size = 4M; + type = ram; + map (dest=bus:sri, dest_offset=0x99000000, size=4M); + map (dest=bus:sri, dest_offset=0xb9000000, reserved, size=4M); + } + +#if (__VERSION__ >= 6003) + section_setup :vtc:linear + { + heap "heap" (min_size = (1k), fixed, align = 8); + } +#endif + + section_setup :vtc:linear + { + start_address + ( + symbol = "_START" + ); + } + + section_setup :vtc:linear + { + stack "ustack_tc0" (min_size = 1k, fixed, align = 8); + stack "istack_tc0" (min_size = 1k, fixed, align = 8); + stack "ustack_tc1" (min_size = 1k, fixed, align = 8); + stack "istack_tc1" (min_size = 1k, fixed, align = 8); + stack "ustack_tc2" (min_size = 1k, fixed, align = 8); + stack "istack_tc2" (min_size = 1k, fixed, align = 8); + stack "ustack_tc3" (min_size = 1k, fixed, align = 8); + stack "istack_tc3" (min_size = 1k, fixed, align = 8); + stack "ustack_tc4" (min_size = 1k, fixed, align = 8); + stack "istack_tc4" (min_size = 1k, fixed, align = 8); + stack "ustack_tc5" (min_size = 1k, fixed, align = 8); + stack "istack_tc5" (min_size = 1k, fixed, align = 8); + } + + /*Section setup for the copy table*/ + section_setup :vtc:linear + { + copytable + ( + align = 4, + dest = linear, + table + { + symbol = "_lc_ub_table_tc0"; + space = :tc0:linear, :tc0:abs24, :tc0:abs18, :tc0:csa; + }, + table + { + symbol = "_lc_ub_table_tc1"; + space = :tc1:linear, :tc1:abs24, :tc1:abs18, :tc1:csa; + }, + table + { + symbol = "_lc_ub_table_tc2"; + space = :tc2:linear, :tc2:abs24, :tc2:abs18, :tc2:csa; + }, + table + { + symbol = "_lc_ub_table_tc3"; + space = :tc3:linear, :tc3:abs24, :tc3:abs18, :tc3:csa; + }, + table + { + symbol = "_lc_ub_table_tc4"; + space = :tc4:linear, :tc4:abs24, :tc4:abs18, :tc4:csa; + }, + table + { + symbol = "_lc_ub_table_tc5"; + space = :tc5:linear, :tc5:abs24, :tc5:abs18, :tc5:csa; + } + ); + } + + /*Sections located at absolute fixed address*/ + + section_layout :vtc:linear + { + /*Fixed memory Allocations for stack memory and CSA*/ + group (ordered) + { + group ustack5(align = 8, run_addr = mem:dsram5[LCF_USTACK5_OFFSET]) + { + stack "ustack_tc5" (size = LCF_USTACK5_SIZE); + } + "__USTACK5":= sizeof(group:ustack5) > 0 ? "_lc_ue_ustack_tc5" : 0; + "__USTACK5_END"="_lc_gb_ustack5"; + + group istack5(align = 8, run_addr = mem:dsram5[LCF_ISTACK5_OFFSET]) + { + stack "istack_tc5" (size = LCF_ISTACK5_SIZE); + } + "__ISTACK5":= sizeof(group:istack5) > 0 ? "_lc_ue_istack_tc5" : 0; + "__ISTACK5_END"="_lc_gb_istack5"; + + group (align = 64, attributes=rw, run_addr=mem:dsram5[LCF_CSA5_OFFSET]) + reserved "csa_tc5" (size = LCF_CSA5_SIZE); + "__CSA5":= "_lc_ub_csa_tc5"; + "__CSA5_END":= "_lc_ue_csa_tc5"; + } + group (ordered) + { + group ustack4(align = 8, run_addr = mem:dsram4[LCF_USTACK4_OFFSET]) + { + stack "ustack_tc4" (size = LCF_USTACK4_SIZE); + } + "__USTACK4":= sizeof(group:ustack4) > 0 ? "_lc_ue_ustack_tc4" : 0; + "__USTACK4_END"="_lc_gb_ustack4"; + + group istack4(align = 8, run_addr = mem:dsram4[LCF_ISTACK4_OFFSET]) + { + stack "istack_tc4" (size = LCF_ISTACK4_SIZE); + } + "__ISTACK4":= sizeof(group:istack4) > 0 ? "_lc_ue_istack_tc4" : 0; + "__ISTACK4_END"="_lc_gb_istack4"; + + group (align = 64, attributes=rw, run_addr=mem:dsram4[LCF_CSA4_OFFSET]) + reserved "csa_tc4" (size = LCF_CSA4_SIZE); + "__CSA4":= "_lc_ub_csa_tc4"; + "__CSA4_END":= "_lc_ue_csa_tc4"; + } + group (ordered) + { + group ustack3(align = 8, run_addr = mem:dsram3[LCF_USTACK3_OFFSET]) + { + stack "ustack_tc3" (size = LCF_USTACK3_SIZE); + } + "__USTACK3":= sizeof(group:ustack3) > 0 ? "_lc_ue_ustack_tc3" : 0; + "__USTACK3_END"="_lc_gb_ustack3"; + + group istack3(align = 8, run_addr = mem:dsram3[LCF_ISTACK3_OFFSET]) + { + stack "istack_tc3" (size = LCF_ISTACK3_SIZE); + } + "__ISTACK3":= sizeof(group:istack3) > 0 ? "_lc_ue_istack_tc3" : 0; + "__ISTACK3_END"="_lc_gb_istack3"; + + group (align = 64, attributes=rw, run_addr=mem:dsram3[LCF_CSA3_OFFSET]) + reserved "csa_tc3" (size = LCF_CSA3_SIZE); + "__CSA3":= "_lc_ub_csa_tc3"; + "__CSA3_END":= "_lc_ue_csa_tc3"; + } + group (ordered) + { + group ustack2(align = 8, run_addr = mem:dsram2[LCF_USTACK2_OFFSET]) + { + stack "ustack_tc2" (size = LCF_USTACK2_SIZE); + } + "__USTACK2":= sizeof(group:ustack2) > 0 ? "_lc_ue_ustack_tc2" : 0; + "__USTACK2_END"="_lc_gb_ustack2"; + + group istack2(align = 8, run_addr = mem:dsram2[LCF_ISTACK2_OFFSET]) + { + stack "istack_tc2" (size = LCF_ISTACK2_SIZE); + } + "__ISTACK2":= sizeof(group:istack2) > 0 ? "_lc_ue_istack_tc2" : 0; + "__ISTACK2_END"="_lc_gb_istack2"; + + group (align = 64, attributes=rw, run_addr=mem:dsram2[LCF_CSA2_OFFSET]) + reserved "csa_tc2" (size = LCF_CSA2_SIZE); + "__CSA2":= "_lc_ub_csa_tc2"; + "__CSA2_END":= "_lc_ue_csa_tc2"; + } + group (ordered) + { + group ustack1(align = 8, run_addr = mem:dsram1[LCF_USTACK1_OFFSET]) + { + stack "ustack_tc1" (size = LCF_USTACK1_SIZE); + } + "__USTACK1":= sizeof(group:ustack1) > 0 ? "_lc_ue_ustack_tc1" : 0; + "__USTACK1_END"="_lc_gb_ustack1"; + + group istack1(align = 8, run_addr = mem:dsram1[LCF_ISTACK1_OFFSET]) + { + stack "istack_tc1" (size = LCF_ISTACK1_SIZE); + } + "__ISTACK1":= sizeof(group:istack1) > 0 ? "_lc_ue_istack_tc1" : 0; + "__ISTACK1_END"="_lc_gb_istack1"; + + group (align = 64, attributes=rw, run_addr=mem:dsram1[LCF_CSA1_OFFSET]) + reserved "csa_tc1" (size = LCF_CSA1_SIZE); + "__CSA1":= "_lc_ub_csa_tc1"; + "__CSA1_END":= "_lc_ue_csa_tc1"; + } + group (ordered) + { + group ustack0(align = 8, run_addr = mem:dsram0[LCF_USTACK0_OFFSET]) + { + stack "ustack_tc0" (size = LCF_USTACK0_SIZE); + } + "__USTACK0":= sizeof(group:ustack0) > 0 ? "_lc_ue_ustack_tc0" : 0; + "__USTACK0_END"="_lc_gb_ustack0"; + + group istack0(align = 8, run_addr = mem:dsram0[LCF_ISTACK0_OFFSET]) + { + stack "istack_tc0" (size = LCF_ISTACK0_SIZE); + } + "__ISTACK0":= sizeof(group:istack0) > 0 ? "_lc_ue_istack_tc0" : 0; + "__ISTACK0_END"="_lc_gb_istack0"; + + group (align = 64, attributes=rw, run_addr=mem:dsram0[LCF_CSA0_OFFSET]) + reserved "csa_tc0" (size = LCF_CSA0_SIZE); + "__CSA0":= "_lc_ub_csa_tc0"; + "__CSA0_END":= "_lc_ue_csa_tc0"; + } + + /*Fixed memory Allocations for _START*/ + group (ordered) + { + group reset (run_addr=RESET) + { + section "reset" ( size = 0x20, fill = 0x0800, attributes = r ) + { + select ".text.start"; + } + } + group interface_const (run_addr=mem:pfls0[0x0020]) + { + select "*.interface_const"; + } + "__IF_CONST" := addressof(group:interface_const); + "__START0" := LCF_STARTPTR_NC_CPU0; + "__START1" := LCF_STARTPTR_NC_CPU1; + "__START2" := LCF_STARTPTR_NC_CPU2; + "__START3" := LCF_STARTPTR_NC_CPU3; + "__START4" := LCF_STARTPTR_NC_CPU4; + "__START5" := LCF_STARTPTR_NC_CPU5; + } + + /*Fixed memory Allocations for Trap Vector Table*/ + group (ordered) + { + group trapvec_tc0 (align = 8, run_addr=LCF_TRAPVEC0_START) + { + section "trapvec_tc0" (size=0x100, attributes=rx, fill=0) + { + select "(.text.traptab_cpu0*)"; + } + } + group trapvec_tc1 (align = 8, run_addr=LCF_TRAPVEC1_START) + { + section "trapvec_tc1" (size=0x100, attributes=rx, fill=0) + { + select "(.text.traptab_cpu1*)"; + } + } + group trapvec_tc2 (align = 8, run_addr=LCF_TRAPVEC2_START) + { + section "trapvec_tc2" (size=0x100, attributes=rx, fill=0) + { + select "(.text.traptab_cpu2*)"; + } + } + group trapvec_tc3 (align = 8, run_addr=LCF_TRAPVEC3_START) + { + section "trapvec_tc3" (size=0x100, attributes=rx, fill=0) + { + select "(.text.traptab_cpu3*)"; + } + } + group trapvec_tc4 (align = 8, run_addr=LCF_TRAPVEC4_START) + { + section "trapvec_tc4" (size=0x100, attributes=rx, fill=0) + { + select "(.text.traptab_cpu4*)"; + } + } + group trapvec_tc5 (align = 8, run_addr=LCF_TRAPVEC5_START) + { + section "trapvec_tc5" (size=0x100, attributes=rx, fill=0) + { + select "(.text.traptab_cpu5*)"; + } + } + "__TRAPTAB_CPU0" := TRAPTAB0; + "__TRAPTAB_CPU1" := TRAPTAB1; + "__TRAPTAB_CPU2" := TRAPTAB2; + "__TRAPTAB_CPU3" := TRAPTAB3; + "__TRAPTAB_CPU4" := TRAPTAB4; + "__TRAPTAB_CPU5" := TRAPTAB5; + } + + /*Fixed memory Allocations for Start up code*/ + group (ordered) + { + group start_tc0 (run_addr=LCF_STARTPTR_NC_CPU0) + { + select "(.text.start_cpu0*)"; + } + group start_tc1 (run_addr=LCF_STARTPTR_NC_CPU1) + { + select "(.text.start_cpu1*)"; + } + group start_tc2 (run_addr=LCF_STARTPTR_NC_CPU2) + { + select "(.text.start_cpu2*)"; + } + group start_tc3 (run_addr=LCF_STARTPTR_NC_CPU3) + { + select "(.text.start_cpu3*)"; + } + group start_tc4 (run_addr=LCF_STARTPTR_NC_CPU4) + { + select "(.text.start_cpu4*)"; + } + group start_tc5 (run_addr=LCF_STARTPTR_NC_CPU5) + { + select "(.text.start_cpu5*)"; + } + "__ENABLE_INDIVIDUAL_C_INIT_CPU0" := 0; /* Not used */ + "__ENABLE_INDIVIDUAL_C_INIT_CPU1" := 0; + "__ENABLE_INDIVIDUAL_C_INIT_CPU2" := 0; + "__ENABLE_INDIVIDUAL_C_INIT_CPU3" := 0; + "__ENABLE_INDIVIDUAL_C_INIT_CPU4" := 0; + "__ENABLE_INDIVIDUAL_C_INIT_CPU5" := 0; + } + + /*Fixed memory Allocations for Interrupt Vector Table*/ + group (ordered) + { + group int_tab_tc0 (ordered) + { +# include "inttab0.lsl" + } + group int_tab_tc1 (ordered) + { +# include "inttab1.lsl" + } + group int_tab_tc2 (ordered) + { +# include "inttab2.lsl" + } + group int_tab_tc3 (ordered) + { +# include "inttab3.lsl" + } + group int_tab_tc4 (ordered) + { +# include "inttab4.lsl" + } + group int_tab_tc5 (ordered) + { +# include "inttab5.lsl" + } + "_lc_u_int_tab" = (LCF_INTVEC0_START); + "__INTTAB_CPU0" = (LCF_INTVEC0_START); + "__INTTAB_CPU1" = (LCF_INTVEC1_START); + "__INTTAB_CPU2" = (LCF_INTVEC2_START); + "__INTTAB_CPU3" = (LCF_INTVEC3_START); + "__INTTAB_CPU4" = (LCF_INTVEC4_START); + "__INTTAB_CPU5" = (LCF_INTVEC5_START); + } + + /*Fixed memory Allocations for BMHD*/ + group (ordered) + { + group bmh_0_orig (run_addr=mem:ucb[0x0000]) + { + select ".rodata.bmhd_0_orig"; + } + group bmh_1_orig (run_addr=mem:ucb[0x0200]) + { + select ".rodata.bmhd_1_orig"; + } + group bmh_2_orig (run_addr=mem:ucb[0x0400]) + { + select ".rodata.bmhd_2_orig"; + } + group bmh_3_orig (run_addr=mem:ucb[0x0600]) + { + select ".rodata.bmhd_3_orig"; + } + group bmh_blank (run_addr=mem:ucb[0x0800]) + { + } + group bmh_0_copy (run_addr=mem:ucb[0x1000]) + { + select ".rodata.bmhd_0_copy"; + } + group bmh_1_copy (run_addr=mem:ucb[0x1200]) + { + select ".rodata.bmhd_1_copy"; + } + group bmh_2_copy (run_addr=mem:ucb[0x1400]) + { + select ".rodata.bmhd_2_copy"; + } + group bmh_3_copy (run_addr=mem:ucb[0x1600]) + { + select ".rodata.bmhd_3_copy"; + } + } + } + + /*Near Abbsolute Addressable Data Sections*/ + section_layout :vtc:abs18 + { + /*Near Absolute Data, selectable with patterns and user defined sections*/ + group + { + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram5) + { + select "(.zdata.zdata_cpu5|.zdata.zdata_cpu5.*)"; + select "(.zbss.zbss_cpu5|.zbss.zbss_cpu5.*)"; + } + + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram4) + { + select "(.zdata.zdata_cpu4|.zdata.zdata_cpu4.*)"; + select "(.zbss.zbss_cpu4|.zbss.zbss_cpu4.*)"; + } + + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram3) + { + select "(.zdata.zdata_cpu3|.zdata.zdata_cpu3.*)"; + select "(.zbss.zbss_cpu3|.zbss.zbss_cpu3.*)"; + } + + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram2) + { + select "(.zdata.zdata_cpu2|.zdata.zdata_cpu2.*)"; + select "(.zbss.zbss_cpu2|.zbss.zbss_cpu2.*)"; + } + + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram1) + { + select "(.zdata.zdata_cpu1|.zdata.zdata_cpu1.*)"; + select "(.zbss.zbss_cpu1|.zbss.zbss_cpu1.*)"; + } + + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram0) + { + select "(.zdata.zdata_cpu0|.zdata.zdata_cpu0.*)"; + select "(.zbss.zbss_cpu0|.zbss.zbss_cpu0.*)"; + } + + group (ordered, attributes=rw, run_addr = mem:cpu0_dlmu) + { + select "(.zdata.zlmudata|.zdata.zlmudata.*)"; + select "(.zbss.zlmubss|.zbss.zlmubss.*)"; + } + } + + /*Near Absolute Data, selectable by toolchain*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram0) +# endif + { + group zdata_mcal(attributes=rw) + { + select ".zdata.dsprInit.cpu0.32bit"; + select ".zdata.dsprInit.cpu0.16bit"; + select ".zdata.dsprInit.cpu0.8bit"; + } + + group zdata_powerOn(attributes=rw) + { + select ".zdata.dsprPowerOnInit.cpu0.32bit"; + select ".zdata.dsprPowerOnInit.cpu0.16bit"; + select ".zdata.dsprPowerOnInit.cpu0.8bit"; + } + + group zbss_mcal(attributes=rw) + { + select ".zbss.dsprClearOnInit.cpu0.32bit"; + select ".zbss.dsprClearOnInit.cpu0.16bit"; + select ".zbss.dsprClearOnInit.cpu0.8bit"; + } + + group zbss_noClear(attributes=rw) + { + select ".zbss.dsprNoInit.cpu0.32bit"; + select ".zbss.dsprNoInit.cpu0.16bit"; + select ".zbss.dsprNoInit.cpu0.8bit"; + } + + group zbss_powerOn(attributes=rw) + { + select ".zbss.dsprPowerOnClear.cpu0.32bit"; + select ".zbss.dsprPowerOnClear.cpu0.16bit"; + select ".zbss.dsprPowerOnClear.cpu0.8bit"; + } + + group zdata(attributes=rw) + { + select "(.zdata|.zdata.*)"; + select "(.zbss|.zbss.*)"; + } + } + + /*Near Absolute Const, selectable with patterns and user defined sections*/ + group + { + group (ordered, align = 4, contiguous, run_addr=mem:pfls0) + { + select ".zrodata.Ifx_Ssw_Tc0.*"; + select ".zrodata.Ifx_Ssw_Tc1.*"; + select ".zrodata.Ifx_Ssw_Tc2.*"; + select ".zrodata.Ifx_Ssw_Tc3.*"; + select ".zrodata.Ifx_Ssw_Tc4.*"; + select ".zrodata.Ifx_Ssw_Tc5.*"; + select ".zrodata.Cpu0_Main.*"; + select ".zrodata.Cpu1_Main.*"; + select ".zrodata.Cpu2_Main.*"; + select ".zrodata.Cpu3_Main.*"; + select ".zrodata.Cpu4_Main.*"; + select ".zrodata.Cpu5_Main.*"; + + /*Near Absolute Const, selectable by toolchain*/ + select ".zrodata.const.cpu0.32bit"; + select ".zrodata.const.cpu0.16bit"; + select ".zrodata.const.cpu0.8bit"; + select ".zrodata.config.cpu0.32bit"; + select ".zrodata.config.cpu0.16bit"; + select ".zrodata.config.cpu0.8bit"; + select "(.zrodata|.zrodata.*)"; + } + } + } + + /*Relative A0/A1/A8/A9 Addressable Sections*/ + section_layout :vtc:linear + { + /*Relative A0 Addressable Data, selectable by toolchain*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group a0 (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group a0 (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group a0 (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group a0 (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group a0 (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group a0 (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram0) +# endif + { + select "(.data_a0.sdata|.data_a0.sdata.*)"; + select "(.bss_a0.sbss|.bss_a0.sbss.*)"; + } + "_SMALL_DATA_" := sizeof(group:a0) > 0 ? addressof(group:a0) : addressof(group:a0) & 0xF0000000 + 32k; + "__A0_MEM" = "_SMALL_DATA_"; + + /*Relative A1 Addressable Const, selectable by toolchain*/ + /*Small constant sections, No option given for CPU specific user sections to make generated code portable across Cpus*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group a1 (ordered, align = 4, run_addr=mem:pfls5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group a1 (ordered, align = 4, run_addr=mem:pfls4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group a1 (ordered, align = 4, run_addr=mem:pfls3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group a1 (ordered, align = 4, run_addr=mem:pfls2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group a1 (ordered, align = 4, run_addr=mem:pfls1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group a1 (ordered, align = 4, run_addr=mem:pfls0) +# endif + { + select "(.rodata_a1.srodata|.rodata_a1.srodata.*)"; + select "(.ldata|.ldata.*)"; + } + "_LITERAL_DATA_" := sizeof(group:a1) > 0 ? addressof(group:a1) : addressof(group:a1) & 0xF0000000 + 32k; + "__A1_MEM" = "_LITERAL_DATA_"; + + /*Relative A9 Addressable Data, selectable with patterns and user defined sections*/ + group a9 (ordered, align = 4, run_addr=mem:lmuram) + { + select "(.data_a9.a9sdata|.data_a9.a9sdata.*)"; + select "(.bss_a9.a9sbss|.bss_a9.a9sbss.*)"; + } + "_A9_DATA_" := sizeof(group:a9) > 0 ? addressof(group:a9) : addressof(group:a9) & 0xF0000000 + 32k; + "__A9_MEM" = "_A9_DATA_"; + + /*Relative A8 Addressable Const, selectable with patterns and user defined sections*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group a8 (ordered, align = 4, run_addr=mem:pfls5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group a8 (ordered, align = 4, run_addr=mem:pfls4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group a8 (ordered, align = 4, run_addr=mem:pfls3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group a8 (ordered, align = 4, run_addr=mem:pfls2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group a8 (ordered, align = 4, run_addr=mem:pfls1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group a8 (ordered, align = 4, run_addr=mem:pfls0) +# endif + { + select "(.rodata_a8.a8srodata|.rodata_a8.a8srodata.*)"; + } + "_A8_DATA_" := sizeof(group:a8) > 0 ? addressof(group:a8) : addressof(group:a8) & 0xF0000000 + 32k; + "__A8_MEM" = "_A8_DATA_"; + } + + /*Far Data / Far Const Sections, selectable with patterns and user defined sections*/ + section_layout :vtc:linear + { + /*Far Data Sections, selectable with patterns and user defined sections*/ + group + { + /*DSRAM sections*/ + group + { + group (ordered, attributes=rw, run_addr=mem:dsram5) + { + select ".data.Ifx_Ssw_Tc5.*"; + select ".data.Cpu5_Main.*"; + select "(.data.data_cpu5|.data.data_cpu5.*)"; + select ".bss.Ifx_Ssw_Tc5.*"; + select ".bss.Cpu5_Main.*"; + select "(.bss.bss_cpu5|.bss.bss_cpu5.*)"; + } + group (ordered, attributes=rw, run_addr=mem:dsram4) + { + select ".data.Ifx_Ssw_Tc4.*"; + select ".data.Cpu4_Main.*"; + select "(.data.data_cpu4|.data.data_cpu4.*)"; + select ".bss.Ifx_Ssw_Tc4.*"; + select ".bss.Cpu4_Main.*"; + select "(.bss.bss_cpu4|.bss.bss_cpu4.*)"; + } + group (ordered, attributes=rw, run_addr=mem:dsram3) + { + select ".data.Ifx_Ssw_Tc3.*"; + select ".data.Cpu3_Main.*"; + select "(.data.data_cpu3|.data.data_cpu3.*)"; + select ".bss.Ifx_Ssw_Tc3.*"; + select ".bss.Cpu3_Main.*"; + select "(.bss.bss_cpu3|.bss.bss_cpu3.*)"; + } + group (ordered, attributes=rw, run_addr=mem:dsram2) + { + select ".data.Ifx_Ssw_Tc2.*"; + select ".data.Cpu2_Main.*"; + select "(.data.data_cpu2|.data.data_cpu2.*)"; + select ".bss.Ifx_Ssw_Tc2.*"; + select ".bss.Cpu2_Main.*"; + select "(.bss.bss_cpu2|.bss.bss_cpu2.*)"; + } + group (ordered, attributes=rw, run_addr=mem:dsram1) + { + select ".data.Ifx_Ssw_Tc1.*"; + select ".data.Cpu1_Main.*"; + select "(.data.data_cpu1|.data.data_cpu1.*)"; + select ".bss.Ifx_Ssw_Tc1.*"; + select ".bss.Cpu1_Main.*"; + select "(.bss.bss_cpu1|.bss.bss_cpu1.*)"; + } + group (ordered, attributes=rw, run_addr=mem:dsram0) + { + select ".data.Ifx_Ssw_Tc0.*"; + select ".data.Cpu0_Main.*"; + select "(.data.data_cpu0|.data.data_cpu0.*)"; + select ".bss.Ifx_Ssw_Tc0.*"; + select ".bss.Cpu0_Main.*"; + select "(.bss.bss_cpu0|.bss.bss_cpu0.*)"; + } + } + + /*LMU Data sections*/ + group + { + group (ordered, attributes=rw, run_addr = mem:cpu0_dlmu) + { + select "(.data.lmudata_cpu0|.data.lmudata_cpu0.*)"; + select "(.bss.lmubss_cpu0|.bss.lmubss_cpu0.*)"; + } + group (ordered, attributes=rw, run_addr = mem:cpu1_dlmu) + { + select "(.data.lmudata_cpu1|.data.lmudata_cpu1.*)"; + select "(.bss.lmubss_cpu1|.bss.lmubss_cpu1.*)"; + } + group (ordered, attributes=rw, run_addr = mem:cpu2_dlmu) + { + select "(.data.lmudata_cpu2|.data.lmudata_cpu2.*)"; + select "(.bss.lmubss_cpu2|.bss.lmubss_cpu2.*)"; + } + group (ordered, attributes=rw, run_addr = mem:cpu3_dlmu) + { + select "(.data.lmudata_cpu3|.data.lmudata_cpu3.*)"; + select "(.bss.lmubss_cpu3|.bss.lmubss_cpu3.*)"; + } + group (ordered, attributes=rw, run_addr = mem:cpu4_dlmu) + { + select "(.data.lmudata_cpu4|.data.lmudata_cpu4.*)"; + select "(.bss.lmubss_cpu4|.bss.lmubss_cpu4.*)"; + } + group (ordered, attributes=rw, run_addr = mem:cpu5_dlmu) + { + select "(.data.lmudata_cpu5|.data.lmudata_cpu5.*)"; + select "(.bss.lmubss_cpu5|.bss.lmubss_cpu5.*)"; + } + group (ordered, attributes=rw, run_addr=mem:lmuram) + { + select "(.data.lmudata|.data.lmudata.*)"; + select "(.bss.lmubss|.bss.lmubss.*)"; + } + } + } + + /*Far Data Sections, selectable by toolchain*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group (ordered, contiguous, align = 4, attributes=rw, run_addr = mem:dsram0) +# endif + { + group data_mcal(attributes=rw) + { + select ".data.farDsprInit.cpu0.32bit"; + select ".data.farDsprInit.cpu0.16bit"; + select ".data.farDsprInit.cpu0.8bit"; + } + + group bss_mcal(attributes=rw) + { + select ".bss.farDsprClearOnInit.cpu0.32bit"; + select ".bss.farDsprClearOnInit.cpu0.16bit"; + select ".bss.farDsprClearOnInit.cpu0.8bit"; + } + + group bss_noInit(attributes=rw) + { + select ".bss.farDsprNoInit.cpu0.32bit"; + select ".bss.farDsprNoInit.cpu0.16bit"; + select ".bss.farDsprNoInit.cpu0.8bit"; + } + + group data(attributes=rw) + { + select "(.data|.data.*)"; + select "(.bss|.bss.*)"; + } + } + + /*Heap allocation*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group (ordered, align = 4, run_addr = mem:dsram5[LCF_HEAP5_OFFSET]) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group (ordered, align = 4, run_addr = mem:dsram4[LCF_HEAP4_OFFSET]) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group (ordered, align = 4, run_addr = mem:dsram3[LCF_HEAP3_OFFSET]) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group (ordered, align = 4, run_addr = mem:dsram2[LCF_HEAP2_OFFSET]) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group (ordered, align = 4, run_addr = mem:dsram1[LCF_HEAP1_OFFSET]) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group (ordered, align = 4, run_addr = mem:dsram0[LCF_HEAP0_OFFSET]) +# endif + { + heap "heap" (size = LCF_HEAP_SIZE); + } + + /*Far Const Sections, selectable with patterns and user defined sections*/ + group + { + group (ordered, align = 4, run_addr=mem:pfls0) + { + select ".rodata.Ifx_Ssw_Tc0.*"; + select ".rodata.Cpu0_Main.*"; + select "(.rodata.rodata_cpu0|.rodata.rodata_cpu0.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls1) + { + select ".rodata.Cpu1_Main.*"; + select ".rodata.Ifx_Ssw_Tc1.*"; + select "(.rodata.rodata_cpu1|.rodata.rodata_cpu1.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls2) + { + select ".rodata.Ifx_Ssw_Tc2.*"; + select ".rodata.Cpu2_Main.*"; + select "(.rodata.rodata_cpu2|.rodata.rodata_cpu2.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls3) + { + select ".rodata.Ifx_Ssw_Tc3.*"; + select ".rodata.Cpu3_Main.*"; + select "(.rodata.rodata_cpu3|.rodata.rodata_cpu3.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls4) + { + select ".rodata.Ifx_Ssw_Tc4.*"; + select ".rodata.Cpu4_Main.*"; + select "(.rodata.rodata_cpu4|.rodata.rodata_cpu4.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls5) + { + select ".rodata.Ifx_Ssw_Tc5.*"; + select ".rodata.Cpu5_Main.*"; + select "(.rodata.rodata_cpu5|.rodata.rodata_cpu5.*)"; + } + } + + /*Far Const Sections, selectable by toolchain*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group (ordered, align = 4, run_addr=mem:pfls5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group ordered, align = 4, run_addr=mem:pfls4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group (ordered, align = 4, run_addr=mem:pfls3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group (ordered, align = 4, run_addr=mem:pfls2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group (ordered, align = 4, run_addr=mem:pfls1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group (ordered, align = 4, run_addr=mem:pfls0) +# endif + { + select ".rodata.farConst.cpu0.32bit"; + select ".rodata.farConst.cpu0.16bit"; + select ".rodata.farConst.cpu0.8bit"; + select "(.rodata|.rodata.*)"; + } + } + + /* PSRAM Code selections*/ + section_layout :vtc:linear + { + /*Code Sections, selectable with patterns and user defined sections*/ + group + { + /*Program Scratchpad Sections*/ + group + { + group code_psram0 (ordered, attributes=rwx, copy, run_addr=mem:psram0) + { + select "(.text.cpu0_psram|.text.cpu0_psram.*)"; + select "(.text.psram_text_cpu0|.text.psram_text_cpu0.*)"; + } + group code_psram1 (ordered, attributes=rwx, copy, run_addr=mem:psram1) + { + select "(.text.cpu1_psram|.text.cpu1_psram.*)"; + select "(.text.psram_text_cpu1|.text.psram_text_cpu1.*)"; + } + group code_psram2 (ordered, attributes=rwx, copy, run_addr=mem:psram2) + { + select "(.text.cpu2_psram|.text.cpu2_psram.*)"; + select "(.text.psram_text_cpu2|.text.psram_text_cpu2.*)"; + } + group code_psram3 (ordered, attributes=rwx, copy, run_addr=mem:psram3) + { + select "(.text.cpu3_psram|.text.cpu3_psram.*)"; + select "(.text.psram_text_cpu3|.text.psram_text_cpu3.*)"; + } + group code_psram4 (ordered, attributes=rwx, copy, run_addr=mem:psram4) + { + select "(.text.cpu4_psram|.text.cpu4_psram.*)"; + select "(.text.psram_text_cpu4|.text.psram_text_cpu4.*)"; + } + group code_psram5 (ordered, attributes=rwx, copy, run_addr=mem:psram5) + { + select "(.text.cpu5_psram|.text.cpu5_psram.*)"; + select "(.text.psram_text_cpu5|.text.psram_text_cpu5.*)"; + } + } + } + } + + /* FLS Code selections*/ + section_layout :vtc:linear + { + /*Code Sections, selectable with patterns and user defined sections*/ + group + { + /*Cpu specific PFLASH Sections*/ + group + { + group (ordered, align = 4, run_addr=mem:pfls0) + { + select ".text.Ifx_Ssw_Tc0.*"; + select ".text.Cpu0_Main.*"; + select ".text.CompilerTasking.Ifx_C_Init"; + select "(.text.text_cpu0|.text.text_cpu0.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls1) + { + select ".text.Ifx_Ssw_Tc1.*"; + select ".text.Cpu1_Main.*"; + select "(.text.text_cpu1|.text.text_cpu1.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls2) + { + select ".text.Ifx_Ssw_Tc2.*"; + select ".text.Cpu2_Main.*"; + select "(.text.text_cpu2|.text.text_cpu2.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls3) + { + select ".text.Ifx_Ssw_Tc3.*"; + select ".text.Cpu3_Main.*"; + select "(.text.text_cpu3|.text.text_cpu3.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls4) + { + select ".text.Ifx_Ssw_Tc4.*"; + select ".text.Cpu4_Main.*"; + select ".text.text_cpu4*"; + select "(.text.text_cpu4|.text.text_cpu4.*)"; + } + group (ordered, align = 4, run_addr=mem:pfls5) + { + select ".text.Ifx_Ssw_Tc5.*"; + select ".text.Cpu5_Main.*"; + select ".text.text_cpu5*"; + select "(.text.text_cpu5|.text.text_cpu5.*)"; + } + } + } + + /*Code Sections, selectable by toolchain*/ +# if LCF_DEFAULT_HOST == LCF_CPU5 + group (ordered, run_addr=mem:pfls5) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU4 + group ordered, run_addr=mem:pfls4) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU3 + group (ordered, run_addr=mem:pfls3) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU2 + group (ordered, run_addr=mem:pfls2) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU1 + group (ordered, run_addr=mem:pfls1) +# endif +# if LCF_DEFAULT_HOST == LCF_CPU0 + group (ordered, run_addr=mem:pfls0) +# endif + { + select ".text.fast.pfls.cpu0"; + select ".text.slow.pfls.cpu0"; + select ".text.5ms.pfls.cpu0"; + select ".text.10ms.pfls.cpu0"; + select ".text.callout.pfls.cpu0"; + select "(.text|.text.*)"; + } + } +} diff --git a/boards/tricore/tc3xx/tc397/scripts/Make.defs b/boards/tricore/tc3xx/tc397/scripts/Make.defs new file mode 100644 index 0000000000..2a5ae5bf8b --- /dev/null +++ b/boards/tricore/tc3xx/tc397/scripts/Make.defs @@ -0,0 +1,32 @@ +############################################################################ +# boards/tricore/tc3xx/tc397/scripts/Make.defs +# +# 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. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/tricore/src/tc3xx/Toolchain.defs + +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)Lcf_Tasking_Tricore_Tc.lsl + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ diff --git a/boards/tricore/tc3xx/tc397/src/Makefile b/boards/tricore/tc3xx/tc397/src/Makefile new file mode 100644 index 0000000000..83c7719356 --- /dev/null +++ b/boards/tricore/tc3xx/tc397/src/Makefile @@ -0,0 +1,29 @@ +############################################################################ +# boards/tricore/tc3xx/tc397/src/Makefile +# +# 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. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = tc397_boardinit.c tc397_bringup.c + +ifeq ($(CONFIG_BOARDCTL),y) +CSRCS += tc397_appinit.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/tricore/tc3xx/tc397/src/tc397.h b/boards/tricore/tc3xx/tc397/src/tc397.h new file mode 100644 index 0000000000..776c0ae73e --- /dev/null +++ b/boards/tricore/tc3xx/tc397/src/tc397.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/src/tc397.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __BOARDS_TRICORE_TC3XX_TC397_SRC_TC397_H +#define __BOARDS_TRICORE_TC3XX_TC397_SRC_TC397_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: tc397_bringup + * + * Description: + * Bring up board features + * + ****************************************************************************/ + +#if defined(CONFIG_BOARDCTL) || defined(CONFIG_BOARD_LATE_INITIALIZE) +int tc397_bringup(void); +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_TRICORE_TC3XX_TC397_SRC_TC397_H */ diff --git a/boards/tricore/tc3xx/tc397/src/tc397_appinit.c b/boards/tricore/tc3xx/tc397/src/tc397_appinit.c new file mode 100644 index 0000000000..dd419bd85f --- /dev/null +++ b/boards/tricore/tc3xx/tc397/src/tc397_appinit.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/src/tc397_appinit.c + * + * 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 + +#include + +#include "tc397.h" + +#ifdef CONFIG_BOARDCTL + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value could be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifndef CONFIG_BOARD_LATE_INITIALIZE + /* Perform board initialization */ + + return tc397_bringup(); +#else + return OK; +#endif +} + +#endif /* CONFIG_BOARDCTL */ diff --git a/boards/tricore/tc3xx/tc397/src/tc397_boardinit.c b/boards/tricore/tc3xx/tc397/src/tc397_boardinit.c new file mode 100644 index 0000000000..41259440a2 --- /dev/null +++ b/boards/tricore/tc3xx/tc397/src/tc397_boardinit.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/src/tc397_boardinit.c + * + * 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 + +#include +#include + +#include "chip.h" +#include "tc397.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tc397_memory_initialize + * + * Description: + * All i.MX6 architectures must provide the following entry point. This + * entry point is called early in the initialization before memory has + * been configured. This board-specific function is responsible for + * configuring any on-board memories. + * + * Logic in tc397_memory_initialize must be careful to avoid using any + * global variables because those will be uninitialized at the time this + * function is called. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void tc397_memory_initialize(void) +{ + /* SDRAM was initialized by a bootloader in the supported configurations. */ +} + +/**************************************************************************** + * Name: tc397_board_initialize + * + * Description: + * All i.MX6 architectures must provide the following entry point. This + * entry point is called in the initialization phase -- after + * tc397_memory_initialize and after all memory has been configured and + * mapped but before any devices have been initialized. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void tc397_board_initialize(void) +{ +#ifdef CONFIG_ARCH_LEDS + /* Configure on-board LEDs if LED support has been selected. */ + + board_autoled_initialize(); +#endif +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() will be + * called immediately after up_intitialize() is called and just before the + * initial application is started. This additional initialization phase + * may be used, for example, to initialize board-specific device drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board initialization */ + + tc397_bringup(); +} +#endif /* CONFIG_BOARD_LATE_INITIALIZE */ diff --git a/boards/tricore/tc3xx/tc397/src/tc397_bringup.c b/boards/tricore/tc3xx/tc397/src/tc397_bringup.c new file mode 100644 index 0000000000..25936c520c --- /dev/null +++ b/boards/tricore/tc3xx/tc397/src/tc397_bringup.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * boards/tricore/tc3xx/tc397/src/tc397_bringup.c + * + * 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 +#include + +#include + +#include "tc397.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tc397_bringup + * + * Description: + * Bring up board features + * + ****************************************************************************/ + +int tc397_bringup(void) +{ + int ret; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", ret); + } +#endif + +#ifdef CONFIG_FS_TMPFS + /* Mount the tmpfs file system */ + + ret = nx_mount(NULL, CONFIG_LIBC_TMPDIR, "tmpfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount tmpfs at %s: %d\n", + CONFIG_LIBC_TMPDIR, ret); + } +#endif + + UNUSED(ret); + return OK; +}