1
0
Fork 0
forked from nuttx/nuttx-update

CEVA: add ceva platform xc5 xm6 support

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2022-01-05 13:53:08 +08:00 committed by Alan Carvalho de Assis
parent 3fceaf10a9
commit ee916bdb91
91 changed files with 11808 additions and 0 deletions

133
arch/ceva/Kconfig Normal file
View file

@ -0,0 +1,133 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if ARCH_CEVA
comment "CEVA Options"
config ARCH_XC5
bool
default n
---help---
CEVA-XC5 is a licensable DSP and memory subsystem (MSS) platform
designed for advanced wireless communication, with low power and
flexible architecture support for both legacy and next-generation
wireless standards.
config ARCH_XM6
bool
default n
select ARCH_HAVE_HARDFAULT_DEBUG
select ARCH_HAVE_MPU
select ARCH_HAVE_MULTICPU
---help---
CEVA-XM6 is a licensable DSP and memory subsystem (MSS) platform
targeted for high-performance computer vision and image-processing
applications that provide very high processing power while
maintaining a small footprint and low power consumption.
config ARCH_FAMILY
string
default "xc5" if ARCH_XC5
default "xm6" if ARCH_XM6
config ARCH_ITCM_SIZE
int "ITCM Size"
config ARCH_DTCM_SIZE
int "DTCM Size"
config CEVA_ICACHE
bool "Use I-Cache"
default n
select ARCH_ICACHE
config CEVA_DCACHE
bool "Use D-Cache"
default n
select ARCH_DCACHE
config ARCH_NR_FPUS
int "FPU Number"
default 1
depends on ARCH_HAVE_FPU
---help---
Built-in support for the number of Floating Point Unit.
Check your chip specifications first; not all CEVA chips
support the FPU.
config ARCH_MPU
bool "MPU support"
default n
depends on ARCH_HAVE_MPU
select ARCH_USE_MPU
---help---
Built-in support for the CEVA Memory Protection Unit (MPU).
Also used to configure the cache and memory attribute.
config ARCH_HAVE_VINTC
bool
default n
config ARCH_HARDFAULT_IRQ
int "Hard Fault IRQ Number"
default -1
config ARCH_NR_MEMORY
int "Memory Block Number"
default 1
config ARCH_NR_USER_MEMORY
int "User Memory Block Number"
depends on BUILD_PROTECTED
default 1
config ARCH_DEFAULT_HEAP
int "Default Heap Index"
default 0
config ARCH_USER_DEFAULT_HEAP
int "User Default Heap Index"
depends on BUILD_PROTECTED
default 0
config ARCH_STACK_HEAP
int "Stack Heap Index"
default 0
config ARCH_KERNEL_STACK_HEAP
int "Kernel Stack Heap Index"
depends on MM_KERNEL_HEAP
default 0
config ARCH_RTL_MAJOR
int "RTL Version Major Number"
config ARCH_RTL_MINOR
int "RTL Version Minor Number"
config ARCH_RTL_REVISION
int "RTL Version Revision Number"
config ARCH_HAVE_HARDFAULT_DEBUG
bool
default n
config DEBUG_HARDFAULT
bool "Verbose Hard-Fault Debug"
default n
depends on ARCH_HAVE_HARDFAULT_DEBUG && DEBUG_ALERT
---help---
Enables verbose debug output when a hard fault occurs. This verbose
output is sometimes helpful when debugging difficult hard fault problems,
but may be more than you typically want to see.
if ARCH_XC5
source arch/ceva/src/xc5/Kconfig
endif
if ARCH_XM6
source arch/ceva/src/xm6/Kconfig
endif
endif # ARCH_CEVA

3
arch/ceva/include/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/board
/chip

107
arch/ceva/include/arch.h Normal file
View file

@ -0,0 +1,107 @@
/****************************************************************************
* arch/ceva/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_CEVA_INCLUDE_ARCH_H
#define __ARCH_CEVA_INCLUDE_ARCH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/chip/chip.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK == 0
/* The interrupt stack is required for CEVA porting */
# undef CONFIG_ARCH_INTERRUPTSTACK
# define CONFIG_ARCH_INTERRUPTSTACK CONFIG_IDLETHREAD_STACKSIZE
#endif
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
/* In the kernel build, there are multiple user heaps; one for each task
* group. In this build configuration, the user heap structure lies
* in a reserved region at the beginning of the .bss/.data address
* space (CONFIG_ARCH_DATA_VBASE). The size of that region is given by
* ARCH_DATA_RESERVE_SIZE
*/
# define UMM_HEAP(i) ((i) ? NULL : &ARCH_DATA_RESERVE->ar_usrheap)
#elif defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)
/* In the protected mode, there are two heaps: A kernel heap and a single
* user heap. Kernel code must obtain the address of the user heap data
* structure from the userspace interface.
*/
# define UMM_HEAP(i) ((struct mm_heap_s *const *)USERSPACE->us_heap)[i]
#else
/* Otherwise, the user heap data structures are in common .bss */
# define UMM_HEAP(i) g_mm_heap[i]
#endif
#ifdef CONFIG_MM_KERNEL_HEAP
/* Kernel has the dedicated heap data structures */
# define KMM_HEAP(i) g_mm_heap[i]
#else
/* Otherwise, kernel allocate the memory from the user heap data structures */
# define KMM_HEAP(i) UMM_HEAP(i)
#endif
#ifdef __KERNEL__
# define MM_HEAP(i) KMM_HEAP(i)
#else
# define MM_HEAP(i) UMM_HEAP(i)
#endif
#define PM_IDLE_DOMAIN 0
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
EXTERN struct mm_heap_s *const g_mm_heap[];
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ARCH_CEVA_INCLUDE_ARCH_H */

View file

@ -0,0 +1,230 @@
/****************************************************************************
* arch/ceva/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_CEVA_INCLUDE_INTTYPES_H
#define __ARCH_CEVA_INCLUDE_INTTYPES_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "lld"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "d"
#define PRIdLEAST64 "lld"
#define PRIdFAST8 "d"
#define PRIdFAST16 "d"
#define PRIdFAST32 "d"
#define PRIdFAST64 "lld"
#define PRIdMAX "lld"
#define PRIdPTR "d"
#define PRIi8 "i"
#define PRIi16 "i"
#define PRIi32 "i"
#define PRIi64 "lli"
#define PRIiLEAST8 "i"
#define PRIiLEAST16 "i"
#define PRIiLEAST32 "i"
#define PRIiLEAST64 "lli"
#define PRIiFAST8 "i"
#define PRIiFAST16 "i"
#define PRIiFAST32 "i"
#define PRIiFAST64 "lli"
#define PRIiMAX "lli"
#define PRIiPTR "i"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "o"
#define PRIo64 "llo"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "o"
#define PRIoLEAST64 "llo"
#define PRIoFAST8 "o"
#define PRIoFAST16 "o"
#define PRIoFAST32 "o"
#define PRIoFAST64 "llo"
#define PRIoMAX "llo"
#define PRIoPTR "o"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 "llu"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "u"
#define PRIuLEAST64 "llu"
#define PRIuFAST8 "u"
#define PRIuFAST16 "u"
#define PRIuFAST32 "u"
#define PRIuFAST64 "llu"
#define PRIuMAX "llu"
#define PRIuPTR "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIx64 "llx"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "x"
#define PRIxLEAST64 "llx"
#define PRIxFAST8 "x"
#define PRIxFAST16 "x"
#define PRIxFAST32 "x"
#define PRIxFAST64 "llx"
#define PRIxMAX "llx"
#define PRIxPTR "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIX64 "llX"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "X"
#define PRIXLEAST64 "llX"
#define PRIXFAST8 "X"
#define PRIXFAST16 "X"
#define PRIXFAST32 "X"
#define PRIXFAST64 "llX"
#define PRIXMAX "llX"
#define PRIXPTR "X"
#define SCNd8 "hhd"
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 "lld"
#define SCNdLEAST8 "hhd"
#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 "lld"
#define SCNdFAST8 "hhd"
#define SCNdFAST16 "hd"
#define SCNdFAST32 "d"
#define SCNdFAST64 "lld"
#define SCNdMAX "lld"
#define SCNdPTR "d"
#define SCNi8 "hhi"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 "lli"
#define SCNiLEAST8 "hhi"
#define SCNiLEAST16 "hi"
#define SCNiLEAST32 "i"
#define SCNiLEAST64 "lli"
#define SCNiFAST8 "hhi"
#define SCNiFAST16 "hi"
#define SCNiFAST32 "i"
#define SCNiFAST64 "lli"
#define SCNiMAX "lli"
#define SCNiPTR "i"
#define SCNo8 "hho"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 "llo"
#define SCNoLEAST8 "hho"
#define SCNoLEAST16 "ho"
#define SCNoLEAST32 "o"
#define SCNoLEAST64 "llo"
#define SCNoFAST8 "hho"
#define SCNoFAST16 "ho"
#define SCNoFAST32 "o"
#define SCNoFAST64 "llo"
#define SCNoMAX "llo"
#define SCNoPTR "o"
#define SCNu8 "hhu"
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 "llu"
#define SCNuLEAST8 "hhu"
#define SCNuLEAST16 "hu"
#define SCNuLEAST32 "u"
#define SCNuLEAST64 "llu"
#define SCNuFAST8 "hhu"
#define SCNuFAST16 "hu"
#define SCNuFAST32 "u"
#define SCNuFAST64 "llu"
#define SCNuMAX "llu"
#define SCNuPTR "u"
#define SCNx8 "hhx"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 "llx"
#define SCNxLEAST8 "hhx"
#define SCNxLEAST16 "hx"
#define SCNxLEAST32 "x"
#define SCNxLEAST64 "llx"
#define SCNxFAST8 "hhx"
#define SCNxFAST16 "hx"
#define SCNxFAST32 "x"
#define SCNxFAST64 "llx"
#define SCNxMAX "llx"
#define SCNxPTR "x"
#endif /* __ARCH_CEVA_INCLUDE_INTTYPES_H */

78
arch/ceva/include/irq.h Normal file
View file

@ -0,0 +1,78 @@
/****************************************************************************
* arch/ceva/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 directed but, rather, only indirectly
* through nuttx/irq.h
*/
#ifndef __ARCH_CEVA_INCLUDE_IRQ_H
#define __ARCH_CEVA_INCLUDE_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
/* Include chip-specific IRQ definitions (including IRQ numbers) */
#include <arch/chip/irq.h>
/* Include CEVA architecture-specific IRQ definitions (including register
* save structure and up_irq_save()/up_irq_restore() functions)
*/
#if defined(CONFIG_ARCH_XC5)
# include <arch/xc5/irq.h>
#elif defined(CONFIG_ARCH_XM6)
# include <arch/xm6/irq.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define IRQ_VINT0 (IRQ_VINT_FIRST + 0)
#define IRQ_VINT1 (IRQ_VINT_FIRST + 1)
#define IRQ_VINT2 (IRQ_VINT_FIRST + 2)
#define IRQ_VINT3 (IRQ_VINT_FIRST + 3)
#define IRQ_VINT4 (IRQ_VINT_FIRST + 4)
#define IRQ_VINT5 (IRQ_VINT_FIRST + 5)
#define IRQ_VINT6 (IRQ_VINT_FIRST + 6)
#define IRQ_VINT7 (IRQ_VINT_FIRST + 7)
#define IRQ_VINT8 (IRQ_VINT_FIRST + 8)
#define IRQ_VINT9 (IRQ_VINT_FIRST + 9)
#define IRQ_VINT10 (IRQ_VINT_FIRST + 10)
#define IRQ_VINT11 (IRQ_VINT_FIRST + 11)
#define IRQ_VINT12 (IRQ_VINT_FIRST + 12)
#define IRQ_VINT13 (IRQ_VINT_FIRST + 13)
#define IRQ_VINT14 (IRQ_VINT_FIRST + 14)
#define IRQ_VINT15 (IRQ_VINT_FIRST + 15)
#define IRQ_VINT16 (IRQ_VINT_FIRST + 16)
#define IRQ_VINT17 (IRQ_VINT_FIRST + 17)
#define IRQ_VINT18 (IRQ_VINT_FIRST + 18)
#define IRQ_VINT19 (IRQ_VINT_FIRST + 19)
#define IRQ_VINT20 (IRQ_VINT_FIRST + 20)
#define IRQ_VINT21 (IRQ_VINT_FIRST + 21)
#define IRQ_VINT22 (IRQ_VINT_FIRST + 22)
#define IRQ_VINT23 (IRQ_VINT_FIRST + 23)
#define IRQ_VINT24 (IRQ_VINT_FIRST + 24)
#define IRQ_VINT25 (IRQ_VINT_FIRST + 25)
#define IRQ_VINT26 (IRQ_VINT_FIRST + 26)
#endif /* __ARCH_CEVA_INCLUDE_IRQ_H */

View file

@ -0,0 +1,40 @@
/****************************************************************************
* arch/ceva/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_CEVA_INCLUDE_LIMITS_H
#define __ARCH_CEVA_INCLUDE_LIMITS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include_next <limits.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Assume ILP32 or LP64 */
#define PTR_MIN LONG_MIN
#define PTR_MAX LONG_MAX
#define UPTR_MAX ULONG_MAX
#endif /* __ARCH_CEVA_INCLUDE_LIMITS_H */

34
arch/ceva/include/math.h Normal file
View file

@ -0,0 +1,34 @@
/****************************************************************************
* arch/ceva/include/math.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_CEVA_INCLUDE_MATH_H
#define __ARCH_CEVA_INCLUDE_MATH_H
/****************************************************************************
* Included Files
****************************************************************************/
#if defined(CONFIG_ARCH_XC5)
# include <arch/xc5/math.h>
#elif defined(CONFIG_ARCH_XM6)
# include <arch/xm6/math.h>
#endif
#endif /* __ARCH_CEVA_INCLUDE_MATH_H */

View file

@ -0,0 +1,106 @@
/****************************************************************************
* arch/ceva/include/spinlock.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_CEVA_INCLUDE_SPINLOCK_H
#define __ARCH_CEVA_INCLUDE_SPINLOCK_H
/****************************************************************************
* Included Files
****************************************************************************/
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif /* __ASSEMBLY__ */
#if defined(CONFIG_ARCH_XC5)
# include <arch/xc5/spinlock.h>
#elif defined(CONFIG_ARCH_XM6)
# include <arch/xm6/spinlock.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Spinlock states */
#define SP_UNLOCKED 0 /* The Unlocked state */
#define SP_LOCKED 1 /* The Locked state */
/* Memory barriers for use with NuttX spinlock logic
*
* Data Memory Barrier (DMB) acts as a memory barrier. It ensures that all
* explicit memory accesses that appear in program order before the DMB
* instruction are observed before any explicit memory accesses that appear
* in program order after the DMB instruction. It does not affect the
* ordering of any other instructions executing on the processor
*
* Data Synchronization Barrier (DSB) acts as a special kind of memory
* barrier. No instruction in program order after this instruction executes
* until this instruction completes. This instruction completes when: (1) All
* explicit memory accesses before this instruction complete, and (2) all
* Cache, Branch predictor and TLB maintenance operations before this
* instruction complete.
*
*/
#define SP_DSB(n) up_dsb()
#define SP_DMB(n) up_dmb()
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/* The Type of a spinlock. */
typedef uint32_t spinlock_t;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logoic.
*
* Input Parameters:
* lock - The address of spinlock object.
*
* Returned Value:
* The spinlock is always locked upon return. The value of previous value
* of the spinlock variable is returned, either SP_LOCKED if the spinlock
* as previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock)
*
****************************************************************************/
/* See prototype in nuttx/include/nuttx/spinlock.h */
/* Include CEVA architecture-specific spinlock definitions */
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_INCLUDE_SPINLOCK_H */

View file

@ -0,0 +1,42 @@
/****************************************************************************
* arch/ceva/include/stdarg.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_CEVA_INCLUDE_STDARG_H
#define __ARCH_CEVA_INCLUDE_STDARG_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdarg.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Redefine va_copy since:
* 1.TL4 doesn't define it at all
* 2.XM6/X2 generate the wrong code
*/
#undef va_copy
#define va_copy(d,s) ((d) = (s))
#endif /* __ARCH_CEVA_INCLUDE_STDARG_H */

110
arch/ceva/include/syscall.h Normal file
View file

@ -0,0 +1,110 @@
/****************************************************************************
* arch/ceva/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 directed but, rather, only indirectly
* through include/syscall.h or include/sys/sycall.h
*/
#ifndef __ARCH_CEVA_INCLUDE_SYSCALL_H
#define __ARCH_CEVA_INCLUDE_SYSCALL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Inline functions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* TRAP call with SYS_ call number and no parameters */
uintptr_t sys_call0(unsigned int nbr);
/* TRAP call with SYS_ call number and one parameter */
uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1);
/* TRAP call with SYS_ call number and two parameters */
uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2);
/* TRAP call with SYS_ call number and three parameters */
uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3);
/* TRAP call with SYS_ call number and four parameters */
uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4);
/* TRAP call with SYS_ call number and five parameters */
uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5);
/* TRAP call with SYS_ call number and six parameters */
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);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif
#endif /* __ARCH_CEVA_INCLUDE_SYSCALL_H */

74
arch/ceva/include/tls.h Normal file
View file

@ -0,0 +1,74 @@
/****************************************************************************
* arch/ceva/include/tls.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_CEVA_INCLUDE_TLS_H
#define __ARCH_CEVA_INCLUDE_TLS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#ifdef CONFIG_TLS
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Name: up_tls_info
*
* Description:
* Return the TLS information structure for the currently executing thread.
* When TLS is enabled, up_createstack() will align allocated stacks to
* the TLS_STACK_ALIGN value. An instance of the following structure will
* be implicitly positioned at the "lower" end of the stack. Assuming a
* "push down" stack, this is at the "far" end of the stack (and can be
* clobbered if the stack overflows).
*
* If an MCU has a "push up" then that TLS structure will lie at the top
* of the stack and stack allocation and initialization logic must take
* care to preserve this structure content.
*
* The stack memory is fully accessible to user mode threads.
*
* Input Parameters:
* None
*
* Returned Value:
* A pointer to TLS info structure at the beginning of the STACK memory
* allocation. This is essentially an application of the TLS_INFO(sp)
* macro and has a platform dependency only in the manner in which the
* stack pointer (sp) is obtained and interpreted.
*
****************************************************************************/
static inline FAR struct tls_info_s *up_tls_info(void)
{
DEBUGASSERT(!up_interrupt_context());
return TLS_INFO((uintptr_t)up_getsp());
}
#endif /* CONFIG_TLS */
#endif /* __ARCH_CEVA_INCLUDE_TLS_H */

96
arch/ceva/include/types.h Normal file
View file

@ -0,0 +1,96 @@
/****************************************************************************
* arch/ceva/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 directed but, rather, only indirectly
* through sys/types.h
*/
#ifndef __ARCH_CEVA_INCLUDE_TYPES_H
#define __ARCH_CEVA_INCLUDE_TYPES_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* 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 int _int32_t;
typedef unsigned int _uint32_t;
typedef signed long long _int64_t;
typedef unsigned long long _uint64_t;
#define __INT64_DEFINED
/* 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 up_irq_save(). */
typedef unsigned int irqstate_t;
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* __ARCH_CEVA_INCLUDE_TYPES_H */

269
arch/ceva/include/xc5/irq.h Normal file
View file

@ -0,0 +1,269 @@
/****************************************************************************
* arch/ceva/include/xc5/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 directed but, rather, only indirectly
* through nuttx/irq.h
*/
#ifndef __ARCH_CEVA_INCLUDE_XC5_IRQ_H
#define __ARCH_CEVA_INCLUDE_XC5_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
/* Included implementation-dependent register save structure layouts */
#include <arch/xc5/reg.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* If this is kernel build, how many nested system calls should we support? */
#ifndef CONFIG_SYS_NNEST
# define CONFIG_SYS_NNEST 2
#endif
/* Alternate register names *************************************************/
#define REG_FP REG_G0
#define REG_LR REG_RETREG
#define REG_PC REG_RETREGI
#define REG_OM REG_MODQ
/* MODG: satuation */
#define REG_MODG_DEFAULT 0x001b
/* MODP: IRQ enable/disable */
#define REG_MODP_DEFAULT 0x3f80
#define REG_MODP_ENABLE 0x3f80
#define REG_MODP_DISABLE 0x0080
/* MOD2: Confirm C compiler assumption */
#define REG_MODPB_DEFAULT 0xf0 /* TRAPx */
/* MODQ: Operation mode */
#define REG_OM_DEFAULT 0x20 /* PI and Supervisor */
/* Note: this is POM filed not OM field */
#define REG_OM_KERNEL 0x00 /* Supervisor Mode */
#define REG_OM_USER 0x08 /* User0 Mode */
#define REG_OM_MASK 0x18 /* Mode mask */
/* First Level Interrupt (vectors 0-15) */
#define IRQ_RESET 0x00 /* Vector 0: Reset(not handler as an IRQ) */
#define IRQ_BOOT 0x01 /* Vector 1: Boot(not handler as an IRQ) */
#define IRQ_TRAP 0x02 /* Vector 2: Software interrupt */
#define IRQ_TRAPE 0x03 /* Vector 3: Emulation Software Interrupt */
#define IRQ_BI 0x03 /* Vector 3: Breakpoint Interrupt */
#define IRQ_CRCALL 0x03 /* Vector 3: Code Replacement Call */
#define IRQ_NMI 0x04 /* Vector 4: Non-Maskable Interrupt */
#define IRQ_INT0 0x05 /* Vector 5: Maskable Interrupt 0 */
#define IRQ_INT1 0x06 /* Vector 6: Maskable Interrupt 1 */
#define IRQ_INT2 0x07 /* Vector 7: Maskable Interrupt 2 */
#define IRQ_INT3 0x08 /* Vector 8: Maskable Interrupt 3 */
#define IRQ_INT4 0x09 /* Vector 9: Maskable Interrupt 4 */
#define IRQ_VINT 0x0a /* Vector 10: Vectored Interrupt */
#define IRQ_TRAP0 0x0b /* Vector 10: Software Interrupt 0 */
#define IRQ_TRAP1 0x0c /* Vector 11: Software Interrupt 1 */
#define IRQ_TRAP2 0x0d /* Vector 12: Software Interrupt 2 */
#define IRQ_TRAP3 0x0e /* Vector 13: Software Interrupt 3 */
#define IRQ_PABP 0x0f /* Vector 15: Program Address Breakpoint */
/* Second Level interrupts (vectors >= 16).
* These definitions are chip-specific
*/
#define IRQ_VINT_FIRST 16 /* Vector number of the first VINT interrupt */
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/* This structure represents the return state from a system call */
#ifdef CONFIG_LIB_SYSCALL
struct xcpt_syscall_s
{
uint32_t saved_pc;
};
#endif
/* The following structure is included in the TCB and defines the complete
* state of the thread.
*/
struct xcptcontext
{
#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
FAR void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/
uint32_t *saved_regs;
# ifdef CONFIG_BUILD_PROTECTED
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
uint32_t sigreturn;
# endif
#endif
#ifdef CONFIG_LIB_SYSCALL
/* The following array holds the return address
* needed to return from each nested system call.
*/
uint8_t nsyscalls;
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
#endif
/* 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.
*/
uint32_t *regs;
};
#endif
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
/* Name: up_irq_save, up_irq_restore, and friends.
*
* NOTE: This function should never be called from application code and,
* as a general rule unless you really know what you are doing, this
* function should not be called directly from operation system code either:
* Typically, the wrapper functions, enter_critical_section() and
* leave_critical section(), are probably what you really want.
*/
/* Get/set the MODp register, here is the irq related bits:
* Bit [0] Interrupt context for NMI (RW)
* Bit [1] Interrupt context for INT0 (RW)
* Bit [2] Interrupt context for INT1 (RW)
* Bit [3] Interrupt context for INT2 (RW)
* Bit [4] Interrupt context for INT3 (RW)
* Bit [5] Interrupt context for INT4 (RW)
* Bit [6] (Reserved)
* Bit [7] Interrupt Enable (RW)
* Bit [8] Interrupt mask for INT0 (RW)
* Bit [9] Interrupt mask for INT1 (RW)
* Bit [10] Interrupt mask for INT2 (RW)
* Bit [11] Interrupt mask for INT3 (RW)
* Bit [12] Interrupt mask for INT4 (RW)
* Bit [13] Interrupt mask for VINT (RW)
* Bit [14] (Reserved)
* Bit [15] Interrupt pending for INT0 (RO)
* Bit [16] Interrupt pending for INT1 (RO)
* Bit [17] Interrupt pending for INT2 (RO)
* Bit [18] Interrupt pending for INT3 (RO)
* Bit [19] Interrupt pending for INT3 (RO)
* Bit [20] Interrupt pending for VINT (RO)
* All writable bits are clear by hardware during reset.
*
* We manipulate the individual mask bits instead of global enable bit since:
* 1.Global IE not only mask INTX request but also mask TRAPX instruction.
* 2.Hardware always enable global IE after the interrupt return.
* Both behavior don't match the nuttx requirement.
*/
static inline uint32_t getmodp(void)
{
register uint32_t modp __asm__ ("r0");
__asm__ __volatile__("mov modp, %0\nnop\nnop" : "=r"(modp));
return modp;
}
static inline void setmodp(uint32_t modp_v)
{
__asm__ __volatile__("nop\nnop\nmov %0, r0\nnop\nnop" : : "r"(modp_v));
__asm__ __volatile__
(
"mov r0, modp\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"
);
}
static inline void up_irq_disable(void)
{
setmodp(REG_MODP_DISABLE);
}
static inline irqstate_t up_irq_save(void)
{
irqstate_t flags = getmodp();
up_irq_disable();
return flags;
}
static inline void up_irq_enable(void)
{
setmodp(REG_MODP_ENABLE);
}
static inline void up_irq_restore(irqstate_t flags)
{
setmodp(flags);
}
/****************************************************************************
* Name: up_getsp
****************************************************************************/
static inline uint32_t up_getsp(void)
{
uint32_t sp;
__asm__ __volatile__("nop\nmov sp, %0" : "=r"(sp));
return sp;
}
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_INCLUDE_XC5_IRQ_H */

View file

@ -0,0 +1,58 @@
/****************************************************************************
* arch/ceva/include/xc5/math.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_CEVA_INCLUDE_XC5_MATH_H
#define __ARCH_CEVA_INCLUDE_XC5_MATH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include_next <math.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
float roundf(float x);
double round (double x);
long double roundl(long double x);
double gamma(double x);
double lgamma(double x);
float log2f (float x);
double log2 (double x);
long double log2l (long double x);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ARCH_CEVA_INCLUDE_XC5_MATH_H */

143
arch/ceva/include/xc5/reg.h Normal file
View file

@ -0,0 +1,143 @@
/****************************************************************************
* arch/ceva/include/xc5/reg.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_CEVA_INCLUDE_XC5_REG_H
#define __ARCH_CEVA_INCLUDE_XC5_REG_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* IRQ Stack Frame Format: */
/* The following registers are stored by the interrupt handling
* logic.
*/
#define REG_SP 0
#define REG_BKNEST40 1
#define REG_BKNEST41 2
#define REG_BKNEST30 3
#define REG_BKNEST31 4
#define REG_BKNEST20 5
#define REG_BKNEST21 6
#define REG_MODU2D 7
#define REG_MODU3D 8
#define REG_G4D 9
#define REG_G5D 10
#define REG_G6D 11
#define REG_G7D 12
#define REG_A20 13
#define REG_A21 14
#define REG_A22 15
#define REG_A23 16
#define REG_AKLMNE 17
#define REG_RETREGN 18
#define REG_MODP 19
#define REG_MODQ 20
#define REG_A16 21
#define REG_A17 22
#define REG_A18 23
#define REG_A19 24
#define REG_AGHIJE 25
#define REG_S0 26
#define REG_S1 27
#define REG_S2 28
#define REG_G0 29
#define REG_G1 30
#define REG_G2 31
#define REG_G3 32
#define REG_R0 33
#define REG_R1 34
#define REG_R2 35
#define REG_R3 36
#define REG_RETREG 37
#define REG_RETREGB 38
#define REG_RETREGI 39
#define REG_A4 40
#define REG_A5 41
#define REG_A6 42
#define REG_A7 43
#define REG_A4567E 44
#define BKNEST10 45
#define BKNEST11 46
#define REG_S3 47
#define REG_A12 48
#define REG_A13 49
#define REG_A14 50
#define REG_A15 51
#define REG_ACDEFE 52
#define REG_MOD0 53
#define REG_MOD1 54
#define REG_MOD2 55
#define REG_MODG 56
#define REG_MOD3 57
#define REG_R4 58
#define REG_R5 59
#define REG_R6 60
#define REG_A8 61
#define REG_A9 62
#define REG_A10 63
#define REG_A11 64
#define REG_A89ABE 65
#define REG_BKNEST00 66
#define REG_BKNEST01 67
#define REG_MODU2 68
#define REG_MODU3 69
#define REG_G4 70
#define REG_G5 71
#define REG_G6 72
#define REG_G7 73
#define REG_R7 74
#define REG_A0 75
#define REG_A1 76
#define REG_A2 77
#define REG_A3 78
#define REG_A0123E 79
#define REG_MODU0 80
#define REG_MODU1 81
#define REG_RETREG2 82
/* The total number of registers is saved on the stack */
#define XCPTCONTEXT_REGS 83
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Inline functions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* __ARCH_CEVA_INCLUDE_XC5_REG_H */

View file

@ -0,0 +1,42 @@
/****************************************************************************
* arch/ceva/include/xc5/spinlock.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_CEVA_INCLUDE_XC5_SPINLOCK_H
#define __ARCH_CEVA_INCLUDE_XC5_SPINLOCK_H
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
/* Memory barrier doesn't need on tl4 */
static inline void up_dsb(void)
{
}
static inline void up_dmb(void)
{
}
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_INCLUDE_XC5_SPINLOCK_H */

259
arch/ceva/include/xm6/irq.h Normal file
View file

@ -0,0 +1,259 @@
/****************************************************************************
* arch/ceva/include/xm6/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 directed but, rather, only indirectly
* through nuttx/irq.h
*/
#ifndef __ARCH_CEVA_INCLUDE_XM6_IRQ_H
#define __ARCH_CEVA_INCLUDE_XM6_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
/* Included implementation-dependent register save structure layouts */
#include <arch/xm6/reg.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* If this is kernel build, how many nested system calls should we support? */
#ifndef CONFIG_SYS_NNEST
# define CONFIG_SYS_NNEST 2
#endif
/* Alternate register names *************************************************/
#define REG_A0 REG_R0
#define REG_A1 REG_R1
#define REG_A2 REG_R2
#define REG_A3 REG_R3
#define REG_A4 REG_R4
#define REG_A5 REG_R5
#define REG_A6 REG_R6
#define REG_FP REG_R8
#define REG_LR REG_RETREG
#define REG_PC REG_RETREGI
#define REG_OM REG_MODC /* Operation Mode */
/* MODA: IRQ enable/disable */
#define REG_MODA_DEFAULT 0x07f0
#define REG_MODA_ENABLE 0x07f0
#define REG_MODA_DISABLE 0x0010
/* MODC: Operation mode */
#define REG_OM_DEFAULT 0x20 /* PI and Supervisor */
/* Note: this is POM field not OM field */
#define REG_OM_KERNEL 0x00 /* Supervisor Mode */
#define REG_OM_USER 0x08 /* User0 Mode */
#define REG_OM_MASK 0x18 /* Mode Mask */
/* First Level Interrupt (vectors 0-15) */
#define IRQ_RESET 0x00 /* Vector 0: Reset(not handler as an IRQ) */
#define IRQ_BOOT 0x01 /* Vector 1: Boot(not handler as an IRQ) */
#define IRQ_TRAP 0x02 /* Vector 2: Software Interrupt */
#define IRQ_TRAPE 0x03 /* Vector 3: Emulation Software Interrupt */
#define IRQ_BI 0x03 /* Vector 3: Breakpoint Interrupt */
#define IRQ_NMI 0x04 /* Vector 4: Non-Maskable Interrupt */
#define IRQ_INT0 0x05 /* Vector 5: Maskable Interrupt 0 */
#define IRQ_INT1 0x06 /* Vector 6: Maskable Interrupt 1 */
#define IRQ_INT2 0x07 /* Vector 7: Maskable Interrupt 2 */
#define IRQ_INT3 0x08 /* Vector 8: Maskable Interrupt 3 */
#define IRQ_INT4 0x09 /* Vector 9: Maskable Interrupt 4 */
#define IRQ_VINT 0x0a /* Vector 10: Vectored Interrupt */
#define IRQ_TRAP0 0x0b /* Vector 11: Software Interrupt 0 */
#define IRQ_TRAP1 0x0c /* Vector 12: Software Interrupt 1 */
#define IRQ_TRAP2 0x0d /* Vector 13: Software Interrupt 2 */
#define IRQ_TRAP3 0x0e /* Vector 14: Software Interrupt 3 */
#define IRQ_PABP 0x03 /* Vector 3: Program Address Breakpoint */
/* Second Level interrupts (vectors >= 16).
* These definitions are chip-specific.
*/
#define IRQ_VINT_FIRST 16 /* Vector number of the first VINT interrupt */
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/* This structure represents the return state from a system call */
#ifdef CONFIG_LIB_SYSCALL
struct xcpt_syscall_s
{
uint32_t saved_pc;
uint32_t saved_om;
};
#endif
/* The following structure is included in the TCB and defines the complete
* state of the thread.
*/
struct xcptcontext
{
#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
FAR void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of the context used during
* signal processing.
*/
uint32_t *saved_regs;
# ifdef CONFIG_BUILD_PROTECTED
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
uint32_t sigreturn;
# endif
#endif
#ifdef CONFIG_LIB_SYSCALL
/* The following array holds the return address and operation mode
* needed to return from each nested system call.
*/
uint8_t nsyscalls;
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
#endif
/* 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.
*/
uint32_t *regs;
};
#endif
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
/* Name: up_irq_save, up_irq_restore, and friends.
*
* NOTE: This function should never be called from application code and,
* as a general rule unless you really know what you are doing, this
* function should not be called directly from operation system code either:
* Typically, the wrapper functions, enter_critical_section() and
* leave_critical section(), are probably what you really want.
*/
/* Get/set the MODA register, here is the irq related bits:
* Bit [4] Interrupt enable (RW)
* Bit [5] Interrupt mask for INT0 (RW)
* Bit [6] Interrupt mask for INT1 (RW)
* Bit [7] Interrupt mask for INT2 (RW)
* Bit [8] Interrupt mask for INT3 (RW)
* Bit [9] Interrupt mask for INT4 (RW)
* Bit [10] Interrupt mask for VINT (RW)
* Bit [11] Interrupt pending for INT0 (RO)
* Bit [12] Interrupt pending for INT1 (RO)
* Bit [13] Interrupt pending for INT2 (RO)
* Bit [14] Interrupt pending for INT3 (RO)
* Bit [15] Interrupt pending for INT4 (RO)
* Bit [16] Interrupt pending for INTV (RO)
* All writable bits are clear by hardware during reset.
*
* We manipulate the individual mask bits instead of global enable bit since:
* 1.Global IE not only mask INTX request but also mask TRAPX instruction.
* 2.Hardware always enable global IE after the interrupt return.
* Both behavior don't match the nuttx requirement.
*/
static inline uint32_t getmoda(void)
{
uint32_t moda;
__asm__ __volatile__("mov moda.ui, %0.ui\nnop #0x02" : "=r"(moda));
return moda;
}
static inline void setmoda(uint32_t moda)
{
__asm__ __volatile__("nop #0x04\nnop\nmovp %0.ui, moda.ui" : : "r"(moda));
}
static inline void up_irq_disable(void)
{
setmoda(REG_MODA_DISABLE);
}
static inline irqstate_t up_irq_save(void)
{
irqstate_t flags = getmoda();
up_irq_disable();
return flags;
}
static inline void up_irq_enable(void)
{
setmoda(REG_MODA_ENABLE);
}
static inline void up_irq_restore(irqstate_t flags)
{
setmoda(flags);
}
/****************************************************************************
* Name: up_getsp
****************************************************************************/
static inline uint32_t up_getsp(void)
{
uint32_t sp;
__asm__ __volatile__("mov sp.ui, %0.ui" : "=r"(sp));
return sp;
}
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_INCLUDE_XM6_IRQ_H */

View file

@ -0,0 +1,58 @@
/****************************************************************************
* arch/ceva/include/xm6/math.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_CEVA_INCLUDE_XM6_MATH_H
#define __ARCH_CEVA_INCLUDE_XM6_MATH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include_next <math.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
float roundf(float x);
double round (double x);
long double roundl(long double x);
double gamma(double x);
double lgamma(double x);
float log2f (float x);
double log2 (double x);
long double log2l (long double x);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ARCH_CEVA_INCLUDE_XM6_MATH_H */

139
arch/ceva/include/xm6/reg.h Normal file
View file

@ -0,0 +1,139 @@
/****************************************************************************
* arch/ceva/include/xm6/reg.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_CEVA_INCLUDE_XM6_REG_H
#define __ARCH_CEVA_INCLUDE_XM6_REG_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* IRQ Stack Frame Format: */
/* The following registers are stored by the interrupt handling
* logic.
*/
#define REG_SP 0
#define REG_MODI 1
#define REG_MODG 2
#define REG_MODE 3
#define REG_MODD 4
#define REG_MODC 5
#define REG_MODA 6
#define REG_R56 7
#define REG_R57 8
#define REG_R58 9
#define REG_R59 10
#define REG_R60 11
#define REG_R61 12
#define REG_R62 13
#define REG_R63 14
#define REG_R48 15
#define REG_R49 16
#define REG_R50 17
#define REG_R51 18
#define REG_R52 19
#define REG_R53 20
#define REG_R54 21
#define REG_R55 22
#define REG_R40 23
#define REG_R41 24
#define REG_R42 25
#define REG_R43 26
#define REG_R44 27
#define REG_R45 28
#define REG_R46 29
#define REG_R47 30
#define REG_R32 31
#define REG_R33 32
#define REG_R34 33
#define REG_R35 34
#define REG_R36 35
#define REG_R37 36
#define REG_R38 37
#define REG_R39 38
#define REG_R24 39
#define REG_R25 40
#define REG_R26 41
#define REG_R27 42
#define REG_R28 43
#define REG_R29 44
#define REG_R30 45
#define REG_R31 46
#define REG_R16 47
#define REG_R17 48
#define REG_R18 49
#define REG_R19 50
#define REG_R20 51
#define REG_R21 52
#define REG_R22 53
#define REG_R23 54
#define REG_R8 55
#define REG_R9 56
#define REG_R10 57
#define REG_R11 58
#define REG_R12 59
#define REG_R13 60
#define REG_R14 61
#define REG_R15 62
#define REG_R0 63
#define REG_R1 64
#define REG_R2 65
#define REG_R3 66
#define REG_R4 67
#define REG_R5 68
#define REG_R6 69
#define REG_R7 70
#define REG_RETREGN 71
#define REG_RETREG 72
#define REG_RETREG_TEMP 73
#define REG_RETREGI 74
#define REG_MODVL0 75
#define REG_MODVL1 76
#define REG_MODVLL 77
#define REG_MODVFP 78
/* The total number of registers is saved on the stack */
#define XCPTCONTEXT_REGS 79
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Inline functions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* __ARCH_CEVA_INCLUDE_XM6_REG_H */

View file

@ -0,0 +1,160 @@
/****************************************************************************
* arch/ceva/include/xm6/spinlock.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_CEVA_INCLUDE_XM6_SPINLOCK_H
#define __ARCH_CEVA_INCLUDE_XM6_SPINLOCK_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <arch/xm6/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SP_SECTION __attribute__ ((section(".DSECT spinlock")))
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
static inline void up_dsb(void)
{
/* MSS_BARRIER(0x638):
* Bit [7] Internal Barrier Activation
*/
#define MSS_BARRIER 0x638
uint32_t barrier = 0x80;
__asm__ __volatile__
(
"out {cpm} %0.ui, (%1.ui).ui"
: : "r"(barrier), "r"(MSS_BARRIER)
);
do
{
__asm__ __volatile__
(
"in {cpm} (%1.ui).ui, %0.ui\n"
"nop #0x04\nnop #0x02"
: "=r"(barrier)
: "r"(MSS_BARRIER)
);
/* Wait unitl the barrier operation complete */
}
while ((barrier & 0x80) != 0);
#undef MSS_BARRIER
}
static inline void up_dmb(void)
{
up_dsb(); /* use dsb instead since dmb doesn't exist on xm6 */
}
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logoic.
*
* Input Parameters:
* lock - The address of spinlock object.
*
* Returned Value:
* The spinlock is always locked upon return. The value of previous value
* of the spinlock variable is returned, either SP_LOCKED if the spinlock
* as previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock)
*
****************************************************************************/
static inline spinlock_t up_testset(volatile FAR spinlock_t *lock)
{
irqstate_t flags;
spinlock_t old;
/* Disable the interrupt */
flags = up_irq_save();
while (1)
{
uint32_t modc = 0;
/* Issue exclusive read */
__asm__ __volatile__
(
"nop\n"
"LS0.ld (%1.ui).ui, %0.ui || monitor {on}\n"
"nop #0x02"
: "=r"(old)
: "r"(lock)
);
/* Is it already locked by other? */
if (old == SP_LOCKED)
{
break; /* Yes, exit */
}
/* Not yet, issue exclusive write */
__asm__ __volatile__
(
"LS1.st %2.ui, (%1.ui).ui || monitor {off}\n"
"mov modc.ui, %0.ui\n"
"nop"
: "=r"(modc)
: "r"(lock), "r"(SP_LOCKED)
: "memory"
);
/* Exclusive write success? */
if ((modc & 0x01) == 0) /* Bit[0] Monitor status */
{
break; /* Yes, we are done */
}
/* Fail, let's try again */
}
/* Restore the interrupt */
up_irq_restore(flags);
return old;
}
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_INCLUDE_XM6_SPINLOCK_H */

5
arch/ceva/src/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
/.depend
/Make.dep
/locked.r
/board
/chip

216
arch/ceva/src/Makefile Normal file
View file

@ -0,0 +1,216 @@
############################################################################
# arch/ceva/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$(DELIM)Make.defs
ifeq ($(CONFIG_ARCH_XC5),y)
ARCH_SUBDIR = xc5
else ifeq ($(CONFIG_ARCH_XM6),y)
ARCH_SUBDIR = xm6
endif
CPPFLAGS += $(EXTRADEFINES)
CFLAGS += $(EXTRADEFINES)
CXXFLAGS += $(EXTRADEFINES)
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src
NUTTX = "$(OUTDIR)\nuttx$(EXEEXT)"
CFLAGS += -I$(ARCH_SRCDIR)\chip
CFLAGS += -I$(ARCH_SRCDIR)\common
CFLAGS += -I$(ARCH_SRCDIR)\$(ARCH_SUBDIR)
CFLAGS += -I$(ARCH_SRCDIR)\$(CONFIG_ARCH_CHIP)
CFLAGS += -I$(TOPDIR)\sched
else
ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src
ifeq ($(WINTOOL),y)
NUTTX = "${shell cygpath -w $(OUTDIR)/nuttx$(EXEEXT)}"
CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}"
CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}"
CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}"
CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(CONFIG_ARCH_CHIP)}"
CFLAGS += -I "${shell cygpath -w $(TOPDIR)/sched}"
LDSCRIPT := ${shell cygpath -m $(LDSCRIPT)}
else
NUTTX = "$(OUTDIR)/nuttx$(EXEEXT)"
CFLAGS += -I$(ARCH_SRCDIR)/chip
CFLAGS += -I$(ARCH_SRCDIR)/common
CFLAGS += -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR)
CFLAGS += -I$(ARCH_SRCDIR)/$(CONFIG_ARCH_CHIP)
CFLAGS += -I$(TOPDIR)/sched
endif
endif
# The "head" object
HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT))
STARTUP_OBJS ?= $(HEAD_OBJ)
# 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)
UBIN = libuarch$(LIBEXT)
BIN = libarch$(LIBEXT)
EXTRA_LIBS ?=
EXTRA_LIBPATHS ?=
LINKLIBS ?=
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
BOARDMAKE = $(if $(wildcard .\board\Makefile),y,)
LIBPATHS += -I "$(OUTDIR)\staging"
ifeq ($(BOARDMAKE),y)
LIBPATHS += -I "$(OUTDIR)\arch\$(CONFIG_ARCH)\src\board"
endif
else
BOARDMAKE = $(if $(wildcard ./board/Makefile),y,)
ifeq ($(WINTOOL),y)
LIBPATHS += -I "${shell cygpath -w "$(OUTDIR)/staging"}"
ifeq ($(BOARDMAKE),y)
LIBPATHS += -I "${shell cygpath -w "$(OUTDIR)/arch/$(CONFIG_ARCH)/src/board"}"
endif
else
LIBPATHS += -I "$(OUTDIR)/staging"
ifeq ($(BOARDMAKE),y)
LIBPATHS += -I "$(OUTDIR)/arch/$(CONFIG_ARCH)/src/board"
endif
endif
endif
LDLIBS = $(patsubst %, -lib %,$(LINKLIBS))
ifeq ($(BOARDMAKE),y)
LDLIBS += -lib libboard.lib
endif
VPATH += .
VPATH += chip
VPATH += common
VPATH += $(ARCH_SUBDIR)
VPATH := $(patsubst %,:$(SRCDIR)$(DELIM)%,$(VPATH))
ifeq ($(WINTOOL),y)
VPATH += :$(shell cygpath -m $(OUTDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)chip)
else
VPATH += :$(OUTDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)chip
endif
all: $(HEAD_OBJ) $(BIN)
.PHONY: board$(DELIM)libboard$(LIBEXT)
$(sort $(AOBJS) $(UAOBJS) $(HEAD_OBJ)): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(sort $(COBJS) $(UCOBJS)): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
$(BIN) $(KBIN): $(OBJS)
$(call ARCHIVE, $@, $(OBJS))
$(UBIN): $(UOBJS)
$(call ARCHIVE, $@, $(UOBJS))
board$(DELIM)libboard$(LIBEXT):
ifeq ($(CONFIG_ARCH_XC5), y)
$(Q) if [ ! -L "$(CROSSDEV)/cevaxccc-xdrv" ]; then \
ln -sf "$(CROSSDEV)/cevaxccc-drv" "$(CROSSDEV)/cevaxccc-xdrv";\
fi
endif
$(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES)
nuttx$(EXEEXT): $(HEAD_OBJ) board$(DELIM)libboard$(LIBEXT) $(LDSCRIPT)
$(Q) echo "LD: nuttx"
$(Q) $(call PREPROCESS, $(LDSCRIPT), $(notdir $(LDSCRIPT)))
$(Q) $(LD) $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \
-o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \
$(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) \
-l $(OUTDIR)$(DELIM)nuttx.lin $(notdir $(LDSCRIPT))
$(Q) $(DISASM) -o $(OUTDIR)$(DELIM)nuttx.lst $(NUTTX)
$(Q) $(OBJDUMP) $(NUTTX) > $(OUTDIR)$(DELIM)nuttx.dump
$(Q) $(OBJCOPY) -b $(OUTDIR)$(DELIM)nuttx -c -split $(NUTTX)
# 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: board$(DELIM)libboard$(LIBEXT) $(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
.depend: Makefile chip$(DELIM)Make.defs $(SRCS)
ifeq ($(BOARDMAKE),y)
$(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend
endif
$(Q) $(MKDEP) $(patsubst %,--dep-path %,$(subst :, ,$(VPATH))) \
"$(CC)" -- $(CFLAGS) -- $^ >Make.dep
$(Q) touch $@
depend: .depend
clean:
ifeq ($(BOARDMAKE),y)
$(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean
endif
$(call DELFILE, $(notdir $(LDSCRIPT)))
$(call DELFILE, $(KBIN))
$(call DELFILE, $(UBIN))
$(call DELFILE, $(BIN))
$(call CLEAN)
distclean: clean
ifeq ($(BOARDMAKE),y)
$(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean
endif
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
-include Make.dep

145
arch/ceva/src/common/mpu.h Normal file
View file

@ -0,0 +1,145 @@
/****************************************************************************
* arch/ceva/src/common/mpu.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_CEVA_SRC_COMMON_MPU_H
#define __ARCH_CEVA_SRC_COMMON_MPU_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <sys/types.h>
# include <stdbool.h>
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
#ifdef CONFIG_ARCH_MPU
/****************************************************************************
* Name: mpu_control
*
* Description:
* Configure and enable (or disable) the MPU
*
****************************************************************************/
void mpu_control(bool enable);
/****************************************************************************
* Name: mpu_user_code
*
* Description:
* Configure a region for user code
*
****************************************************************************/
void mpu_user_code(const void *base, size_t size);
/****************************************************************************
* Name: mpu_priv_code
*
* Description:
* Configure a region for privileged code
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void mpu_priv_code(const void *base, size_t size);
/****************************************************************************
* Name: mpu_user_data
*
* Description:
* Configure a region as user data
*
****************************************************************************/
void mpu_user_data(void *base, size_t size);
/****************************************************************************
* Name: mpu_priv_data
*
* Description:
* Configure a region as privileged data
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void mpu_priv_data(void *base, size_t size);
/****************************************************************************
* Name: mpu_peripheral
*
* Description:
* Configure a region as privileged peripheral address space
*
****************************************************************************/
void mpu_peripheral(void *base, size_t size);
/****************************************************************************
* Name: mpu_stronglyordered
*
* Description:
* Configure a region for privileged, strongly ordered memory
*
****************************************************************************/
void mpu_stronglyordered(void *base, size_t size);
#else
#define mpu_control(enable)
#define mpu_user_code(base, size)
#define mpu_priv_code(base, size)
#define mpu_user_data(base, size)
#define mpu_priv_data(base, size)
#define mpu_peripheral(base, size)
#define mpu_stronglyordered(base, size)
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_SRC_COMMON_MPU_H */

View file

@ -0,0 +1,130 @@
/****************************************************************************
* arch/ceva/src/common/svcall.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_CEVA_SRC_COMMON_SVCALL_H
#define __ARCH_CEVA_SRC_COMMON_SVCALL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <syscall.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* 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_PROTECTED is defined, then four more syscall values
* must be reserved.
*/
#ifdef CONFIG_LIB_SYSCALL
# ifdef CONFIG_BUILD_PROTECTED
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 8"
# elif CONFIG_SYS_RESERVED != 8
# error "CONFIG_SYS_RESERVED must have the value 8"
# endif
# else
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 4"
# elif CONFIG_SYS_RESERVED != 4
# error "CONFIG_SYS_RESERVED must have the value 4"
# endif
# endif
#endif
/* CEVA system calls ********************************************************/
/* SYS call 0:
*
* int up_saveusercontext(uint32_t *saveregs);
*/
#define SYS_save_context 0x00
/* SYS call 1:
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*/
#define SYS_restore_context 0x01
/* SYS call 2:
*
* void up_switchcontext(uint32_t **saveregs, uint32_t *restoreregs);
*/
#define SYS_switch_context 0x02
#ifdef CONFIG_LIB_SYSCALL
/* SYS call 3:
*
* void up_syscall_return(void);
*/
#define SYS_syscall_return 0x03
#ifdef CONFIG_BUILD_PROTECTED
/* SYS call 4:
*
* void up_task_start(main_t taskentry, int argc, FAR char *argv[])
* noreturn_function;
*/
#define SYS_task_start 0x04
/* SYS call 5:
*
* void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
* noreturn_function
*/
#define SYS_pthread_start 0x05
/* SYS call 6:
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
* FAR siginfo_t *info, FAR void *ucontext);
*/
#define SYS_signal_handler 0x06
/* SYS call 7:
*
* void signal_handler_return(void);
*/
#define SYS_signal_handler_return 0x07
#endif /* CONFIG_BUILD_PROTECTED */
#endif /* CONFIG_LIB_SYSCALL */
/****************************************************************************
* Inline Functions
****************************************************************************/
#endif /* __ARCH_CEVA_SRC_COMMON_SVCALL_H */

View file

@ -0,0 +1,76 @@
/****************************************************************************
* arch/ceva/src/common/up_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.
*
****************************************************************************/
#ifndef ___ARCH_CEVA_SRC_COMMON_UP_ARCH_H
#define ___ARCH_CEVA_SRC_COMMON_UP_ARCH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Inline Functions
****************************************************************************/
#ifndef __ASSEMBLY__
# 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))
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* Atomic modification of registers */
void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits);
void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits);
void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* ___ARCH_CEVA_SRC_COMMON_UP_ARCH_H */

View file

@ -0,0 +1,372 @@
/****************************************************************************
* arch/ceva/src/common/up_assert.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 <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/usb/usbdev_trace.h>
#include "sched/sched.h"
#include "irq/irq.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* USB trace dumping */
#ifndef CONFIG_USBDEV_TRACE
# undef CONFIG_ARCH_USBDUMP
#endif
#ifndef CONFIG_BOARD_RESET_ON_ASSERT
# define CONFIG_BOARD_RESET_ON_ASSERT 0
#endif
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_ARCH_STACKDUMP
static uint32_t s_last_regs[XCPTCONTEXT_REGS];
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_stackdump
****************************************************************************/
#ifdef CONFIG_ARCH_STACKDUMP
static void up_stackdump(uint32_t sp, uint32_t stack_base)
{
uint32_t stack;
for (stack = sp; stack < stack_base; stack += 8 * sizeof(uint32_t))
{
uint32_t *ptr = (uint32_t *)stack;
_alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
stack, ptr[0], ptr[1], ptr[2], ptr[3],
ptr[4], ptr[5], ptr[6], ptr[7]);
}
}
#else
# define up_stackdump(sp, stack_base)
#endif
/****************************************************************************
* Name: up_taskdump
****************************************************************************/
#ifdef CONFIG_STACK_COLORATION
static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg)
{
/* Dump interesting properties of this task */
#if CONFIG_TASK_NAME_SIZE > 0
_alert("%s: PID=%d Stack Used=%lu of %lu\n",
tcb->name, tcb->pid, up_check_tcbstack(tcb),
tcb->adj_stack_size);
#else
_alert("PID: %d Stack Used=%lu of %lu\n",
tcb->pid, up_check_tcbstack(tcb),
tcb->adj_stack_size);
#endif
}
#endif
/****************************************************************************
* Name: up_showtasks
****************************************************************************/
#ifdef CONFIG_STACK_COLORATION
static inline void up_showtasks(void)
{
/* Dump interesting properties of each task in the crash environment */
sched_foreach(up_taskdump, NULL);
}
#else
# define up_showtasks()
#endif
/****************************************************************************
* Name: up_registerdump
****************************************************************************/
#ifdef CONFIG_ARCH_STACKDUMP
static inline void up_registerdump(void)
{
volatile uint32_t *regs = CURRENT_REGS;
int rx;
/* Are user registers available from interrupt processing? */
if (regs == NULL)
{
/* No.. capture user registers by hand */
up_saveusercontext(s_last_regs);
regs = s_last_regs;
}
/* Dump the interrupt registers */
for (rx = 0; rx < XCPTCONTEXT_REGS; rx += 8)
{
_alert("R%03d: %08x %08x %08x %08x %08x %08x %08x %08x\n",
rx, regs[rx], regs[rx + 1], regs[rx + 2], regs[rx + 3],
regs[rx + 4], regs[rx + 5], regs[rx + 6], regs[rx + 7]);
}
}
#else
# define up_registerdump()
#endif
/****************************************************************************
* Name: assert_tracecallback
****************************************************************************/
#ifdef CONFIG_ARCH_USBDUMP
static int usbtrace_syslog(FAR const char *fmt, ...)
{
va_list ap;
int ret;
/* Let nx_vsyslog do the real work */
va_start(ap, fmt);
ret = nx_vsyslog(LOG_EMERG, fmt, &ap);
va_end(ap);
return ret;
}
static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg)
{
usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value);
return 0;
}
#endif
/****************************************************************************
* Name: up_dumpstate
****************************************************************************/
#ifdef CONFIG_ARCH_STACKDUMP
static void up_dumpstate(void)
{
struct tcb_s *rtcb = running_task();
uint32_t sp = up_getsp();
uint32_t ustackbase;
uint32_t ustacksize;
uint32_t istackbase;
uint32_t istacksize;
/* Dump the registers (if available) */
up_registerdump();
/* Get the limits on the user stack memory */
ustackbase = (uint32_t)rtcb->adj_stack_ptr;
ustacksize = rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
istackbase = (uint32_t)&g_intstackbase;
istacksize = &g_intstackbase - &g_intstackalloc;
/* Show interrupt stack info */
_alert("sp: %08x\n", sp);
_alert("IRQ stack:\n");
_alert(" base: %08x\n", istackbase);
_alert(" size: %08x\n", istacksize);
#ifdef CONFIG_STACK_COLORATION
_alert(" used: %08x\n", up_check_intstack());
#endif
/* Does the current stack pointer lie within the interrupt
* stack?
*/
if (sp <= istackbase && sp > istackbase - istacksize)
{
/* Yes.. dump the interrupt stack */
up_stackdump(sp, istackbase);
}
else if (CURRENT_REGS)
{
_alert("ERROR: Stack pointer is not within the interrupt stack\n");
up_stackdump(istackbase - istacksize, istackbase);
}
/* Extract the user stack pointer if we are in an interrupt handler.
* If we are not in an interrupt handler. Then sp is the user stack
* pointer (and the above range check should have failed).
*/
if (CURRENT_REGS)
{
sp = (uint32_t)CURRENT_REGS;
}
/* Show user stack info */
_alert("sp: %08x\n", sp);
_alert("User stack:\n");
_alert(" base: %08x\n", ustackbase);
_alert(" size: %08x\n", ustacksize);
#ifdef CONFIG_STACK_COLORATION
_alert(" used: %08x\n", up_check_tcbstack(rtcb));
#endif
/* Dump the user stack if the stack pointer lies within the allocated user
* stack memory.
*/
if (sp > ustackbase || sp <= ustackbase - ustacksize)
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
up_stackdump(ustackbase - ustacksize, ustackbase);
}
else
{
up_stackdump(sp, ustackbase);
}
#ifdef CONFIG_SMP
/* Show the CPU number */
_alert("CPU%d:\n", up_cpu_index());
#endif
/* Dump the state of all tasks (if available) */
up_showtasks();
#ifdef CONFIG_ARCH_USBDUMP
/* Dump USB trace data */
usbtrace_enumerate(assert_tracecallback, NULL);
#endif
}
#else
# define up_dumpstate()
#endif
/****************************************************************************
* Name: _up_assert
****************************************************************************/
static void _up_assert(int errorcode) noreturn_function;
static void _up_assert(int errorcode)
{
/* Flush any buffered SYSLOG data */
syslog_flush();
/* Are we in an interrupt handler or the idle task? */
if (CURRENT_REGS || running_task()->pid == 0)
{
up_irq_save();
for (; ; )
{
#ifdef CONFIG_SMP
/* Try (again) to stop activity on other CPUs */
spin_trylock(&g_cpu_irqlock);
#endif
#if CONFIG_BOARD_RESET_ON_ASSERT >= 1
board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE);
#endif
}
}
else
{
#if CONFIG_BOARD_RESET_ON_ASSERT >= 2
board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE);
#endif
exit(errorcode);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_assert
****************************************************************************/
void up_assert(const uint8_t *filename, int lineno)
{
#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG_ALERT)
struct tcb_s *rtcb = running_task();
#endif
/* Flush any buffered SYSLOG data (prior to the assertion) */
syslog_flush();
#ifdef CONFIG_SMP
#if CONFIG_TASK_NAME_SIZE > 0
_alert("Assertion failed CPU%d at file:%s line: %d task: %s\n",
up_cpu_index(), filename, lineno, rtcb->name);
#else
_alert("Assertion failed CPU%d at file:%s line: %d\n",
up_cpu_index(), filename, lineno);
#endif
#else
#if CONFIG_TASK_NAME_SIZE > 0
_alert("Assertion failed at file:%s line: %d task: %s\n",
filename, lineno, rtcb->name);
#else
_alert("Assertion failed at file:%s line: %d\n",
filename, lineno);
#endif
#endif
up_dumpstate();
/* Flush any buffered SYSLOG data (from the above) */
syslog_flush();
#ifdef CONFIG_BOARD_CRASHDUMP
board_crashdump(up_getsp(), running_task(), filename, lineno);
#endif
_up_assert(EXIT_FAILURE);
}

View file

@ -0,0 +1,143 @@
/****************************************************************************
* arch/ceva/src/common/up_blocktask.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_block_task
*
* Description:
* The currently executing task at the head of
* the ready to run list must be stopped. Save its context
* and move it to the inactive list specified by task_state.
*
* Inputs:
* tcb: Refers to a task in the ready-to-run list (normally
* the task at the head of the list). It most be
* stopped, its context saved and moved into one of the
* waiting task lists. It it was the task at the head
* of the ready-to-run list, then a context to the new
* ready to run task must be performed.
* task_state: Specifies which waiting task list should be
* hold the blocked task TCB.
*
****************************************************************************/
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
{
struct tcb_s *rtcb = this_task();
bool switch_needed;
/* Verify that the context switch can be performed */
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
/* Remove the tcb task from the ready-to-run list. If we
* are blocking the task at the head of the task list (the
* most likely case), then a context switch to the next
* ready-to-run task is needed. In this case, it should
* also be true that rtcb == tcb.
*/
switch_needed = sched_removereadytorun(tcb);
/* Add the task to the specified blocked task list */
sched_addblocked(tcb, (tstate_t)task_state);
/* If there are any pending tasks, then add them to the ready-to-run
* task list now
*/
if (g_pendingtasks.head)
{
switch_needed |= sched_mergepending();
}
/* Now, perform the context switch if one is needed */
if (switch_needed)
{
/* Update scheduler parameters */
sched_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.
*/
rtcb->xcp.regs = CURRENT_REGS;
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Reset scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
CURRENT_REGS = rtcb->xcp.regs;
}
/* No, then we will need to perform the user context switch */
else
{
struct tcb_s *nexttcb = this_task();
/* Reset scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_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.
*/
}
}
}

View file

@ -0,0 +1,180 @@
/****************************************************************************
* arch/ceva/src/common/up_board.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if !defined(CONFIG_BOARD_LATE_INITIALIZE) && !defined(CONFIG_NSH_ARCHINIT)
# error CONFIG_BOARD_LATE_INITIALIZE or CONFIG_NSH_ARCHINIT is required for late initialization
#endif
#if defined(CONFIG_BOARD_LATE_INITIALIZE) && defined(CONFIG_NSH_ARCHINIT)
# error CONFIG_BOARD_LATE_INITIALIZE and CONFIG_NSH_ARCHINIT can not be defined at the same time
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_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_initialize(). board_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 the arch late initialization */
up_lateinitialize();
/* Perform the board late initialization */
board_lateinitialize();
}
#endif /* CONFIG_BOARD_LATE_INITIALIZE */
/****************************************************************************
* 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 initalization logic and the
* matching application logic. The value cold 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.
*
****************************************************************************/
#ifdef CONFIG_LIB_BOARDCTL
int board_app_initialize(uintptr_t arg)
{
# ifdef CONFIG_NSH_ARCHINIT
/* Perform the arch late initialization */
up_lateinitialize();
/* Perform the board late initialization */
board_lateinitialize();
# endif
return 0;
}
#endif /* CONFIG_LIB_BOARDCTL */
/****************************************************************************
* Name: board_app_finalinitialize
*
* 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_FINALINIT.
*
* Input Parameters:
* arg - The argument has no meaning.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure to indicate the nature of the failure.
*
****************************************************************************/
#ifdef CONFIG_BOARDCTL_FINALINIT
int board_app_finalinitialize(uintptr_t arg)
{
/* Perform the arch final initialization */
up_finalinitialize();
/* Perform the board final initialization */
board_finalinitialize();
return 0;
}
#endif /* CONFIG_BOARDCTL_FINALINIT */
/****************************************************************************
* Name: board_reset
*
* Description:
* Reset board. This function may or may not be supported by a
* particular board architecture.
*
* Input Parameters:
* status - Status information provided with the reset event. This
* meaning of this status information is board-specific. If not used by
* a board, the value zero may be provided in calls to board_reset.
*
* Returned Value:
* If this function returns, then it was not possible to power-off the
* board due to some constraints. The return value int this case is a
* board-specific reason for the failure to shutdown.
*
****************************************************************************/
#ifdef CONFIG_BOARDCTL_RESET
int board_reset(int status)
{
while (1)
{
up_reset(status);
up_cpu_idle();
}
return 0;
}
#endif /* CONFIG_BOARDCTL_RESET */

View file

@ -0,0 +1,204 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include "sched/sched.h"
#include "up_internal.h"
#ifdef CONFIG_STACK_COLORATION
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
/****************************************************************************
* Name: do_stackcheck
*
* 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.
*
****************************************************************************/
static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
{
uintptr_t start;
uintptr_t end;
FAR uint32_t *ptr;
size_t nwords;
size_t mark;
if (size == 0)
{
return 0;
}
/* Get aligned addresses of the top and bottom of the stack */
#ifdef CONFIG_TLS
if (!int_stack)
{
/* Skip over the TLS data structure at the bottom of the stack */
DEBUGASSERT(alloc & (B2C(TLS_STACK_ALIGN) - 1) == 0);
start = alloc + sizeof(struct tls_info_s);
}
else
#endif
{
DEBUGASSERT(alloc & (sizeof(uint32_t) - 1) == 0);
start = alloc;
}
end = alloc + size;
/* Get the adjusted size based on the top and bottom of the stack */
size = end - start;
nwords = size / sizeof(uint32_t);
/* The CEVA 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 = (FAR uint32_t *)start, mark = nwords;
*ptr == STACK_COLOR && mark > 0;
ptr++, mark--);
/* If the stack is completely used, then this might mean that the stack
* overflowed from above (meaning that the stack is too small), or may
* have been overwritten from below meaning that some other stack or data
* structure overflowed.
*
* If you see returned values saying that the entire stack is being used
* then enable the following logic to see it there are unused areas in the
* middle of the stack.
*/
#if 0
if (mark + 16 > nwords)
{
int i;
int j;
ptr = (FAR uint32_t *)start;
for (i = 0; i < nwords; i += 64)
{
for (j = 0; j < 64; j++)
{
int ch;
if (*ptr++ == STACK_COLOR)
{
ch = '.';
}
else
{
ch = 'X';
}
up_putc(ch);
}
up_putc('\n');
}
}
#endif
/* Return our guess about how much stack space was used */
return mark * sizeof(uint32_t);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_check_stack 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(FAR struct tcb_s *tcb)
{
return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr,
tcb->adj_stack_size, false);
}
ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
{
return tcb->adj_stack_size - up_check_tcbstack(tcb);
}
size_t up_check_stack(void)
{
return up_check_tcbstack(this_task());
}
ssize_t up_check_stack_remain(void)
{
return up_check_tcbstack_remain(this_task());
}
size_t up_check_intstack(void)
{
return do_stackcheck((uintptr_t)&g_intstackalloc,
&g_intstackbase - &g_intstackalloc,
true);
}
size_t up_check_intstack_remain(void)
{
return &g_intstackbase - &g_intstackalloc - up_check_intstack();
}
#endif /* CONFIG_STACK_COLORATION */

View file

@ -0,0 +1,275 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <string.h>
#include <sched.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/kmalloc.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Macros
****************************************************************************/
/* Configuration */
#undef HAVE_KERNEL_HEAP
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
defined(CONFIG_MM_KERNEL_HEAP)
# define HAVE_KERNEL_HEAP 1
#endif
/* Stack alignment macros */
#define STACK_ALIGN_MASK (sizeof(uint32_t) - 1)
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
/****************************************************************************
* 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
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
* the stack pointer.
*
* Inputs:
* - 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 either CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL are 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(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
/* Conver the stack size unit from byte to char */
stack_size = B2C(stack_size);
#ifdef CONFIG_TLS
/* Add the size of the TLS information structure */
stack_size += sizeof(struct tls_info_s);
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
*/
DEBUGASSERT(stack_size <= B2C(TLS_MAXSTACK));
if (stack_size >= B2C(TLS_MAXSTACK))
{
stack_size = B2C(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
#ifdef HAVE_KERNEL_HEAP
/* Use the kernel allocator if this is a kernel thread */
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
tcb->stack_alloc_ptr = mm_memalign(
KMM_HEAP(CONFIG_ARCH_KERNEL_STACK_HEAP),
B2C(TLS_STACK_ALIGN), stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = mm_memalign(
UMM_HEAP(CONFIG_ARCH_STACK_HEAP),
B2C(TLS_STACK_ALIGN), stack_size);
}
#else /* CONFIG_TLS */
#ifdef HAVE_KERNEL_HEAP
/* Use the kernel allocator if this is a kernel thread */
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
tcb->stack_alloc_ptr = mm_malloc(
KMM_HEAP(CONFIG_ARCH_KERNEL_STACK_HEAP),
stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = mm_malloc(
UMM_HEAP(CONFIG_ARCH_STACK_HEAP),
stack_size);
}
#endif /* CONFIG_TLS */
#ifdef CONFIG_DEBUG_FEATURES
/* Was the allocation successful? */
if (!tcb->stack_alloc_ptr)
{
serr("ERROR: Failed to allocate stack, size %d\n", stack_size);
}
#endif
}
/* Did we successfully allocate a stack? */
if (tcb->stack_alloc_ptr)
{
#if defined(CONFIG_TLS) && defined(CONFIG_STACK_COLORATION)
FAR void *stack_base;
#endif
FAR void *top_of_stack;
size_t size_of_stack;
/* The CEVA 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.
*/
/* The CEVA stack must be aligned to 4-byte alignment.
* If necessary size_of_stack must be rounded down to the next
* boundary
*/
size_of_stack = STACK_ALIGN_DOWN(stack_size);
top_of_stack = tcb->stack_alloc_ptr + size_of_stack;
/* Save the adjusted stack values in the struct tcb_s */
tcb->adj_stack_ptr = top_of_stack;
tcb->adj_stack_size = size_of_stack;
#ifdef CONFIG_TLS
/* Initialize the TLS data structure */
memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
#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.
*/
stack_base = tcb->stack_alloc_ptr + sizeof(struct tls_info_s);
stack_size = tcb->adj_stack_size - sizeof(struct tls_info_s);
up_stack_color(stack_base, stack_size);
#endif /* CONFIG_STACK_COLORATION */
#else /* CONFIG_TLS */
#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.
*/
up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */
#endif /* CONFIG_TLS */
return OK;
}
return ERROR;
}
/****************************************************************************
* Name: up_stack_color
*
* Description:
* Write a well know value into the stack
*
****************************************************************************/
#ifdef CONFIG_STACK_COLORATION
void up_stack_color(FAR void *stackbase, size_t nbytes)
{
uint32_t *stkptr = stackbase;
size_t nwords = nbytes / sizeof(uint32_t);
/* Set the entire stack to the coloration value */
while (nwords-- > 0)
{
*stkptr++ = STACK_COLOR;
}
}
#endif

View file

@ -0,0 +1,106 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* 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.
*/
#ifdef CONFIG_SMP
uint32_t *volatile g_current_regs[CONFIG_SMP_NCPUS];
#else
uint32_t *volatile g_current_regs[1];
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
uint32_t *up_doirq(int irq, uint32_t *regs)
{
/* Is it the outermost interrupt? */
if (CURRENT_REGS != NULL)
{
/* No, simply deliver the IRQ because only the outermost nested
* interrupt can result in a context switch.
*/
irq_dispatch(irq, regs);
}
else
{
/* 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(irq, regs);
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value
* different from the input regs, then the lower level will know that
* a context switch occurred during interrupt processing.
*/
regs = CURRENT_REGS;
/* Restore the previous value of CURRENT_REGS. NULL would indicate
* that we are no longer in an interrupt handler.
* It will be non-NULL if we are returning from a nested interrupt.
*/
CURRENT_REGS = NULL;
if (regs != (uint32_t *)regs[REG_SP])
{
/* We are returning with a pending context switch. This case is
* different because in this case, the register save structure
* does not lie on the stack but, rather within other storage.
* We'll have to copy some values to the stack.
*/
memcpy((uint32_t *)regs[REG_SP], regs, XCPTCONTEXT_SIZE);
regs = (uint32_t *)regs[REG_SP];
}
}
return regs;
}

View file

@ -0,0 +1,84 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include "task/task.h"
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: _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 _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();
sinfo("TCB=%p exiting\n", tcb);
/* Update scheduler parameters */
sched_suspend_scheduler(tcb);
/* 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();
/* Reset scheduler parameters */
sched_resume_scheduler(tcb);
/* Then switch contexts */
up_fullcontextrestore(tcb->xcp.regs);
}

View file

@ -0,0 +1,51 @@
/****************************************************************************
* arch/ceva/src/common/up_fullcontextrestore.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 "svcall.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_fullcontextrestore
*
* Description:
* Restore the current thread context. Full prototype is:
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*
* Return:
* None
*
****************************************************************************/
void up_fullcontextrestore(uint32_t *restoreregs)
{
/* Let sys_call1() do all of the work */
sys_call1(SYS_restore_context, (uintptr_t)restoreregs);
while (1); /* Shut up the compiler warning */
}

View file

@ -0,0 +1,273 @@
/****************************************************************************
* arch/ceva/src/common/up_heap.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 <nuttx/config.h>
#include <assert.h>
#include <string.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include "mpu.h"
#include "up_arch.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_MM_KERNEL_HEAP
# define MM_DEF_HEAP &g_kmmheap
#else
# define MM_DEF_HEAP &g_mmheap
#endif
#if CONFIG_ARCH_DEFAULT_HEAP == 0
# define MM_HEAP1 MM_DEF_HEAP
#else
static struct mm_heap_s g_mmheap1;
# define MM_HEAP1 &g_mmheap1
#endif
#if CONFIG_ARCH_NR_MEMORY >= 2
# if CONFIG_ARCH_DEFAULT_HEAP == 1
# define MM_HEAP2 MM_DEF_HEAP
# else
static struct mm_heap_s g_mmheap2;
# define MM_HEAP2 &g_mmheap2
# endif
# define _END_BSS2 ((void *)&_ebss2)
# define _END_HEAP2 ((void *)&_eheap2)
#else
# define MM_HEAP2 NULL
# define _END_BSS2 NULL
# define _END_HEAP2 NULL
#endif
#if CONFIG_ARCH_NR_MEMORY >= 3
# if CONFIG_ARCH_DEFAULT_HEAP == 2
# define MM_HEAP3 MM_DEF_HEAP
# else
static struct mm_heap_s g_mmheap3;
# define MM_HEAP3 &g_mmheap3
# endif
# define _END_BSS3 ((void *)&_ebss3)
# define _END_HEAP3 ((void *)&_eheap3)
#else
# define MM_HEAP3 NULL
# define _END_BSS3 NULL
# define _END_HEAP3 NULL
#endif
#if CONFIG_ARCH_NR_MEMORY >= 4
# if CONFIG_ARCH_DEFAULT_HEAP == 3
# define MM_HEAP4 MM_DEF_HEAP
# else
static struct mm_heap_s g_mmheap4;
# define MM_HEAP4 &g_mmheap4
# endif
# define _END_BSS4 ((void *)&_ebss4)
# define _END_HEAP4 ((void *)&_eheap4)
#else
# define MM_HEAP4 NULL
# define _END_BSS4 NULL
# define _END_HEAP4 NULL
#endif
#if CONFIG_ARCH_NR_MEMORY >= 5
# error CONFIG_ARCH_NR_MEMORY must between 1 to 4
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static void *const g_bssend[] =
{
_START_HEAP, _END_BSS2, _END_BSS3, _END_BSS4, NULL,
};
static void *const g_heapend[] =
{
_END_HEAP, _END_HEAP2, _END_HEAP3, _END_HEAP4, NULL,
};
/****************************************************************************
* Public Data
****************************************************************************/
struct mm_heap_s *const g_mm_heap[] =
{
MM_HEAP1, MM_HEAP2, MM_HEAP3, MM_HEAP4, NULL,
};
/* g_idle_topstack: _sbss is the start of the BSS region as defined by the
* linker script. _ebss lies at the end of the BSS region. The idle task
* stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE.
* The IDLE thread is the thread that the system boots on and, eventually,
* becomes the IDLE, do nothing task that runs only when there is nothing
* else to run. The heap continues from there until the end of memory.
* g_idle_topstack is a read-only variable the provides this computed
* address.
*/
void *g_idle_basestack = _END_BSS;
void *g_idle_topstack = _START_HEAP;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_allocate_heap
*
* Description:
* This function will be called to dynamically set aside the heap region.
*
* - For the normal "flat" build, this function returns the size of the
* single heap.
* - For the protected build (CONFIG_BUILD_PROTECTED=y) with both kernel-
* and user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function
* provides the size of the unprotected, user-space heap.
*
* The following memory map is assumed for the flat build:
*
* .data region. Size determined at link time.
* .bss region Size determined at link time.
* IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
* Heap. Extends to the end of SRAM.
*
* The following memory map is assumed for the kernel build:
*
* Kernel .data region. Size determined at link time.
* Kernel .bss region Size determined at link time.
* Kernel IDLE stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
* Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE.
* Padding for alignment
* User .data region. Size determined at link time.
* User .bss region Size determined at link time.
* User heap. Extends to the end of SRAM.
*
****************************************************************************/
void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
{
int i;
#ifdef CONFIG_BUILD_PROTECTED
struct mm_heap_s *const *heap =
(struct mm_heap_s *const *)USERSPACE->us_heap;
void *const *bssend = (void *const *)USERSPACE->us_bssend;
void *const *heapend = (void *const *)USERSPACE->us_heapend;
for (i = 0; i < CONFIG_ARCH_NR_USER_MEMORY; i++)
{
size_t size = heapend[i] - bssend[i];
if (size != 0)
{
mpu_user_data(bssend[i], size);
up_heap_color(bssend[i], size);
if (i == CONFIG_ARCH_USER_DEFAULT_HEAP)
{
/* Return the default user-space heap settings */
*heap_start = bssend[i];
*heap_size = heapend[i] - bssend[i];
}
else
{
/* Initialize the additional user-space heap */
mm_initialize(heap[i], bssend[i], size);
}
}
}
#else
for (i = 0; i < CONFIG_ARCH_NR_MEMORY; i++)
{
size_t size = g_heapend[i] - g_bssend[i];
if (size != 0)
{
mpu_priv_data(g_bssend[i], size);
up_heap_color(g_bssend[i], size);
if (i == CONFIG_ARCH_DEFAULT_HEAP)
{
/* Return the default heap settings */
*heap_start = g_bssend[i];
*heap_size = g_heapend[i] - g_bssend[i];
}
else
{
/* Initialize the additional heap */
mm_initialize(g_mm_heap[i], g_bssend[i], size);
}
}
}
#endif
}
/****************************************************************************
* Name: up_allocate_kheap
*
* Description:
* For the kernel build (CONFIG_BUILD_PROTECTED/KERNEL=y) with both kernel-
* and user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
* the kernel-space heap.
*
****************************************************************************/
#ifdef CONFIG_MM_KERNEL_HEAP
void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
{
int i;
for (i = 0; i < CONFIG_ARCH_NR_MEMORY; i++)
{
size_t size = g_heapend[i] - g_bssend[i];
if (size != 0)
{
mpu_priv_data(g_bssend[i], size);
up_heap_color(g_bssend[i], size);
if (i == CONFIG_ARCH_DEFAULT_HEAP)
{
/* Return the default kernel-space heap settings */
*heap_start = g_bssend[i];
*heap_size = g_heapend[i] - g_bssend[i];
DEBUGASSERT(*heap_size >= CONFIG_MM_KERNEL_HEAPSIZE);
}
else
{
/* Initialize the additional kernel-space heap */
mm_initialize(g_mm_heap[i], g_bssend[i], size);
}
}
}
}
#endif

View file

@ -0,0 +1,170 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/power/pm.h>
#include "up_internal.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_idlepm
*
* Description:
* Perform IDLE state power management.
*
****************************************************************************/
#ifdef CONFIG_PM
static void up_idlepm(void)
{
enum pm_state_e newstate;
/* Decide, which power saving level can be obtained */
newstate = pm_checkstate(PM_IDLE_DOMAIN);
/* Then force the global state change */
pm_changestate(PM_IDLE_DOMAIN, newstate);
/* The change may fail, let's get the final state from power manager */
newstate = pm_querystate(PM_IDLE_DOMAIN);
#ifdef CONFIG_PM_KEEPBUSY
/* Check whether need keep CPU busy */
if (pm_keepbusy(PM_IDLE_DOMAIN, newstate))
{
return;
}
#endif
/* MCU-specific power management logic */
switch (newstate)
{
case PM_NORMAL:
up_cpu_doze();
break;
case PM_IDLE:
up_cpu_idle();
break;
case PM_STANDBY:
up_cpu_standby();
break;
case PM_SLEEP:
up_cpu_sleep();
break;
default:
break;
}
}
#else
# define up_idlepm() up_cpu_idle()
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_idle
*
* Description:
* up_idle() is the logic that will be executed
* when their 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)
{
irqstate_t flags;
flags = up_irq_save();
sched_lock();
/* Perform IDLE mode power management */
up_idlepm();
/* Quit lower power mode, restore to PM_NORMAL */
up_cpu_normal();
pm_changestate(PM_IDLE_DOMAIN, PM_RESTORE);
sched_unlock();
up_irq_restore(flags);
}
/****************************************************************************
* Power callback default implementation
****************************************************************************/
void weak_function up_cpu_normal(void)
{
}
/****************************************************************************
* Name: up_pminitialize
*
* Description:
* This function is called by MCU-specific logic at power-on reset in
* order to provide one-time initialization the power management subsystem.
* This function must be called *very* early in the initialization sequence
* *before* any other device drivers are initialized (since they may
* attempt to register with the power management subsystem).
*
* Input parameters:
* None.
*
* Returned value:
* None.
*
****************************************************************************/
#ifdef CONFIG_PM
void up_pminitialize(void)
{
/* Then initialize the power management subsystem proper */
pm_initialize();
}
#endif

View file

@ -0,0 +1,232 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched_note.h>
#include <nuttx/mm/iob.h>
#include <nuttx/drivers/drivers.h>
#include <nuttx/fs/loop.h>
#include <nuttx/net/loopback.h>
#include <nuttx/net/tun.h>
#include <nuttx/net/telnet.h>
#include <nuttx/syslog/ramlog.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/syslog/syslog_console.h>
#include <nuttx/serial/pty.h>
#include <nuttx/crypto/crypto.h>
#include <nuttx/power/pm.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "up_internal.h"
#include "chip.h"
#include "sched/sched.h"
/****************************************************************************
* 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
*
****************************************************************************/
static inline void up_color_intstack(void)
{
uint32_t *ptr = (uint32_t *)&g_intstackalloc;
ssize_t size;
for (size = &g_intstackbase - &g_intstackalloc;
size > 0;
size -= sizeof(uint32_t))
{
*ptr++ = INTSTACK_COLOR;
}
}
/****************************************************************************
* 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)
{
struct tcb_s *idle;
/* Initialize global variables */
CURRENT_REGS = NULL;
/* Initialize the idle task stack info */
idle = this_task(); /* It should be idle task */
idle->stack_alloc_ptr = g_idle_basestack;
idle->adj_stack_ptr = g_idle_topstack;
idle->adj_stack_size = g_idle_topstack - g_idle_basestack;
/* Colorize the interrupt stack */
up_color_intstack();
/* Add any extra memory fragments to the memory manager */
up_addregion();
#ifdef CONFIG_PM
/* Initialize the power management subsystem. This MCU-specific function
* must be called *very* early in the initialization sequence *before* any
* other device drivers are initialized (since they may attempt to register
* with the power management subsystem).
*/
up_pminitialize();
#endif
#ifdef CONFIG_ARCH_DMA
/* Initialize the DMA subsystem if the weak function up_dma_initialize has
* been brought into the build
*/
up_dma_initialize();
#endif
/* Register devices */
#if defined(CONFIG_DEV_NULL)
devnull_register(); /* Standard /dev/null */
#endif
#if defined(CONFIG_DEV_RANDOM)
devrandom_register(); /* Standard /dev/random */
#endif
#if defined(CONFIG_DEV_URANDOM)
devurandom_register(); /* Standard /dev/urandom */
#endif
#if defined(CONFIG_DEV_ZERO)
devzero_register(); /* Standard /dev/zero */
#endif
#if defined(CONFIG_DEV_LOOP)
loop_register(); /* Standard /dev/loop */
#endif
#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \
defined(CONFIG_DRIVER_NOTE)
note_register(); /* Non-standard /dev/note */
#endif
/* Initialize the serial device driver */
#ifdef USE_SERIALDRIVER
up_serialinit();
#endif
#ifdef CONFIG_RPMSG_UART
rpmsg_serialinit();
#endif
/* Initialize the console device driver (if it is other than the standard
* serial driver).
*/
#if defined (CONFIG_ARM_LWL_CONSOLE)
lwlconsole_init();
#elif defined(CONFIG_CONSOLE_SYSLOG)
syslog_console_init();
#endif
#ifdef CONFIG_PSEUDOTERM_SUSV1
/* Register the master pseudo-terminal multiplexor device */
ptmx_register();
#endif
#if defined(CONFIG_CRYPTO)
/* Initialize the HW crypto and /dev/crypto */
up_cryptoinitialize();
#endif
#ifdef CONFIG_CRYPTO_CRYPTODEV
devcrypto_register();
#endif
#ifndef CONFIG_NETDEV_LATEINIT
/* Initialize the network */
up_netinitialize();
#endif
#ifdef CONFIG_NET_LOOPBACK
/* Initialize the local loopback device */
localhost_initialize();
#endif
#ifdef CONFIG_NET_TUN
/* Initialize the TUN device */
tun_initialize();
#endif
#ifdef CONFIG_NETDEV_TELNET
/* Initialize the Telnet session factory */
telnet_initialize();
#endif
#if defined(CONFIG_USBDEV) || defined(CONFIG_USBHOST)
/* Initialize USB -- device and/or host */
up_usbinitialize();
#endif
}

View file

@ -0,0 +1,352 @@
/****************************************************************************
* arch/ceva/src/common/up_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_CEVA_SRC_COMMON_UP_INTERNAL_H
#define __ARCH_CEVA_SRC_COMMON_UP_INTERNAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <sys/types.h>
# include <stdint.h>
#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.
*/
#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS == 0
# undef USE_SERIALDRIVER
# undef USE_EARLYSERIALINIT
# undef CONFIG_DEV_LOWCONSOLE
# undef CONFIG_RAMLOG_CONSOLE
#else
# if defined(CONFIG_RAMLOG_CONSOLE)
# undef USE_SERIALDRIVER
# undef USE_EARLYSERIALINIT
# undef CONFIG_DEV_LOWCONSOLE
# elif defined(CONFIG_DEV_LOWCONSOLE)
# 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
/* Linker defined section addresses */
#define _START_TEXT ((const void *)&_stext)
#define _END_TEXT ((const void *)&_etext)
#define _START_BSS ((void *)&_sbss)
#define _END_BSS ((void *)&_ebss)
#define _DATA_INIT ((const void *)&_eronly)
#define _START_DATA ((void *)&_sdata)
#define _END_DATA ((void *)&_edata)
#define _START_HEAP ((void *)&_ebss + B2C(CONFIG_IDLETHREAD_STACKSIZE))
#define _END_HEAP ((void *)&_eheap)
#define _END_MEM ((void *)~0)
/* 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'
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* 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.
*/
#ifdef CONFIG_SMP
/* For the case of architectures with multiple CPUs, then there must be one
* such value for each processor that can receive an interrupt.
*/
int up_cpu_index(void); /* See include/nuttx/arch.h */
EXTERN uint32_t *volatile g_current_regs[CONFIG_SMP_NCPUS];
# define CURRENT_REGS (g_current_regs[up_cpu_index()])
#else
EXTERN uint32_t *volatile g_current_regs[1];
# define CURRENT_REGS (g_current_regs[0])
#endif
/* 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 void *g_idle_basestack;
EXTERN void *g_idle_topstack;
/* Address of the interrupt stack pointer */
EXTERN char g_intstackalloc; /* Allocated stack base */
EXTERN char g_intstackbase; /* Initial top of interrupt stack */
/* These 'addresses' of these values are setup by the linker script.
* They are not actual char storage locations! They are only used
* meaningfully in the following way:
*
* - The linker script defines, for example, the symbol _sdata.
* - The declareion extern char _sdata; makes C happy. C will believe
* that the value _sdata is the address of a char variable _data (it is
* not!).
* - We can recover the linker value then by simply taking the address of
* of _data. like: char *pdata = &_sdata;
*/
/* Start of .text */
EXTERN const char _stext;
EXTERN const char _stext2;
EXTERN const char _stext3;
EXTERN const char _stext4;
/* End+1 of .text */
EXTERN const char _etext;
EXTERN const char _etext2;
EXTERN const char _etext3;
EXTERN const char _etext4;
/* End+1 of read only section (.text + .rodata) */
EXTERN const char _eronly;
EXTERN const char _eronly2;
EXTERN const char _eronly3;
EXTERN const char _eronly4;
/* Start of .data */
EXTERN char _sdata;
EXTERN char _sdata2;
EXTERN char _sdata3;
EXTERN char _sdata4;
/* End+1 of .data */
EXTERN char _edata;
EXTERN char _edata2;
EXTERN char _edata3;
EXTERN char _edata4;
/* Start of .bss */
EXTERN char _sbss;
EXTERN char _sbss2;
EXTERN char _sbss3;
EXTERN char _sbss4;
/* End+1 of .bss */
EXTERN char _ebss;
EXTERN char _ebss2;
EXTERN char _ebss3;
EXTERN char _ebss4;
/* End+1 of the memory */
EXTERN char _eheap;
EXTERN char _eheap2;
EXTERN char _eheap3;
EXTERN char _eheap4;
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
/* Context switching */
int up_saveusercontext(uint32_t *saveregs);
void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
void up_switchcontext(uint32_t **saveregs, uint32_t *restoreregs);
/* Signal handling **********************************************************/
void up_sigdeliver(void);
/* Arch specific ************************************************************/
void up_earlyinitialize(void);
void up_lateinitialize(void);
void up_finalinitialize(void);
/* Power management *********************************************************/
#ifdef CONFIG_PM
void up_pminitialize(void);
#else
# define up_pminitialize()
#endif
void up_reset(void);
void up_cpu_doze(void);
void up_cpu_idle(void);
void up_cpu_standby(void);
void up_cpu_sleep(void);
void up_cpu_normal(void);
/* Interrupt handling *******************************************************/
void up_irqinitialize(void);
/* Interrupt acknowledge and dispatch */
uint32_t *up_doirq(int irq, uint32_t *regs);
/* Exception Handlers */
int up_svcall(int irq, FAR void *context, FAR void *arg);
int up_hardfault(int irq, FAR void *context, FAR void *arg);
void up_svcall_handler(void);
/* System timer *************************************************************/
void up_timer_initialize(void);
/* Low level serial output **************************************************/
#ifdef USE_SERIALDRIVER
void up_serialinit(void);
#else
# define up_serialinit()
#endif
#ifdef USE_EARLYSERIALINIT
void up_earlyserialinit(void);
#else
# define up_earlyserialinit()
#endif
#ifdef CONFIG_RPMSG_UART
void rpmsg_serialinit(void);
#else
# define rpmsg_serialinit()
#endif
/* Defined in drivers/lowconsole.c */
#ifdef CONFIG_DEV_LOWCONSOLE
void lowconsole_init(void);
#else
# define lowconsole_init()
#endif
/* DMA **********************************************************************/
#ifdef CONFIG_ARCH_DMA
void up_dma_initialize(void);
#endif
/* Memory management ********************************************************/
#if CONFIG_MM_REGIONS > 1
void up_addregion(void);
#else
# define up_addregion()
#endif
/* Watchdog timer ***********************************************************/
void up_wdtinit(void);
/* Networking ***************************************************************/
#if defined(CONFIG_NET) && !defined(CONFIG_NETDEV_LATEINIT)
void up_netinitialize(void);
#else
# define up_netinitialize()
#endif
/* USB **********************************************************************/
#ifdef CONFIG_USBDEV
void up_usbinitialize(void);
void up_usbuninitialize(void);
#else
# define up_usbinitialize()
# define up_usbuninitialize()
#endif
/* Debug ********************************************************************/
#ifdef CONFIG_HEAP_COLORATION
# define up_heap_color(start, size) memset(start, HEAP_COLOR, size)
#else
# define up_heap_color(start, size)
#endif
#ifdef CONFIG_STACK_COLORATION
void up_stack_color(FAR void *stackbase, size_t nbytes);
#endif
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_CEVA_SRC_COMMON_UP_INTERNAL_H */

View file

@ -0,0 +1,45 @@
/****************************************************************************
* arch/ceva/src/common/up_interruptcontext.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_interrupt_context
*
* Description: Return true is we are currently executing in
* the interrupt handler context.
****************************************************************************/
bool up_interrupt_context(void)
{
return CURRENT_REGS != NULL;
}

View file

@ -0,0 +1,53 @@
/****************************************************************************
* arch/ceva/src/common/up_modifyreg16.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 <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_arch.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: modifyreg16
*
* Description:
* Atomically modify the specified bits in a memory mapped register
*
****************************************************************************/
void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits)
{
irqstate_t flags;
uint16_t regval;
flags = spin_lock_irqsave();
regval = getreg16(addr);
regval &= ~clearbits;
regval |= setbits;
putreg16(regval, addr);
spin_unlock_irqrestore(flags);
}

View file

@ -0,0 +1,53 @@
/****************************************************************************
* arch/ceva/src/common/up_modifyreg32.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 <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_arch.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: modifyreg32
*
* Description:
* Atomically modify the specified bits in a memory mapped register
*
****************************************************************************/
void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
{
irqstate_t flags;
uint32_t regval;
flags = spin_lock_irqsave();
regval = getreg32(addr);
regval &= ~clearbits;
regval |= setbits;
putreg32(regval, addr);
spin_unlock_irqrestore(flags);
}

View file

@ -0,0 +1,53 @@
/****************************************************************************
* arch/ceva/src/common/up_modifyreg8.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 <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_arch.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: modifyreg8
*
* Description:
* Atomically modify the specified bits in a memory mapped register
*
****************************************************************************/
void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits)
{
irqstate_t flags;
uint8_t regval;
flags = spin_lock_irqsave();
regval = getreg8(addr);
regval &= ~clearbits;
regval |= setbits;
putreg8(regval, addr);
spin_unlock_irqrestore(flags);
}

View file

@ -0,0 +1,70 @@
/****************************************************************************
* arch/ceva/src/common/up_pthread_start.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 <nuttx/config.h>
#include <pthread.h>
#include <nuttx/arch.h>
#include "svcall.h"
#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_PTHREAD)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_pthread_start
*
* Description:
* In this kernel mode build, this function will be called to execute a
* pthread in user-space. When the pthread is first started, a kernel-mode
* stub will first run to perform some housekeeping functions. This
* kernel-mode stub will then be called transfer control to the user-mode
* pthread.
*
* Normally the a user-mode start-up stub will also execute before the
* pthread actually starts. See libc/pthread/pthread_startup.c
*
* Input Parameters:
* entrypt - The user-space address of the pthread entry point
* arg - Standard argument for the pthread entry point
*
* Returned Value:
* This function should not return. It should call the user-mode start-up
* stub and that stub should call pthread_exit if/when the user pthread
* terminates.
*
****************************************************************************/
void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
{
/* Let sys_call2() do all of the work */
sys_call2(SYS_pthread_start, (uintptr_t)entrypt, (uintptr_t)arg);
while (1); /* Shut up the compiler warning */
}
#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */

View file

@ -0,0 +1,46 @@
/****************************************************************************
* arch/ceva/src/common/up_puts.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 <nuttx/config.h>
#include <nuttx/arch.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_puts
*
* Description:
* This is a low-level helper function used to support debug.
*
****************************************************************************/
void up_puts(const char *str)
{
while (*str)
{
up_putc(*str++);
}
}

View file

@ -0,0 +1,114 @@
/****************************************************************************
* arch/ceva/src/common/up_releasepending.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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_release_pending
*
* Description:
* Release and ready-to-run tasks that have
* collected in the pending task list. This can call a
* context switch if a new task is placed at the head of
* the ready to run list.
*
****************************************************************************/
void up_release_pending(void)
{
struct tcb_s *rtcb = this_task();
sinfo("From TCB=%p\n", rtcb);
/* Merge the g_pendingtasks list into the ready-to-run task list */
if (sched_mergepending())
{
/* The currently active task has changed! We will need to switch
* contexts.
*/
/* Update scheduler parameters */
sched_suspend_scheduler(rtcb);
/* Are we operating in interrupt context? */
if (CURRENT_REGS)
{
/* Yes, then we have to do things differently. Just copy the
* CURRENT_REGS into the OLD rtcb.
*/
rtcb->xcp.regs = CURRENT_REGS;
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
CURRENT_REGS = rtcb->xcp.regs;
}
/* No, then we will need to perform the user context switch */
else
{
struct tcb_s *nexttcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_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.
*/
}
}
}

View file

@ -0,0 +1,117 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration */
#undef HAVE_KERNEL_HEAP
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
defined(CONFIG_MM_KERNEL_HEAP)
# define HAVE_KERNEL_HEAP 1
#endif
/****************************************************************************
* 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 either CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL are 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(FAR struct tcb_s *dtcb, uint8_t ttype)
{
/* Is there a stack allocated? */
if (dtcb->stack_alloc_ptr)
{
#ifdef HAVE_KERNEL_HEAP
/* Use the kernel allocator if this is a kernel thread */
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
if (kmm_heapmember(dtcb->stack_alloc_ptr))
{
kmm_free(dtcb->stack_alloc_ptr);
}
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
if (umm_heapmember(dtcb->stack_alloc_ptr))
{
kumm_free(dtcb->stack_alloc_ptr);
}
}
/* Mark the stack freed */
dtcb->stack_alloc_ptr = NULL;
}
/* The size of the allocated stack is now zero */
dtcb->adj_stack_size = 0;
}

View file

@ -0,0 +1,170 @@
/****************************************************************************
* arch/ceva/src/common/up_reprioritizertr.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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_reprioritize_rtr
*
* Description:
* Called when the priority of a running or
* ready-to-run task changes and the reprioritization will
* cause a context switch. Two cases:
*
* 1) The priority of the currently running task drops and the next
* task in the ready to run list has priority.
* 2) An idle, ready to run task's priority has been raised above the
* the priority of the current, running task and it now has the
* priority.
*
* Inputs:
* tcb: The TCB of the task that has been reprioritized
* priority: The new task priority
*
****************************************************************************/
void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
{
/* Verify that the caller is sane */
if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
tcb->task_state > LAST_READY_TO_RUN_STATE
#if SCHED_PRIORITY_MIN > 0
|| priority < SCHED_PRIORITY_MIN
#endif
#if SCHED_PRIORITY_MAX < UINT8_MAX
|| priority > SCHED_PRIORITY_MAX
#endif
)
{
DEBUGPANIC();
}
else
{
struct tcb_s *rtcb = this_task();
bool switch_needed;
sinfo("TCB=%p PRI=%d\n", tcb, priority);
/* Remove the tcb task from the ready-to-run list.
* sched_removereadytorun will return true if we just removed the head
* of the ready to run list.
*/
switch_needed = sched_removereadytorun(tcb);
/* Setup up the new task priority */
tcb->sched_priority = (uint8_t)priority;
/* Return the task to the ready-to-run task list. sched_addreadytorun
* will return true if the task was added to the head of ready-to-run
* list. We will need to perform a context switch only if the
* EXCLUSIVE or of the two calls is non-zero (i.e., one and only one
* the calls changes the head of the ready-to-run list).
*/
switch_needed ^= sched_addreadytorun(tcb);
/* Now, perform the context switch if one is needed (i.e. if the head
* of the ready-to-run list is no longer the same).
*/
if (switch_needed)
{
/* If we are going to do a context switch, then now is the right
* time to add any pending tasks back into the ready-to-run list.
* task list now
*/
if (g_pendingtasks.head)
{
sched_mergepending();
}
/* Update scheduler parameters */
sched_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.
*/
rtcb->xcp.regs = CURRENT_REGS;
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
CURRENT_REGS = rtcb->xcp.regs;
}
/* No, then we will need to perform the user context switch */
else
{
struct tcb_s *nexttcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_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.
*/
}
}
}
}

View file

@ -0,0 +1,67 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <nuttx/irq.h>
#include "svcall.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_saveusercontext
*
* Description:
* Save the current thread context. Full prototype is:
*
* int up_saveusercontext(uint32_t *saveregs);
*
* Return:
* 0: Normal return
* 1: Context switch return
*
****************************************************************************/
int up_saveusercontext(uint32_t *saveregs)
{
int ret;
/* Let sys_call1() do all of the work */
ret = sys_call1(SYS_save_context, (uintptr_t)saveregs);
if (ret == 0)
{
/* There are two return conditions. On the first return, A0 (the
* return value will be zero. On the second return we need to
* force A0 to be 1.
*/
saveregs[REG_A0] = 1;
}
return ret;
}

View file

@ -0,0 +1,215 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <string.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
#ifndef CONFIG_DISABLE_SIGNALS
/****************************************************************************
* 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.
*
****************************************************************************/
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
DEBUGASSERT(tcb != NULL && sigdeliver != NULL);
/* Refuse to handle nested signal actions */
if (tcb->xcp.sigdeliver == NULL)
{
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS);
if (tcb->task_state == TSTATE_TASK_RUNNING)
{
uint8_t me = this_cpu();
#ifdef CONFIG_SMP
uint8_t cpu = tcb->cpu;
#else
uint8_t cpu = 0;
#endif
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (cpu == me && !CURRENT_REGS)
{
/* In this case just deliver the signal now. */
sigdeliver(tcb);
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
#ifdef CONFIG_SMP
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Wait while the pause request is pending */
while (up_cpu_pausereq(cpu))
{
}
}
/* Now tcb on the other CPU can be accessed safely */
#endif
/* Save the current register context location */
tcb->xcp.saved_regs = g_current_regs[cpu];
tcb->xcp.sigdeliver = (FAR void *)sigdeliver;
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
g_current_regs[cpu] -= XCPTCONTEXT_REGS;
memcpy(g_current_regs[cpu], g_current_regs[cpu]
+ XCPTCONTEXT_REGS, XCPTCONTEXT_SIZE);
g_current_regs[cpu][REG_SP] = (uint32_t)g_current_regs[cpu];
/* Then set up to vector to the trampoline with interrupts
* unchanged. We must already be in privileged thread mode
* to be here.
*/
g_current_regs[cpu][REG_PC] = (uint32_t)up_sigdeliver;
#ifdef REG_OM
g_current_regs[cpu][REG_OM] &= ~REG_OM_MASK;
g_current_regs[cpu][REG_OM] |= REG_OM_KERNEL;
#endif
#ifdef CONFIG_SMP
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
#endif
}
}
/* 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 signaling some other non-running task.
*/
else
{
/* Save the current register context location */
tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.sigdeliver = (FAR void *)sigdeliver;
/* Duplicate the register context. These will be restored
* by the signal trampoline after the signal has been delivered.
*/
tcb->xcp.regs -= XCPTCONTEXT_REGS;
memcpy(tcb->xcp.regs, tcb->xcp.regs
+ XCPTCONTEXT_REGS, XCPTCONTEXT_SIZE);
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs;
/* Then set up to vector to the trampoline with interrupts
* unchanged. We must already be in privileged thread mode to be
* here.
*/
tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
#ifdef REG_OM
tcb->xcp.regs[REG_OM] &= ~REG_OM_MASK;
tcb->xcp.regs[REG_OM] |= REG_OM_KERNEL;
#endif
}
}
}
#endif /* !CONFIG_DISABLE_SIGNALS */

View file

@ -0,0 +1,96 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
#ifndef CONFIG_DISABLE_SIGNALS
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_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 unchanged.
*
****************************************************************************/
void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t *regs = rtcb->xcp.saved_regs;
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
* EINTR).
*/
int saved_errno = rtcb->pterrno;
sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
/* Deliver the signal */
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).
*/
sinfo("Resuming\n");
rtcb->pterrno = saved_errno;
/* Then restore the correct state for this thread of
* execution.
*/
up_fullcontextrestore(regs);
}
#endif /* !CONFIG_DISABLE_SIGNALS */

View file

@ -0,0 +1,75 @@
/****************************************************************************
* arch/ceva/src/common/up_signal_dispatch.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include "svcall.h"
#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_dispatch
*
* Description:
* In this kernel mode build, this function will be called to execute a
* a signal handler in user-space. When the signal is delivered, a
* kernel-mode stub will first run to perform some housekeeping functions.
* This kernel-mode stub will then be called transfer control to the user
* mode signal handler by calling this function.
*
* Normally the a user-mode signalling handling stub will also execute
* before the ultimate signal handler is called. See
* arch/ceva/src/[xc5/xm6]/up_signal_handler. This function is the
* user-space, signal handler trampoline function. It is called from
* up_signal_dispatch() in user-mode.
*
* Inputs:
* sighand - The address user-space signal handling function
* signo, info, and ucontext - Standard arguments to be passed to the
* signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via an architecture specific system call made by up_signal_handler().
* However, this will look like a normal return by the caller of
* up_signal_dispatch.
*
****************************************************************************/
void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext)
{
/* Let sys_call4() do all of the work */
sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo,
(uintptr_t)info, (uintptr_t)ucontext);
}
#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */

View file

@ -0,0 +1,111 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
/****************************************************************************
* Pre-processor Macros
****************************************************************************/
/* Stack alignment macros */
#define STACK_ALIGN_MASK (sizeof(uint32_t) - 1)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* 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
* - adj_stack_ptr: Adjusted initial stack pointer after the frame has
* been removed from the stack. This will still be the initial value
* of the stack pointer when the task is started.
*
* Inputs:
* - 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.
*
****************************************************************************/
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
FAR void *topaddr;
/* 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;
}
/* Save the adjusted stack values in the struct tcb_s */
topaddr = tcb->adj_stack_ptr - frame_size;
tcb->adj_stack_ptr = topaddr;
tcb->adj_stack_size -= frame_size;
/* Reinitialize the task state after the stack is adjusted */
up_initial_state(tcb);
/* And return the pointer to the allocated region */
return topaddr;
}

View file

@ -0,0 +1,312 @@
/****************************************************************************
* arch/ceva/src/common/up_start.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/init.h>
#include <nuttx/userspace.h>
#include <arch/board/board.h>
#include <string.h>
#include "mpu.h"
#include "up_internal.h"
#if CONFIG_ARCH_NR_MEMORY >= 2
# define _START_TEXT2 ((const void *)&_stext2)
# define _END_TEXT2 ((const void *)&_etext2)
# define _START_BSS2 ((void *)&_sbss2)
# define _END_BSS2 ((void *)&_ebss2)
# define _DATA_INIT2 ((const void *)&_eronly2)
# define _START_DATA2 ((void *)&_sdata2)
# define _END_DATA2 ((void *)&_edata2)
#else
# define _START_TEXT2 NULL
# define _END_TEXT2 NULL
# define _START_BSS2 NULL
# define _END_BSS2 NULL
# define _DATA_INIT2 NULL
# define _START_DATA2 NULL
# define _END_DATA2 NULL
#endif
#if CONFIG_ARCH_NR_MEMORY >= 3
# define _START_TEXT3 ((const void *)&_stext3)
# define _END_TEXT3 ((const void *)&_etext3)
# define _START_BSS3 ((void *)&_sbss3)
# define _END_BSS3 ((void *)&_ebss3)
# define _DATA_INIT3 ((const void *)&_eronly3)
# define _START_DATA3 ((void *)&_sdata3)
# define _END_DATA3 ((void *)&_edata3)
#else
# define _START_TEXT3 NULL
# define _END_TEXT3 NULL
# define _START_BSS3 NULL
# define _END_BSS3 NULL
# define _DATA_INIT3 NULL
# define _START_DATA3 NULL
# define _END_DATA3 NULL
#endif
#if CONFIG_ARCH_NR_MEMORY >= 4
# define _START_TEXT4 ((const void *)&_stext4)
# define _END_TEXT4 ((const void *)&_etext4)
# define _START_BSS4 ((void *)&_sbss4)
# define _END_BSS4 ((void *)&_ebss4)
# define _DATA_INIT4 ((const void *)&_eronly4)
# define _START_DATA4 ((void *)&_sdata4)
# define _END_DATA4 ((void *)&_edata4)
#else
# define _START_TEXT4 NULL
# define _END_TEXT4 NULL
# define _START_BSS4 NULL
# define _END_BSS4 NULL
# define _DATA_INIT4 NULL
# define _START_DATA4 NULL
# define _END_DATA4 NULL
#endif
#if CONFIG_ARCH_NR_MEMORY >= 5
# error CONFIG_ARCH_NR_MEMORY must between 1 to 4
#endif
/****************************************************************************
* Private Function prototypes
****************************************************************************/
static void init_bss_section(bool priv,
void *const bssstart[],
void *const bssend[]);
static void init_data_section(bool priv,
const void *const datasource[],
void *const datastart[],
void *const dataend[]);
static void init_text_section(bool priv,
const void *const textstart[],
const void *const textend[]);
static void init_kernelspace(void);
#ifdef CONFIG_BUILD_PROTECTED
static void init_userspace(void);
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
static void init_bss_section(bool priv,
void *const bssstart[],
void *const bssend[])
{
int i;
for (i = 0; bssstart[i] != _END_MEM || bssend[i] != _END_MEM; i++)
{
if (priv)
{
mpu_priv_data(bssstart[i], bssend[i] - bssstart[i]);
}
else
{
mpu_user_data(bssstart[i], bssend[i] - bssstart[i]);
}
memset(bssstart[i], 0, bssend[i] - bssstart[i]);
}
}
static void init_data_section(bool priv,
const void *const datasource[],
void *const datastart[],
void *const dataend[])
{
int i;
for (i = 0; datasource[i] != _END_MEM
|| datastart[i] != _END_MEM
|| dataend[i] != _END_MEM; i++)
{
if (priv)
{
mpu_priv_data(datastart[i], dataend[i] - datastart[i]);
}
else
{
mpu_user_data(datastart[i], dataend[i] - datastart[i]);
}
if (datasource[i] != datastart[i])
{
memcpy(datastart[i], datasource[i], dataend[i] - datastart[i]);
}
}
}
static void init_text_section(bool priv,
const void *const textstart[],
const void *const textend[])
{
int i;
for (i = 0; textstart[i] != _END_MEM || textend[i] != _END_MEM; i++)
{
if (priv)
{
mpu_priv_code(textstart[i], textend[i] - textstart[i]);
}
else
{
mpu_user_code(textstart[i], textend[i] - textstart[i]);
}
}
}
static void init_kernelspace(void)
{
const void *const textstart[] =
{
_START_TEXT, _START_TEXT2, _START_TEXT3, _START_TEXT4, _END_MEM,
};
const void *const textend[] =
{
_END_TEXT, _END_TEXT2, _END_TEXT3, _END_TEXT4, _END_MEM,
};
const void *const datasource[] =
{
_DATA_INIT, _DATA_INIT2, _DATA_INIT3, _DATA_INIT4, _END_MEM,
};
void *const datastart[] =
{
_START_DATA, _START_DATA2, _START_DATA3, _START_DATA4, _END_MEM,
};
void *const dataend[] =
{
_END_DATA, _END_DATA2, _END_DATA3, _END_DATA4, _END_MEM,
};
void *const bssstart[] =
{
_START_BSS, _START_BSS2, _START_BSS3, _START_BSS4, _END_MEM,
};
void *const bssend[] =
{
_END_BSS, _END_BSS2, _END_BSS3, _END_BSS4, _END_MEM,
};
init_text_section(true, textstart, textend);
/* Move the initialized data section from his temporary holding spot in
* FLASH into the correct place in SRAM. The correct place in SRAM is
* give by _sdata and _edata. The temporary location is in FLASH at the
* end of all of the other read-only data (.text, .rodata) at _eronly.
*/
init_data_section(true, datasource, datastart, dataend);
/* Clear .bss. We'll do this inline (vs. calling memset) just to be
* certain that there are no issues with the state of global variables.
*/
init_bss_section(true, bssstart, bssend);
/* Initialize the idle stack */
mpu_priv_data(g_idle_basestack,
g_idle_topstack - g_idle_basestack);
#ifdef CONFIG_STACK_COLORATION
up_stack_color(g_idle_basestack,
g_idle_topstack - g_idle_basestack - B2C(256));
#endif
}
#ifdef CONFIG_BUILD_PROTECTED
static void init_userspace(void)
{
/* Initialize all of user-space .data */
DEBUGASSERT(
USERSPACE->us_datasource != 0 &&
USERSPACE->us_datastart != 0 &&
USERSPACE->us_dataend != 0);
init_text_section(false,
(const void *const *)USERSPACE->us_textstart,
(const void *const *)USERSPACE->us_textend);
init_data_section(false,
(const void *const *)USERSPACE->us_datasource,
(void *const *)USERSPACE->us_datastart,
(void *const *)USERSPACE->us_dataend);
/* Clear all of user-space .bss */
DEBUGASSERT(
USERSPACE->us_bssstart != 0 &&
USERSPACE->us_bssend != 0);
init_bss_section(false,
(void *const *)USERSPACE->us_bssstart,
(void *const *)USERSPACE->us_bssend);
}
#else
# define init_userspace()
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_start
*
* Description:
* This is the reset entry point.
*
****************************************************************************/
void up_start(void)
{
up_enable_icache();
up_enable_dcache();
init_kernelspace();
init_userspace();
mpu_control(true);
up_earlyserialinit();
up_earlyinitialize();
board_earlyinitialize();
nx_start();
}

View file

@ -0,0 +1,414 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/sched.h>
#include <nuttx/userspace.h>
#include "svcall.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_svcall
*
* Description:
* This is SVCall exception handler that performs context switching
*
****************************************************************************/
int up_svcall(int irq, FAR void *context, FAR void *arg)
{
uint32_t *regs = (uint32_t *)context;
uint32_t cmd;
DEBUGASSERT(regs && regs == CURRENT_REGS);
cmd = regs[REG_A0];
/* The SVCall software interrupt is called with A0 = system call command
* and A1..A6 = variable number of arguments depending on the system call.
*/
#ifdef CONFIG_DEBUG_SYSCALL_INFO
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# endif
{
svcinfo("SVCALL Entry: regs: %p cmd: %d\n", regs, cmd);
svcinfo("A0: %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3],
regs[REG_A4], regs[REG_A5], regs[REG_A6]);
svcinfo("FP: %08x LR: %08x PC: %08x IRQ: %08x OM: %08x\n",
regs[REG_FP], regs[REG_LR], regs[REG_PC], regs[REG_IRQ],
# ifdef REG_OM
regs[REG_OM]
#else
0x00000000
#endif
);
}
#endif
/* Handle the SVCall according to the command in A0 */
switch (cmd)
{
/* A0=SYS_save_context: This is a save context command:
*
* int up_saveusercontext(uint32_t *saveregs);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_save_context
* A1 = saveregs
*
* In this case, we simply need to copy the current regsters to the
* save register space references in the saved A1 and return.
*/
case SYS_save_context:
{
DEBUGASSERT(regs[REG_A1] != 0);
memcpy((uint32_t *)regs[REG_A1], regs, XCPTCONTEXT_SIZE);
}
break;
/* A0=SYS_restore_context: This a restore context command:
*
* void up_fullcontextrestore(uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_restore_context
* A1 = restoreregs
*
* In this case, we simply need to set CURRENT_REGS to restore register
* area referenced in the saved A1. context == CURRENT_REGS is the
* noraml exception return. By setting CURRENT_REGS = context[A1],
* we force the return to the saved context referenced in A1.
*/
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_A1] != 0);
CURRENT_REGS = (uint32_t *)regs[REG_A1];
}
break;
/* A0=SYS_switch_context: This a switch context command:
*
* void up_switchcontext(uint32_t **saveregs, uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_switch_context
* A1 = saveregs
* A2 = restoreregs
*
* In this case, we do both: We save the context registers to the save
* register area reference by the saved contents of A1 and then set
* CURRENT_REGS to to the save register area referenced by the saved
* contents of A2.
*/
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
*(uint32_t **)regs[REG_A1] = regs;
CURRENT_REGS = (uint32_t *)regs[REG_A2];
}
break;
/* A0=SYS_syscall_return: This a syscall return command:
*
* void up_syscall_return(void);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_syscall_return
*
* We need to restore the saved return address and return in
* unprivileged thread mode.
*/
#ifdef CONFIG_LIB_SYSCALL
case SYS_syscall_return:
{
struct tcb_s *rtcb = sched_self();
int index = rtcb->xcp.nsyscalls - 1;
/* Make sure that there is a saved syscall return address. */
DEBUGASSERT(index >= 0);
/* Setup to return to the saved syscall return address in
* the original mode.
*/
regs[REG_PC] = rtcb->xcp.syscall[index].saved_pc;
#ifdef REG_OM
regs[REG_OM] = rtcb->xcp.syscall[index].saved_om;
#endif
rtcb->xcp.nsyscalls = index;
/* The return value must be in A0-A1. up_svcall_handler()
* temporarily moved the value for A0 into A2.
*/
regs[REG_A0] = regs[REG_A2];
}
break;
#endif
/* A0=SYS_task_start: This a user task start
*
* void up_task_start(main_t taskentry, int argc, FAR char *argv[]);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_task_start
* A1 = taskentry
* A2 = argc
* A3 = argv
*/
#ifdef CONFIG_BUILD_PROTECTED
case SYS_task_start:
{
/* Set up to return to the user-space task start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)USERSPACE->task_startup;
#ifdef REG_OM
regs[REG_OM] &= ~REG_OM_MASK;
regs[REG_OM] |= REG_OM_USER;
#endif
/* Change the parameter ordering to match the expectation of struct
* userpace_s task_startup:
*/
regs[REG_A0] = regs[REG_A1]; /* Task entry */
regs[REG_A1] = regs[REG_A2]; /* argc */
regs[REG_A2] = regs[REG_A3]; /* argv */
}
break;
#endif
/* A0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
pthread_addr_t arg);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_pthread_start
* A1 = entrypt
* A2 = arg
*/
#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)USERSPACE->pthread_startup;
#ifdef REG_OM
regs[REG_OM] &= ~REG_OM_MASK;
regs[REG_OM] |= REG_OM_USER;
#endif
/* Change the parameter ordering to match the expectation of struct
* userpace_s pthread_startup:
*/
regs[REG_A0] = regs[REG_A1]; /* pthread entry */
regs[REG_A1] = regs[REG_A2]; /* arg */
}
break;
#endif
/* A0=SYS_signal_handler: This a user signal handler callback
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
* FAR siginfo_t *info, FAR void *ucontext);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_signal_handler
* A1 = sighand
* A2 = signo
* A3 = info
* A4 = ucontext
*/
#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
case SYS_signal_handler:
{
struct tcb_s *rtcb = sched_self();
/* Remember the caller's return address */
DEBUGASSERT(rtcb->xcp.sigreturn == 0);
rtcb->xcp.sigreturn = regs[REG_PC];
/* Set up to return to the user-space signal handler function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler;
#ifdef REG_OM
regs[REG_OM] &= ~REG_OM_MASK;
regs[REG_OM] |= REG_OM_USER;
#endif
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
*/
regs[REG_A0] = regs[REG_A1]; /* sighand */
regs[REG_A1] = regs[REG_A2]; /* signal */
regs[REG_A2] = regs[REG_A3]; /* info */
regs[REG_A3] = regs[REG_A4]; /* ucontext */
}
break;
#endif
/* A0=SYS_signal_handler_return: This a user signal handler callback
*
* void signal_handler_return(void);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_signal_handler_return
*/
#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
case SYS_signal_handler_return:
{
struct tcb_s *rtcb = sched_self();
/* Set up to return to the kernel-mode signal dispatching logic. */
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_PC] = rtcb->xcp.sigreturn;
#ifdef REG_OM
regs[REG_OM] &= ~REG_OM_MASK;
regs[REG_OM] |= REG_OM_KERNEL;
#endif
rtcb->xcp.sigreturn = 0;
}
break;
#endif
/* This is not an architecture-specific system call. If NuttX is built
* as a standalone kernel with a system call interface, then all of the
* additional system calls must be handled as in the default case.
*/
default:
{
#ifdef CONFIG_LIB_SYSCALL
FAR struct tcb_s *rtcb = sched_self();
int index = rtcb->xcp.nsyscalls;
/* Verify that the SYS call number is within range */
DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall);
DEBUGASSERT(index < CONFIG_SYS_NNEST);
/* Setup to return to up_svcall_handler in privileged mode. */
rtcb->xcp.syscall[index].saved_pc = regs[REG_PC];
#ifdef REG_OM
rtcb->xcp.syscall[index].saved_om = regs[REG_OM];
#endif
rtcb->xcp.nsyscalls = index + 1;
regs[REG_PC] = (uint32_t)up_svcall_handler;
#ifdef REG_OM
regs[REG_OM] &= ~REG_OM_MASK;
regs[REG_OM] |= REG_OM_KERNEL;
#endif
/* Offset A0 to account for the reserved values */
regs[REG_A0] -= CONFIG_SYS_RESERVED;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif
}
break;
}
/* Report what happened.
* That might be different in the case of a context switch
*/
#ifdef CONFIG_DEBUG_SYSCALL_INFO
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# else
if (regs != CURRENT_REGS)
# endif
{
svcinfo("SVCall Return:\n");
svcinfo("A0: %08x %08x %08x %08x %08x %08x %08x\n",
CURRENT_REGS[REG_A0], CURRENT_REGS[REG_A1],
CURRENT_REGS[REG_A2], CURRENT_REGS[REG_A3],
CURRENT_REGS[REG_A4], CURRENT_REGS[REG_A5],
CURRENT_REGS[REG_A6]);
svcinfo("FP: %08x LR: %08x PC: %08x IRQ: %08x OM: %08x\n",
CURRENT_REGS[REG_FP], CURRENT_REGS[REG_LR],
CURRENT_REGS[REG_PC], CURRENT_REGS[REG_IRQ],
# ifdef REG_OM
CURRENT_REGS[REG_OM]
#else
0x00000000
#endif
);
}
# ifdef CONFIG_DEBUG_SVCALL
else
{
svcinfo("SVCall Return: %d\n", regs[REG_A0]);
}
# endif
#endif
return OK;
}

View file

@ -0,0 +1,51 @@
/****************************************************************************
* arch/ceva/src/common/up_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 "svcall.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_switchcontext
*
* Description:
* Save the current thread context and restore the specified context.
* Full prototype is:
*
* void up_switchcontext(uint32_t **saveregs, uint32_t *restoreregs);
*
* Return:
* None
*
****************************************************************************/
void up_switchcontext(uint32_t **saveregs, uint32_t *restoreregs)
{
/* Let sys_call2() do all of the work */
sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs);
}

View file

@ -0,0 +1,70 @@
/****************************************************************************
* arch/ceva/src/common/up_task_start.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include "svcall.h"
#if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_task_start
*
* Description:
* In this kernel mode build, this function will be called to execute a
* task in user-space. When the task is first started, a kernel-mode
* stub will first run to perform some housekeeping functions. This
* kernel-mode stub will then be called transfer control to the user-mode
* task.
*
* Normally the a user-mode start-up stub will also execute before the
* task actually starts. See libc/sched/task_startup.c
*
* Input Parameters:
* taskentry - The user-space entry point of the task.
* argc - The number of parameters being passed.
* argv - The parameters being passed. These lie in kernel-space memory
* and will have to be reallocated in user-space memory.
*
* Returned Value:
* This function should not return. It should call the user-mode start-up
* stub and that stub should call exit if/when the user task terminates.
*
****************************************************************************/
void up_task_start(main_t taskentry, int argc, FAR char *argv[])
{
/* Let sys_call3() do all of the work */
sys_call3(SYS_task_start, (uintptr_t)taskentry, (uintptr_t)argc,
(uintptr_t)argv);
while (1); /* Shut up the compiler warning */
}
#endif /* CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL */

View file

@ -0,0 +1,128 @@
/****************************************************************************
* arch/ceva/src/common/up_unblocktask.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 <nuttx/config.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_unblock_task
*
* Description:
* A task is currently in an inactive task list
* but has been prepped to execute. Move the TCB to the
* ready-to-run list, restore its context, and start execution.
*
* Inputs:
* tcb: Refers to the tcb to be unblocked. This tcb is
* in one of the waiting tasks lists. It must be moved to
* the ready-to-run list and, if it is the highest priority
* ready to run taks, executed.
*
****************************************************************************/
void up_unblock_task(struct tcb_s *tcb)
{
struct tcb_s *rtcb = this_task();
/* Verify that the context switch can be performed */
DEBUGASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) &&
(tcb->task_state <= LAST_BLOCKED_STATE));
/* Remove the task from the blocked task list */
sched_removeblocked(tcb);
/* Add the task in the correct location in the prioritized
* ready-to-run task list
*/
if (sched_addreadytorun(tcb))
{
/* The currently active task has changed! We need to do
* a context switch to the new task.
*/
/* Update scheduler parameters */
sched_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.
*/
rtcb->xcp.regs = CURRENT_REGS;
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
CURRENT_REGS = rtcb->xcp.regs;
}
/* No, then we will need to perform the user context switch */
else
{
struct tcb_s *nexttcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_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.
*/
}
}
}

View file

@ -0,0 +1,231 @@
/****************************************************************************
* arch/ceva/src/common/up_userspace.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/init.h>
#include <nuttx/mm/mm.h>
#include <nuttx/wqueue.h>
#include <nuttx/userspace.h>
#include "up_internal.h"
#ifdef CONFIG_BUILD_PROTECTED
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if CONFIG_ARCH_USER_DEFAULT_HEAP == 0
# define MM_HEAP1 &g_mmheap
#else
static struct mm_heap_s g_mmheap1;
# define MM_HEAP1 &g_mmheap1
#endif
#if CONFIG_ARCH_NR_USER_MEMORY >= 2
# if CONFIG_ARCH_USER_DEFAULT_HEAP == 1
# define MM_HEAP2 &g_mmheap
# else
static struct mm_heap_s g_mmheap2;
# define MM_HEAP2 &g_mmheap2
# endif
# define _START_TEXT2 ((const void *)&_stext2)
# define _END_TEXT2 ((const void *)&_etext2)
# define _START_BSS2 ((void *)&_sbss2)
# define _END_BSS2 ((void *)&_ebss2)
# define _DATA_INIT2 ((const void *)&_eronly2)
# define _START_DATA2 ((void *)&_sdata2)
# define _END_DATA2 ((void *)&_edata2)
# define _END_HEAP2 ((void *)&_eheap2)
#else
# define MM_HEAP2 NULL
# define _START_TEXT2 NULL
# define _END_TEXT2 NULL
# define _START_BSS2 NULL
# define _END_BSS2 NULL
# define _DATA_INIT2 NULL
# define _START_DATA2 NULL
# define _END_DATA2 NULL
# define _END_HEAP2 NULL
#endif
#if CONFIG_ARCH_NR_USER_MEMORY >= 3
# if CONFIG_ARCH_USER_DEFAULT_HEAP == 2
# define MM_HEAP3 &g_mmheap
# else
static struct mm_heap_s g_mmheap3;
# define MM_HEAP3 &g_mmheap3
# endif
# define _START_TEXT3 ((const void *)&_stext3)
# define _END_TEXT3 ((const void *)&_etext3)
# define _START_BSS3 ((void *)&_sbss3)
# define _END_BSS3 ((void *)&_ebss3)
# define _DATA_INIT3 ((const void *)&_eronly3)
# define _START_DATA3 ((void *)&_sdata3)
# define _END_DATA3 ((void *)&_edata3)
# define _END_HEAP3 ((void *)&_eheap3)
#else
# define MM_HEAP3 NULL
# define _START_TEXT3 NULL
# define _END_TEXT3 NULL
# define _START_BSS3 NULL
# define _END_BSS3 NULL
# define _DATA_INIT3 NULL
# define _START_DATA3 NULL
# define _END_DATA3 NULL
# define _END_HEAP3 NULL
#endif
#if CONFIG_ARCH_NR_USER_MEMORY >= 4
# if CONFIG_ARCH_USER_DEFAULT_HEAP == 3
# define MM_HEAP4 &g_mmheap
# else
static struct mm_heap_s g_mmheap4;
# define MM_HEAP4 &g_mmheap4
# endif
# define _START_TEXT4 ((const void *)&_stext4)
# define _END_TEXT4 ((const void *)&_etext4)
# define _START_BSS4 ((void *)&_sbss4)
# define _END_BSS4 ((void *)&_ebss4)
# define _DATA_INIT4 ((const void *)&_eronly4)
# define _START_DATA4 ((void *)&_sdata4)
# define _END_DATA4 ((void *)&_edata4)
# define _END_HEAP4 ((void *)&_eheap4)
#else
# define MM_HEAP4 NULL
# define _START_TEXT4 NULL
# define _END_TEXT4 NULL
# define _START_BSS4 NULL
# define _END_BSS4 NULL
# define _DATA_INIT4 NULL
# define _START_DATA4 NULL
# define _END_DATA4 NULL
# define _END_HEAP4 NULL
#endif
#if CONFIG_ARCH_NR_USER_MEMORY >= 5
# error CONFIG_ARCH_NR_USER_MEMORY must between 1 to 4
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static const void *const g_textstart[] =
{
_START_TEXT, _START_TEXT2, _START_TEXT3, _START_TEXT4, _END_MEM,
};
static const void *const g_textend[] =
{
_END_TEXT, _END_TEXT2, _END_TEXT3, _END_TEXT4, _END_MEM,
};
static const void *const g_datasource[] =
{
_DATA_INIT, _DATA_INIT2, _DATA_INIT3, _DATA_INIT4, _END_MEM,
};
static void *const g_datastart[] =
{
_START_DATA, _START_DATA2, _START_DATA3, _START_DATA4, _END_MEM,
};
static void *const g_dataend[] =
{
_END_DATA, _END_DATA2, _END_DATA3, _END_DATA4, _END_MEM,
};
static void *const g_bssstart[] =
{
_START_BSS, _START_BSS2, _START_BSS3, _START_BSS4, _END_MEM,
};
static void *const g_bssend[] =
{
_END_BSS, _END_BSS2, _END_BSS3, _END_BSS4, _END_MEM,
};
static void *const g_heapend[] =
{
_END_HEAP, _END_HEAP2, _END_HEAP3, _END_HEAP4, _END_MEM,
};
/****************************************************************************
* Public Data
****************************************************************************/
struct mm_heap_s *const g_mm_heap[] =
{
MM_HEAP1, MM_HEAP2, MM_HEAP3, MM_HEAP4, NULL,
};
const struct userspace_s userspace __attribute__ ((section ("userspace"))) =
{
/* General memory map */
.us_base =
{
.us_entrypoint = CONFIG_USER_ENTRYPOINT,
.us_textstart = (uintptr_t)g_textstart,
.us_textend = (uintptr_t)g_textend,
.us_datasource = (uintptr_t)g_datasource,
.us_datastart = (uintptr_t)g_datastart,
.us_dataend = (uintptr_t)g_dataend,
.us_bssstart = (uintptr_t)g_bssstart,
.us_bssend = (uintptr_t)g_bssend,
.us_heapend = (uintptr_t)g_heapend,
/* Memory manager heap structure */
.us_heap = (struct mm_heap_s *)g_mm_heap,
/* Task/thread startup routines */
.task_startup = task_startup,
#ifndef CONFIG_DISABLE_PTHREAD
.pthread_startup = pthread_startup,
#endif
/* Signal handler trampoline */
#ifndef CONFIG_DISABLE_SIGNALS
.signal_handler = up_signal_handler,
#endif
/* User-space work queue support (declared in include/nuttx/wqueue.h) */
#ifdef CONFIG_LIB_USRWORK
.work_usrstart = work_usrstart,
#endif
},
};
/****************************************************************************
* Public Functions
****************************************************************************/
#endif /* CONFIG_BUILD_PROTECTED */

View file

@ -0,0 +1,142 @@
/****************************************************************************
* arch/ceva/src/common/up_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 <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Macros
****************************************************************************/
/* Stack alignment macros */
#define STACK_ALIGN_MASK (sizeof(uint32_t) - 1)
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
/****************************************************************************
* 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 task_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
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
* initial value of the stack pointer.
*
* Inputs:
* - 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(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
{
FAR void *top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS
/* Make certain that the user provided stack is properly aligned */
DEBUGASSERT((uintptr_t)stack & (B2C(TLS_STACK_ALIGN) - 1) == 0);
#else
DEBUGASSERT((uintptr_t)stack & STACK_ALIGN_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;
/* The CEVA 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.
*/
/* The CEVA stack must be aligned to 4-byte alignment.
* If necessary size_of_stack must be rounded down to the next
* boundary
*/
size_of_stack = STACK_ALIGN_DOWN(stack_size);
top_of_stack = tcb->stack_alloc_ptr + size_of_stack;
/* Save the adjusted stack values in the struct tcb_s */
tcb->adj_stack_ptr = top_of_stack;
tcb->adj_stack_size = size_of_stack;
#ifdef CONFIG_TLS
/* Initialize the TLS data structure */
memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
#endif
#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.
*/
#ifdef CONFIG_TLS
up_stack_color(
tcb->stack_alloc_ptr + sizeof(struct tls_info_s),
tcb->adj_stack_size - sizeof(struct tls_info_s));
#else
up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
#endif
#endif
return OK;
}

View file

@ -0,0 +1,208 @@
/****************************************************************************
* arch/ceva/src/common/up_vfork.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 <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include "sched/sched.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* any data other than a variable of type pid_t used to store the return
* value from vfork(), or returns from the function in which vfork() was
* called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls nxtask_vforksetup().
* 3) nxtask_vforksetup() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart()
* 6) nxtask_vforkstart() then executes the child thread.
*
* nxtask_vforkabort() may be called if an error occurs between steps 3 & 6.
*
* Input Parameters:
* regs - Caller context information saved by vfork()
*
* Return:
* Upon successful completion, vfork() returns 0 to the child process and
* returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
pid_t up_vfork(const uint32_t *regs)
{
#ifdef CONFIG_SCHED_WAITPID
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
size_t stacksize;
const void *sp = regs + XCPTCONTEXT_REGS;
void *newsp;
uint32_t newfp;
uint32_t stackutil;
size_t argsize;
void *argv;
int ret;
/* Allocate and initialize a TCB for the child task. */
child = nxtask_vforksetup(parent->start, &argsize);
if (!child)
{
serr("ERROR: nxtask_vforksetup failed\n");
return (pid_t)ERROR;
}
sinfo("TCBs: Parent=%p Child=%p\n", parent, child);
/* Get the size of the parent task's stack. */
stacksize = parent->adj_stack_size;
/* Allocate the stack for the TCB */
ret = up_create_stack((FAR struct tcb_s *)child, C2B(stacksize + argsize),
parent->flags & TCB_FLAG_TTYPE_MASK);
if (ret != OK)
{
serr("ERROR: up_create_stack failed: %d\n", ret);
nxtask_vforkabort(child, -ret);
return (pid_t)ERROR;
}
/* Allocate the memory and copy argument from parent task */
argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
memcpy(argv, parent->adj_stack_ptr, argsize);
/* How much of the parent's stack was utilized? The CEVA uses
* a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two.
*/
DEBUGASSERT(parent->adj_stack_ptr >= sp);
stackutil = parent->adj_stack_ptr - sp;
sinfo("Parent: stacksize:%d stackutil:%d\n", stacksize, stackutil);
/* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* effort is overkill.
*/
newsp = child->cmn.adj_stack_ptr - stackutil;
memcpy(newsp, sp, stackutil);
/* Allocate the context and copy the parent snapshot */
newsp -= XCPTCONTEXT_SIZE;
memcpy(newsp, regs, XCPTCONTEXT_SIZE);
child->cmn.xcp.regs = newsp;
/* Was there a frame pointer in place before? */
if (regs[REG_FP] <= (uint32_t)parent->adj_stack_ptr &&
regs[REG_FP] >= (uint32_t)parent->adj_stack_ptr - stacksize)
{
uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - regs[REG_FP];
newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
}
else
{
newfp = regs[REG_FP];
}
sinfo("Parent: stack base:%08x SP:%08x FP:%08x\n",
parent->adj_stack_ptr, sp, regs[REG_FP]);
sinfo("Child: stack base:%08x SP:%08x FP:%08x\n",
child->cmn.adj_stack_ptr, newsp, newfp);
/* Update the stack pointer, frame pointer, and the return value in A0
* should be cleared to zero, providing the indication to the newly started
* child thread.
*/
child->cmn.xcp.regs[REG_A0] = 0; /* Return value */
child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->cmn.xcp.regs[REG_PC] = regs[REG_LR]; /* Program counter */
child->cmn.xcp.regs[REG_SP] = (uint32_t)newsp; /* Stack pointer */
#ifdef CONFIG_LIB_SYSCALL
/* If we got here via a syscall, then we are going to have to setup some
* syscall return information as well.
*/
if (parent->xcp.nsyscalls > 0)
{
int index;
for (index = 0; index < parent->xcp.nsyscalls; index++)
{
child->cmn.xcp.syscall[index] = parent->xcp.syscall[index];
}
child->cmn.xcp.nsyscalls = parent->xcp.nsyscalls;
}
#endif
/* And, finally, start the child task. On a failure, nxtask_vforkstart()
* will discard the TCB by calling nxtask_vforkabort().
*/
return nxtask_vforkstart(child);
#else /* CONFIG_SCHED_WAITPID */
return (pid_t)ERROR;
#endif
}

View file

@ -0,0 +1,152 @@
/****************************************************************************
* arch/ceva/src/common/vintc.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_CEVA_SRC_COMMON_VINTC_H
#define __ARCH_CEVA_SRC_COMMON_VINTC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: up_vintc_initialize
*
* Description:
* Initialize the VINTC.
*
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_VINTC
void up_vintc_initialize(void);
#else
static inline void up_vintc_initialize(void)
{
}
#endif
/****************************************************************************
* Name: up_vintc_enable_irq
*
* Description:
* On CEVA architectures, there are four levels of interrupt enabling:
* (1) at the global level(up_irq_enable)
* (2) at the DSP level(up_enable_irq)
* (2) at the VINTC level
* (3) at the device level
* In order to receive interrupts, they must be enabled at all four levels.
*
* This function implements enabling of the device specified by 'irq'
* at the VINTC level if supported by the architecture.
*
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_VINTC
void up_vintc_enable_irq(int irq);
#else
static inline void up_vintc_enable_irq(int irq)
{
}
#endif
/****************************************************************************
* Name: up_vintc_disable_irq
*
* Description:
* This function implements disabling of the device specified by 'irq'
* at the VINTC level if supported by the architecture(up_irq_save()
* supports the global level, the device level is hardware specific).
*
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_VINTC
void up_vintc_disable_irq(int irq);
#else
static inline void up_vintc_disable_irq(int irq)
{
}
#endif
/****************************************************************************
* Name: up_vintc_prioritize_irq
*
* Description:
* Set the priority of an IRQ.
*
****************************************************************************/
#if defined(CONFIG_ARCH_HAVE_VINTC) && defined(CONFIG_ARCH_IRQPRIO)
int up_vintc_prioritize_irq(int irq, int priority);
#else
static inline int up_vintc_prioritize_irq(int irq, int priority)
{
return 0; /* Not a critical error */
}
#endif
/****************************************************************************
* Name: up_vintc_trigger_irq
*
* Description:
* Trigger an IRQ by software.
*
****************************************************************************/
#if defined(CONFIG_ARCH_HAVE_VINTC) && defined(CONFIG_ARCH_HAVE_IRQTRIGGER)
void up_vintc_trigger_irq(int irq);
#else
static inline void up_vintc_trigger_irq(int irq)
{
}
#endif
/****************************************************************************
* Name: up_vintc_handler
*
* Description:
* This function address must be sent from VINTC on VECTOR input in order
* to let DSP could jump to the appropriate interrupt handler location.
* Note that VINTC may pass this address to the hardware register, but
* ARCH specific code is responsible to implement this function.
*
****************************************************************************/
void up_vintc_handler(void);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ARCH_CEVA_SRC_COMMON_VINTC_H */

11
arch/ceva/src/xc5/Kconfig Normal file
View file

@ -0,0 +1,11 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
comment "XC5 Configuration Options"
config XC5_PSU_ENABLE
bool "Enable power management of XC5"
---help---
Doze or idle mode of xc5 power managerment.

View file

@ -0,0 +1,68 @@
############################################################################
# arch/ceva/src/xc5/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.
#
############################################################################
RTL_VERSION := $(CONFIG_ARCH_RTL_MAJOR).$(CONFIG_ARCH_RTL_MINOR).$(CONFIG_ARCH_RTL_REVISION)
ITCM_KB := $(shell expr $(CONFIG_ARCH_ITCM_SIZE) / 1024)
DTCM_KB := $(shell expr $(CONFIG_ARCH_DTCM_SIZE) / 1024)
#
# Supported toolchains
#
# Each toolchain definition should set:
#
# CROSSDEV The GNU toolchain triple (command prefix)
# ARCROSSDEV If required, an alternative prefix used when
# invoking ar and nm.
# ARCHCPUFLAGS CPU-specific flags selecting the instruction set
# FPU options, etc.
# MAXOPTIMIZATION The maximum optimization level that results in
# reliable code generation.
#
ARCROSSDEV ?= $(CROSSDEV)
ifneq ($(CROSSDEV),)
export LD_LIBRARY_PATH := $(CROSSDEV):$(LD_LIBRARY_PATH)
export PATH := $(CROSSDEV):$(PATH)
export CEVAXMTOOLS := $(CROSSDEV)
endif
ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y)
MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL)
else ifeq ($(CONFIG_DEBUG_FULLOPT),y)
MAXOPTIMIZATION := -O3 -Os3
endif
ARCHCPUFLAGS = -mrtl-version-$(RTL_VERSION) -Wa,-rtl$(RTL_VERSION)
ARCHCPUFLAGS += -Wa,-p -mmsg-full-path -TARG:arch=cevaxc5 -Wa,-vdiv4 -Wno-unused
LDFLAGS = -alignAllSections,c:0x20,d:0x4 -cevaxc5 -removeUnRefFunc
LDFLAGS += -internalCode$(ITCM_KB) -internalData$(DTCM_KB)
LIBGCC = $(CROSSDEV)libs/xc5/cevaxclib.lib
LIBGCC += $(CROSSDEV)libs/xc5/libcc.lib
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
WINTOOL = y
endif
CC = $(CROSSDEV)/cevaxccc -mquiet -Wa,-quiet
CXX = $(CROSSDEV)/cevaxccc -mquiet -Wa,-quiet -x c++
CPP = $(CROSSDEV)/cevaxccc -mquiet -Wa,-quiet -E -P -x c

75
arch/ceva/src/xc5/cpm.S Normal file
View file

@ -0,0 +1,75 @@
/****************************************************************************
* arch/ceva/src/xc5/cpm.S
*
* 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.
*
****************************************************************************/
.file "cpm.S"
.text
.public _getcpm
.func_start 2 _getcpm
_getcpm:
push {dw} r0
mov a0, r0
nop
in {dw,cpm} (r0), r0
nop
nop
nop
mov r0, a0
pop {dw} r0
ret
.func_end 2 _getcpm
.public _putcpm
.func_start 2 _putcpm
_putcpm:
push {dw} r0
push {dw} r1
mov a0, r0
mov a1, r1
nop
out {dw,cpm} r1, (r0)
pop {dw} r1
pop {dw} r0
ret
.func_end 2 _putcpm
.public _modifycpm
.func_start 2 _modifycpm
_modifycpm:
push {dw} r0
push {dw} r1
mov a0, r0
nop
in {dw,cpm} (r0), r1
nop
nop
nop
mov r1, a0
not a1, a1
and a0, a1, a0
or a0, a2, a0
nop
mov a0, r1
nop
out {dw,cpm} r1, (r0)
pop {dw} r1
pop {dw} r0
ret
.func_end 2 _modifycpm

52
arch/ceva/src/xc5/cpm.h Normal file
View file

@ -0,0 +1,52 @@
/****************************************************************************
* arch/ceva/src/xc5/cpm.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_CEVA_SRC_XC5_CPM_H
#define __ARCH_CEVA_SRC_XC5_CPM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
uint32_t getcpm(uintptr_t addr);
void putcpm(uintptr_t addr, uint32_t value);
void modifycpm(uintptr_t addr, uint32_t clearbits, uint32_t setbits);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif
#endif /* __ARCH_CEVA_SRC_XC5_CPM_H */

42
arch/ceva/src/xc5/psu.h Normal file
View file

@ -0,0 +1,42 @@
/****************************************************************************
* arch/ceva/src/xc5/psu.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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ARCH_CEVA_SRC_XC5_PSU_H
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define XC5_DOZE 0x1ff2
#define XC5_IDLE 0x1ff3
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
void up_psu_lp(int value);
#endif /* __ARCH_CEVA_SRC_XC5_PSU_H */

View file

@ -0,0 +1,78 @@
/****************************************************************************
* arch/ceva/src/xc5/syscall.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "syscall.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sys_callx
*
* Description:
* This function generate the trap exception with the specified number of
* parameters.
*
* a0 = SYS_ call number
* a1 = parm0
* a2 = parm1
* a3 = parm2
* a4 = parm3
* a5 = parm4
* a6 = parm5
* a7 = parm6
*
****************************************************************************/
.text
.public _sys_call0
.public _sys_call1
.public _sys_call2
.public _sys_call3
.public _sys_call4
.public _sys_call5
.public _sys_call6
.func_start 2 _sys_call0
_sys_call0:
_sys_call1:
_sys_call2:
_sys_call3:
_sys_call4:
_sys_call5:
_sys_call6:
trap0
nop
ret
.func_end 2 _sys_call0

View file

@ -0,0 +1,93 @@
/****************************************************************************
* arch/ceva/src/xc5/up_hardfault.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 <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include "cpm.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define REG_P_MAPAR 0x00a0
#define REG_P_MAPSR 0x00a4
#define REG_UOP_STS 0x0238
#define REG_UOP_PAR 0x023c
#define REG_DBG_GEN 0x028c
#ifdef CONFIG_DEBUG_HARDFAULT
# define hfalert(format, ...) _alert(format, ##__VA_ARGS__)
#else
# define hfalert(x...)
#endif
#define hfdumpreg1(reg) \
hfalert("%s: %08x\n", \
#reg, getcpm(REG_##reg))
#define hfdumpreg2(reg1, reg2) \
hfalert("%s: %08x %s: %08x\n", \
#reg1, getcpm(REG_##reg1), \
#reg2, getcpm(REG_##reg2))
#define hfdumpreg3(reg1, reg2, reg3) \
hfalert("%s: %08x %s: %08x %s: %08x\n", \
#reg1, getcpm(REG_##reg1), \
#reg2, getcpm(REG_##reg2), \
#reg3, getcpm(REG_##reg3))
#define hfdumpreg4(reg1, reg2, reg3, reg4) \
hfalert("%s: %08x %s: %08x %s: %08x %s: %08x\n",\
#reg1, getcpm(REG_##reg1), \
#reg2, getcpm(REG_##reg2), \
#reg3, getcpm(REG_##reg3), \
#reg4, getcpm(REG_##reg4))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_hardfault
*
* Description:
* This is Hard Fault exception handler.
*
****************************************************************************/
int up_hardfault(int irq, FAR void *context, FAR void *arg)
{
/* Dump some hard fault info */
hfalert("Hard Fault:\n");
hfdumpreg4(P_MAPAR, P_MAPSR, UOP_STS, UOP_PAR);
hfdumpreg1(REG_DBG_GEN);
PANIC();
return OK;
}

302
arch/ceva/src/xc5/up_head.S Normal file
View file

@ -0,0 +1,302 @@
/****************************************************************************
* arch/ceva/src/xc5/up_head.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK == 0
# undef CONFIG_ARCH_INTERRUPTSTACK
# define CONFIG_ARCH_INTERRUPTSTACK CONFIG_IDLETHREAD_STACKSIZE
#endif
.MACRO IRQ_HANDLER irq retx
push {dw} retreg
push {16dw,l} r4, a8
nop
mov #irq, a0
call {t} INCODE exception_common
pop {16dw,l} r4, a8
pop {dw} retreg
retx
.ENDM
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "up_head.S"
.extern _g_idle_topstack
.extern _g_idle_basestack
.extern _up_doirq
.extern _up_start
.extern _up_relocate
/****************************************************************************
* Interrupt Functions
****************************************************************************/
.CSECT inttbl
br {t} reset_handler
.ORG 0x20
IRQ_HANDLER IRQ_TRAPE, retb
.ORG 0x40
IRQ_HANDLER IRQ_TRAP, reti
.ORG 0x60
IRQ_HANDLER IRQ_NMI, retn
.ORG 0x80
IRQ_HANDLER IRQ_INT0, reti
.ORG 0xc0
IRQ_HANDLER IRQ_INT1, reti
.ORG 0x100
IRQ_HANDLER IRQ_INT2, reti
.ORG 0x140
IRQ_HANDLER IRQ_INT3, reti
.ORG 0x180
IRQ_HANDLER IRQ_INT4, reti
.ORG 0x200
IRQ_HANDLER IRQ_TRAP0, reti
.ORG 0x240
IRQ_HANDLER IRQ_TRAP1, reti
.ORG 0x280
IRQ_HANDLER IRQ_TRAP2, reti
.ORG 0x2c0
IRQ_HANDLER IRQ_TRAP3, reti
.ORG 0x300
.GLOBAL _up_vintc_handler
_up_vintc_handler:
IRQ_HANDLER IRQ_VINT, reti
.CSECT resetsec
reset_handler:
mov #0x0, mod0
mov #0x0, mod1
mov #0x0, mod2
mov modg, a0
and a0, #0x300, a0
or a0, #0x0000001b, a0
mov a0, modg
mov #0xf0, modpb
ld {dw} (#_g_idle_topstack), a0
nop
nop
nop
nop
mov a0, sp
nop
nop
push {dw} retreg
callr {t} _up_relocate
pop {dw} retreg
brr {t} _up_start
/****************************************************************************
* Private Functions
****************************************************************************/
/* Common exception handling logic, need sync with:
* arch/ceva/include/xc5/reg.h
*/
.func_start 3 exception_common
exception_common:
/* Note: a0 contain exception number
* Complete the context save
*/
push {16dw,h} auxreg1
push {16dw,h} r4, a8
push {dw} mod3
push {4dw} modx
bkst
push {16dw,h} auxreg0
push {16dw,h} auxreg2
push {16dw,l} auxreg1
push {16dw,l} auxreg0
push {16dw,l} auxreg2
nop
/*#ifndef CONFIG_ARCH_XC5_NO_VPU
vpush{8dw} via0
vpush{8dw} vib0
vpush{8dw} vic0
vpush{8dw} vid0
vpush{8dw} vie0
vpush{8dw} vif0
vpush{8dw} vig0
vpush{8dw} vih0
vpush{8dw} voa0e
vpush{8dw} voa0
vpush{8dw} vob0e
vpush{8dw} vob0
vpush{8dw} vc0
vpush{8dw} vpr0
vpush{dw} modv0
vpush{dw} modv1
#endif*/
mov lci0, g4
mov lci1, g5 || bkst
mov lci2, g6
mov lci3, g7
mov lcstep0, modu2
mov lcstep1, modu3
push {8dw} auxreg1
nop
bkst
push {dw} bknest0
push {dw} bknest1
bkst
push {dw} bknest0
push {dw} bknest1
nop
nop
nop
subsps #1
nop
mov sp, r0
nop
st {dw} sp, (r0)
/* Prepare the C language environment */
mov #0x0, mod0
mov #0x0, mod1
mov #0x0, mod2
mov modg, a1
and a1, #0x300, a1
or a1, #0x0000001b, a1
mov a1, modg
/* There are two arguments to up_doirq:
*
* a0 = The IRQ number
* r0 = The top of the stack points to the saved state
*/
/* Switch to the dedicated stack */
mov #_g_intstackbase, r1
nop
mov r1, sp
nop
nop
push {dw} retreg
mov #_up_doirq, r1
nop
nop
callar r1
pop {dw} retreg
/* On return from up_doirq, r0 will hold a pointer to register context
* array to use for the interrupt return.
*/
mov r0, sp
addsps #1
nop
nop
/* Unwind the same stack frame that we created at entry */
pop {dw} bknest1
pop {dw} bknest0
nop
nop
bkrest
pop {dw} bknest1
pop {dw} bknest0
nop
nop
bkrest
pop {8dw} auxreg1
nop
nop
nop
bkrest
mov modu3, lcstep1
mov modu2, lcstep0
mov g7, lci3
mov g6, lci2
mov g5, lci1
mov g4, lci0
/*#ifndef CONFIG_ARCH_XC5_NO_VPU
vpop{dw} modv1
vpop{dw} modv0
vpop{8dw} vpr0
vpop{8dw} vc0
vpop{8dw} vob0
vpop{8dw} vob0e
vpop{8dw} voa0
vpop{8dw} voa0e
vpop{8dw} vih0
vpop{8dw} vig0
vpop{8dw} vif0
vpop{8dw} vie0
vpop{8dw} vid0
vpop{8dw} vic0
vpop{8dw} vib0
vpop{8dw} via0
#endif*/
pop {16dw,l} auxreg2
pop {16dw,l} auxreg0
pop {16dw,l} auxreg1
nop
nop
pop {16dw,h} auxreg2
pop {16dw,h} auxreg0
pop {4dw} modx
pop {dw} mod3
pop {16dw,h} r4, a8
bkrest
pop {16dw,h} auxreg1
ret
.func_end 3 exception_common
.bss
.public _g_intstackalloc
.public _g_intstackbase
_g_intstackalloc:
DD CONFIG_ARCH_INTERRUPTSTACK/4 dup ?
_g_intstackbase:

View file

@ -0,0 +1,294 @@
/****************************************************************************
* arch/ceva/src/xc5/up_icache.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 <nuttx/config.h>
#include <nuttx/cache.h>
#include <nuttx/irq.h>
#include "cpm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MSS_PCR 0x0000
#define P_ADD0_ATT0 0x0014
#define P_CCOSAR 0x0090
#define P_CCOCR 0x0094
#define MSS_HDCFG 0x021c
#define MSS_PCR_CAC_PFE 0x00000004
#define P_ADD0_ATT0_L1IC 0x00000001
#define P_ADD0_ATT0_L1IC_LOCK 0x00000002
#define P_CCOCR_L1ICO 0x00000002
#define P_CCOCR_OT_PREFETCH 0x00000004
#define P_CCOCR_OT_LOCK 0x00000008
#define P_CCOCR_OT_UNLOCK 0x0000000c
#define P_CCOCR_OT_INVALIDATE 0x00000010
#define P_CCOCR_OT_MASK 0x0000003c
#define P_CCOCR_OS_ENTIRE 0x00000080
#define P_CCOCR_NOBPL_SHIFT 16
#define P_CCOCR_NOBPL_MASK 0xffff0000
#define MSS_HDCFG_PCAC_SZE_0KB 0x00000000
#define MSS_HDCFG_PCAC_SZE_32KB 0x00001000
#define MSS_HDCFG_PCAC_SZE_64KB 0x00002000
#define MSS_HDCFG_PCAC_SZE_128KB 0x00003000
#define MSS_HDCFG_PCAC_SZE_MASK 0x00007000
#define MSS_CACHE_BLOCK_SIZE 64
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_CEVA_ICACHE
static void maintain_icache_all(uint32_t op)
{
irqstate_t flags;
/* Disable irq */
flags = up_irq_save();
/* Start the operation on the entire cache */
putcpm(P_CCOCR, P_CCOCR_L1ICO | op | P_CCOCR_OS_ENTIRE);
while (getcpm(P_CCOCR) & P_CCOCR_L1ICO)
{
/* Loop until the operation finish */;
}
/* Restore irq */
up_irq_restore(flags);
}
static void maintain_icache(uint32_t op, uintptr_t start, uintptr_t end)
{
static size_t op_maxblocks;
/* Initialize op_maxblocks if not yet */
if (op_maxblocks == 0)
{
switch (getcpm(MSS_HDCFG) & MSS_HDCFG_PCAC_SZE_MASK)
{
case MSS_HDCFG_PCAC_SZE_32KB:
op_maxblocks = 512;
break;
case MSS_HDCFG_PCAC_SZE_64KB:
op_maxblocks = 1024;
break;
case MSS_HDCFG_PCAC_SZE_128KB:
op_maxblocks = 2048;
break;
default:
op_maxblocks = 1;
break;
}
}
/* Align the address to the cache block boundary */
start &= ~(MSS_CACHE_BLOCK_SIZE - 1);
end += (MSS_CACHE_BLOCK_SIZE - 1);
end &= ~(MSS_CACHE_BLOCK_SIZE - 1);
/* Skip dtcm since it never put into dcache */
if (end > CONFIG_ARCH_ITCM_SIZE)
{
if (start < CONFIG_ARCH_ITCM_SIZE)
{
start = CONFIG_ARCH_ITCM_SIZE;
}
while (start < end)
{
irqstate_t flags;
size_t op_blocks;
/* Get the max blocks we can do in one iteration */
op_blocks = (end - start) / MSS_CACHE_BLOCK_SIZE;
if (op_blocks > op_maxblocks)
{
op_blocks = op_maxblocks;
}
/* Disable irq */
flags = up_irq_save();
/* Set the cache address */
putcpm(P_CCOSAR, start);
/* Start the cache operation */
putcpm(P_CCOCR, /* Address based operation */
P_CCOCR_L1ICO | op | (op_blocks << P_CCOCR_NOBPL_SHIFT));
while (getcpm(P_CCOCR) & P_CCOCR_L1ICO)
{
/* Loop until the operation finish */;
}
/* Restore irq */
up_irq_restore(flags);
/* Prepare the next loop */
start += op_blocks * MSS_CACHE_BLOCK_SIZE;
}
}
}
/****************************************************************************
* Name: up_enable_icache
*
* Description:
* Enable the I-Cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void up_enable_icache(void)
{
/* Invalidate the entire icache */
maintain_icache_all(P_CCOCR_OT_INVALIDATE);
/* Enable prefetch */
modifycpm(MSS_PCR, 0, MSS_PCR_CAC_PFE);
/* Enable icache and disable lock */
modifycpm(P_ADD0_ATT0, P_ADD0_ATT0_L1IC_LOCK, P_ADD0_ATT0_L1IC);
}
/****************************************************************************
* Name: up_disable_icache
*
* Description:
* Disable the I-Cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void up_disable_icache(void)
{
/* Disable icache */
modifycpm(P_ADD0_ATT0, P_ADD0_ATT0_L1IC, 0);
/* Invalidate the entire icache */
maintain_icache_all(P_CCOCR_OT_INVALIDATE);
}
/****************************************************************************
* Name: up_invalidate_icache
*
* Description:
* Invalidate the instruction cache within the specified region.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
void up_invalidate_icache(uintptr_t start, uintptr_t end)
{
maintain_icache(P_CCOCR_OT_INVALIDATE, start, end);
}
/****************************************************************************
* Name: up_invalidate_icache_all
*
* Description:
* Invalidate the entire contents of I cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void up_invalidate_icache_all(void)
{
maintain_icache_all(P_CCOCR_OT_INVALIDATE);
}
/****************************************************************************
* Name: up_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
* by cleaning the D cache (i.e., flushing the D cache contents to memory
* and invalidating the I cache. This is typically used when code has been
* written to a memory region, and will be executed.
*
* Input Parameters:
* addr - virtual start address of region
* len - Size of the address region in bytes
*
* Returned Value:
* None
*
****************************************************************************/
void up_coherent_dcache(uintptr_t addr, size_t len)
{
/* Invalidate instruction cache is enough */
up_invalidate_icache(addr, addr + len);
}
#endif

View file

@ -0,0 +1,88 @@
/****************************************************************************
* arch/ceva/src/xc5/up_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 <nuttx/config.h>
#include <string.h>
#include <nuttx/arch.h>
#include <nuttx/irq.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 intial 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));
if (tcb->adj_stack_ptr)
{
xcp->regs = tcb->adj_stack_ptr - XCPTCONTEXT_SIZE;
memset(xcp->regs, 0, XCPTCONTEXT_SIZE);
/* Save the initial stack pointer */
xcp->regs[REG_SP] = (uint32_t)xcp->regs;
/* Save the task entry point */
xcp->regs[REG_PC] = (uint32_t)tcb->start;
/* Initialize all no zero registers */
xcp->regs[REG_MODP] = REG_MODP_DEFAULT;
/* Initialize modg for saturation setting */
xcp->regs[REG_MODG] = REG_MODG_DEFAULT;
/* All tasks start via a stub function in kernel space.
* So all tasks must start in privileged thread mode.
* If CONFIG_BUILD_PROTECTED is defined,
* then that stub function will switch to unprivileged
* mode before transferring control to the user task.
*/
xcp->regs[REG_OM] = REG_OM_DEFAULT;
}
}

201
arch/ceva/src/xc5/up_intc.c Normal file
View file

@ -0,0 +1,201 @@
/****************************************************************************
* arch/ceva/src/xc5/up_intc.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include "cpm.h"
#include "up_internal.h"
#include "vintc.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_disable_irq
*
* Description:
* This function implements disabling of the device specified by 'irq'
* at the interrupt controller level if supported by the architecture
* (up_irq_save() supports the global level, the device level is hardware
* specific).
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
void up_disable_irq(int irq)
{
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
up_vintc_disable_irq(irq);
}
else if (irq >= IRQ_TRAP0)
{
switch (irq)
{
case IRQ_TRAP0:
__asm__ __volatile__("rst #0x01, imaskt");
break;
case IRQ_TRAP1:
__asm__ __volatile__("rst #0x02, imaskt");
break;
case IRQ_TRAP2:
__asm__ __volatile__("rst #0x04, imaskt");
break;
case IRQ_TRAP3:
__asm__ __volatile__("rst #0x08, imaskt");
break;
}
}
}
/****************************************************************************
* Name: up_enable_irq
*
* Description:
* On many architectures, there are three levels of interrupt enabling: (1)
* at the global level, (2) at the level of the interrupt controller,
* and (3) at the device level. In order to receive interrupts, they
* must be enabled at all three levels.
*
* This function implements enabling of the device specified by 'irq'
* at the interrupt controller level if supported by the architecture
* (up_irq_restore() supports the global level, the device level is
* hardware specific).
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
void up_enable_irq(int irq)
{
/* Note: All INTx is enabled by REG_MODA_DEFAULT */
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
up_vintc_enable_irq(irq);
}
else if (irq >= IRQ_TRAP0)
{
switch (irq)
{
case IRQ_TRAP0:
__asm__ __volatile__("set #0x01, imaskt");
break;
case IRQ_TRAP1:
__asm__ __volatile__("set #0x02, imaskt");
break;
case IRQ_TRAP2:
__asm__ __volatile__("set #0x04, imaskt");
break;
case IRQ_TRAP3:
__asm__ __volatile__("set #0x08, imaskt");
break;
}
}
}
/****************************************************************************
* Name: up_prioritize_irq
*
* Description:
* Set the priority of an IRQ.
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
#ifdef CONFIG_ARCH_IRQPRIO
int up_prioritize_irq(int irq, int priority)
{
int ret = -EINVAL;
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
ret = up_vintc_prioritize_irq(irq, priority);
}
return ret;
}
#endif
/****************************************************************************
* Name: up_trigger_irq
*
* Description:
* Trigger an IRQ by software. May not be supported by all architectures.
*
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_IRQTRIGGER
void up_trigger_irq(int irq)
{
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
up_vintc_trigger_irq(irq);
}
}
#endif /* CONFIG_ARCH_HAVE_IRQTRIGGER */
/****************************************************************************
* Name: up_irqinitialize
****************************************************************************/
void up_irqinitialize(void)
{
/* Initialize the secondary interrupt controller */
up_vintc_initialize();
/* Attach and enable SVCall exception handler */
irq_attach(IRQ_TRAP0, up_svcall, NULL);
up_enable_irq(IRQ_TRAP0);
/* Attach and enable Hard Fault exception handler */
#if CONFIG_ARCH_HARDFAULT_IRQ >= 0
irq_attach(CONFIG_ARCH_HARDFAULT_IRQ, up_hardfault, NULL);
up_enable_irq(CONFIG_ARCH_HARDFAULT_IRQ);
#endif
/* And finally, enable interrupts */
up_irq_enable();
}

130
arch/ceva/src/xc5/up_mpu.c Normal file
View file

@ -0,0 +1,130 @@
/****************************************************************************
* arch/ceva/src/xc5/up_mpu.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 <nuttx/config.h>
#include "cpm.h"
#include "mpu.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_ARCH_MPU
/****************************************************************************
* Name: mpu_control
*
* Description:
* Configure and enable (or disable) the MPU
*
****************************************************************************/
void mpu_control(bool enable)
{
}
/****************************************************************************
* Name: mpu_user_code
*
* Description:
* Configure a region for user code
*
****************************************************************************/
void mpu_user_code(const void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_priv_code
*
* Description:
* Configure a region for privileged code
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void mpu_priv_code(const void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_user_data
*
* Description:
* Configure a region as user data
*
****************************************************************************/
void mpu_user_data(void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_priv_data
*
* Description:
* Configure a region as privileged data
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void mpu_priv_data(void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_peripheral
*
* Description:
* Configure a region as privileged peripheral address space
*
****************************************************************************/
void mpu_peripheral(void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_stronglyordered
*
* Description:
* Configure a region for privileged, strongly ordered memory
*
****************************************************************************/
void mpu_stronglyordered(void *base, size_t size)
{
}
#endif

View file

@ -0,0 +1,73 @@
/****************************************************************************
* arch/ceva/src/xc5/up_psu.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 <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* disable psu function temporily */
#define CONFIG_XC5_PSU_ENABLE
/****************************************************************************
* Private Functions
****************************************************************************/
#if CONFIG_XC5_PSU_ENABLE
static void up_cpu_pmod(uint32_t psvm)
{
/* Core auto restore to DPS here after wakeup */
__asm__ __volatile__
(
"mov #0x2, mod2\n"
"mov #0x3f80, modp\n" /* Enable the interrupt */
"mov %0, r0\n" /* Enter the low power mode */
"mov #0x250, r1\n"
"out {dw,cpm} r0, (r1)\n" /* output to cpm register psmv */
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"mov #0x0080, modp" /* restore the interrupt */
: : "r"(psvm)
);
}
#else
static void up_cpu_pmod(uint32_t psvm)
{
}
#endif /* CONFIG_XC5_PSU_ENABLE */
/****************************************************************************
* Public Functions
****************************************************************************/
void up_psu_lp(int value)
{
up_cpu_pmod(value);
}

View file

@ -0,0 +1,87 @@
/****************************************************************************
* arch/ceva/src/xc5/up_relocate.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 <nuttx/config.h>
#include "cpm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MSS_PDEA 0x004
#define MSS_PDIA 0x008
#define MSS_PDTC 0x00c
#define MSS_PDTC_MASK 0xfffff
#define MSS_PDTC_PDST (1 << 29)
#define MSS_DDEA 0x208
#define MSS_DDIA 0x20c
#define MSS_DDTC 0x210
#define MSS_DDTC_MASK 0x1fffff
#define MSS_DDTC_PDST (1 << 29)
#define MSS_DDTC_BSZ_SHIFT 25
#define MSS_DDTC_DDIR_SHIFT 30
#define BSZ_1_TRANS (0 << MSS_DDTC_BSZ_SHIFT)
#define BSZ_4_TRANS (6 << MSS_DDTC_BSZ_SHIFT)
#define BSZ_8_TRANS (10 << MSS_DDTC_BSZ_SHIFT)
#define BSZ_16_TRANS (14 << MSS_DDTC_BSZ_SHIFT)
#define DDIR_EX2IN (0 << MSS_DDTC_DDIR_SHIFT)
#define DDIR_IN2EX (1 << MSS_DDTC_DDIR_SHIFT)
#define _START_INTTBL ((void *)&_sinttbl)
/****************************************************************************
* Public Data
****************************************************************************/
extern char _sinttbl;
/****************************************************************************
* Private Functions
****************************************************************************/
static void pdma_config(unsigned long iaddr, unsigned long eaddr,
uint32_t count)
{
putcpm(MSS_PDIA, iaddr);
putcpm(MSS_PDEA, eaddr);
putcpm(MSS_PDTC, count & MSS_PDTC_MASK);
}
static void pdma_wait_idle(void)
{
while (getcpm(MSS_PDTC) & MSS_PDTC_PDST);
}
/****************************************************************************
* Public Functions
****************************************************************************/
void up_relocate(void)
{
pdma_config(0, (unsigned long)_START_INTTBL, 0x320);
pdma_wait_idle();
}

View file

@ -0,0 +1,99 @@
/****************************************************************************
* arch/ceva/src/xc5/up_signal_handler.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "svcall.h"
#if (defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)) && \
!defined(CONFIG_DISABLE_SIGNALS)
/****************************************************************************
* File info
****************************************************************************/
.file "up_signal_handler.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_dispatch() in user-mode.
*
* Input Parameters:
* r0 = sighand
* The address user-space signal handling function
* r1, r2, r3 = signo, info, and ucontext
* Standard arguments to be passed to the signal handling function.
*
* Returned Value:
* None. This function does not return in the normal sense. It returns
* via the SYS_signal_handler_return (see svcall.h)
*
****************************************************************************/
.text
.public _up_signal_handler
.func_start 3 _up_signal_handler
_up_signal_handler:
/* Save some register */
push retreg.ui /* Save LR on the stack */
push {dw} retreg
/* Call the signal handler */
mov a0, a4 /* r4=sighand */
mov a1, a0 /* r0=signo */
mov a2, a1 /* r1=info */
mov a3, a2 /* r2=ucontext */
mov a4, r4
nop
nop
nop
callar r4 /* Call the signal handler */
/* Restore the registers */
pop {dw} retreg
/* Execute the SYS_signal_handler_return SVCall (will not return) */
mov #SYS_signal_handler_return, a0
trap
.func_end 3 _up_signal_handler
#else /* Add dummy symbol to avoid cofflib crash */
.text
dummy_signal_handler:
#endif

View file

@ -0,0 +1,110 @@
/****************************************************************************
* arch/ceva/src/xc5/up_svcall_handler.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "svcall.h"
#ifdef CONFIG_LIB_SYSCALL
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "up_svcall_handler.S"
.extern _g_stublookup
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_svcall_handler
*
* Description:
* This function is the kernel-space, syscall handler trampoline function. It
* is called from up_svcall() in interrupt handler.
*
* Call the stub function corresponding to the system call. NOTE the non-
* standard parameter passing:
*
* r0 = SYS_ call number
* r1 = parm0
* r2 = parm1
* r3 = parm2
* r4 = parm3
* r5 = parm4
* r6 = parm5
*
* Returned Value:
* None. This function does not return in the normal sense. It returns
* via the SYS_syscall_return (see svcall.h)
*
****************************************************************************/
.text
.public _up_svcall_handler
.func_start 3 _up_svcall_handler
_up_svcall_handler:
/* Create a stack frame to hold LR */
push {dw} retreg
/* Call the stub function */
mov #_g_stublookup, a8
shift #0x02, a8
add a8, a8
nop
nop
mov a8, r4
ld {dw} (r4), a8
nop
nop
nop
nop
nop
mov a8, r4
callar r4
/* Destroy the stack frame */
pop {dw} retreg
/* Execute the SYS_syscall_return SVCall (will not return) */
/* Save return value in r2 */
mov a0, a2 /* will restore in up_svcall */
mov #SYS_syscall_return, a0
trap
.func_end 3 _up_svcall_handler
#else /* Add dummy symbol to avoid cofflib crash */
.text
dummy_svcall_handler:
#endif /* CONFIG_LIB_SYSCALL */

112
arch/ceva/src/xc5/vfork.S Normal file
View file

@ -0,0 +1,112 @@
/****************************************************************************
* arch/ceva/src/xc5/vfork.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include "svcall.h"
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "vfork.S"
.extern _up_vfork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the vfork()
* context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls nxtask_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart()
* 6) nxtask_vforkstart() then executes the child thread.
*
* Input Paremeters:
* None
*
* Return:
* Upon successful completion, vfork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
*
****************************************************************************/
.text
.public _vfork
.func_start 3 _vfork
_vfork:
/* Create a stack frame */
subs sp, #XCPTCONTEXT_SIZE, sp
/* Save the volatile registers by svcall(SYS_save_context) */
mov #SYS_save_context, a0
mov sp, a1
trap
/* Then, call up_vfork(), passing it a pointer to the stack structure */
mov sp, a0
nop
push {dw} retreg
callr {t} _up_vfork
pop {dw} retreg
nop
/* Release the stack data and return the value returned by up_vfork */
adds sp, #XCPTCONTEXT_SIZE, sp
ret
.func_end 3 _vfork

11
arch/ceva/src/xm6/Kconfig Normal file
View file

@ -0,0 +1,11 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
comment "XM6 Configuration Options"
config ARCH_XM6_BUG001
bool "Enable bug 001 workaround"
---help---
Read CEVA-XM6 Bug List for more information

View file

@ -0,0 +1,73 @@
############################################################################
# arch/ceva/src/xm6/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.
#
############################################################################
RTL_VERSION := $(CONFIG_ARCH_RTL_MAJOR).$(CONFIG_ARCH_RTL_MINOR).$(CONFIG_ARCH_RTL_REVISION)
ITCM_KB := $(shell expr $(CONFIG_ARCH_ITCM_SIZE) / 1024)
DTCM_KB := $(shell expr $(CONFIG_ARCH_DTCM_SIZE) / 1024)
#
# Supported toolchains
#
# Each toolchain definition should set:
#
# CROSSDEV The GNU toolchain triple (command prefix)
# ARCROSSDEV If required, an alternative prefix used when
# invoking ar and nm.
# ARCHCPUFLAGS CPU-specific flags selecting the instruction set
# FPU options, etc.
# MAXOPTIMIZATION The maximum optimization level that results in
# reliable code generation.
#
ARCROSSDEV ?= $(CROSSDEV)
ifneq ($(CROSSDEV),)
export LD_LIBRARY_PATH := $(CROSSDEV):$(LD_LIBRARY_PATH)
export PATH := $(CROSSDEV):$(PATH)
export CEVAXMTOOLS := $(CROSSDEV)
endif
ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y)
MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL)
else ifeq ($(CONFIG_DEBUG_FULLOPT),y)
MAXOPTIMIZATION := -O3 -Os3
endif
ARCHCPUFLAGS = -mrtl-version-$(RTL_VERSION) -Wa,-rtl$(RTL_VERSION)
ARCHCPUFLAGS += -Wa,-p
LDFLAGS = -alignAllSections,c:0x20,d:0x20
LDFLAGS += -internalCode$(ITCM_KB) -internalData$(DTCM_KB)
LIBGCC = $(CROSSDEV)libs/cevaxm6/cevaxm6lib.lib
LIBGCC += $(CROSSDEV)libs/cevaxm6/complexlib.lib
LIBGCC += $(CROSSDEV)libs/cevaxm6/libcc.lib
ifneq ($(CONFIG_ARCH_NR_FPUS),)
ARCHCPUFLAGS += -CG:SPU_FP_num=$(CONFIG_ARCH_NR_FPUS) -Wa,-fp=$(CONFIG_ARCH_NR_FPUS)
endif
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
WINTOOL = y
endif
CC = $(CROSSDEV)/cevaxm6cc -mquiet -Wa,-quiet
CXX = $(CROSSDEV)/cevaxm6cc -mquiet -Wa,-quiet -x c++
CPP = $(CROSSDEV)/cevaxm6cc -mquiet -Wa,-quiet -E -P -x c

64
arch/ceva/src/xm6/cpm.h Normal file
View file

@ -0,0 +1,64 @@
/****************************************************************************
* arch/ceva/src/xm6/cpm.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_CEVA_SRC_XM6_CPM_H
#define __ARCH_CEVA_SRC_XM6_CPM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#include <vec-c.h>
/****************************************************************************
* Inline functions
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
static inline uint32_t getcpm(uintptr_t addr)
{
return in(cpm, (const volatile uint32_t *)addr);
}
static inline void putcpm(uintptr_t addr, uint32_t value)
{
out(cpm, value, (volatile uint32_t *)addr);
}
static inline void modifycpm(uintptr_t addr, uint32_t clearbits,
uint32_t setbits)
{
putcpm(addr, (getcpm(addr) & ~clearbits) | setbits);
}
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ARCH_CEVA_SRC_XM6_CPM_H */

View file

@ -0,0 +1,87 @@
/****************************************************************************
* arch/ceva/src/xm6/syscall.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
.IF CONFIG_ARCH_XM6_BUG001
.EQU prx pr14
.ELSE
.EQU prx pr15
.ENDIF
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "syscall.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sys_callx
*
* Description:
* This function generate the trap exception with the specified number of
* parameters.
*
* r0 = SYS_ call number
* r1 = parm0
* r2 = parm1
* r3 = parm2
* r4 = parm3
* r5 = parm4
* r6 = parm5
*
****************************************************************************/
.text
.public _sys_call0
.public _sys_call1
.public _sys_call2
.public _sys_call3
.public _sys_call4
.public _sys_call5
.public _sys_call6
.func_start 3 _sys_call0
_sys_call0:
_sys_call1:
_sys_call2:
_sys_call3:
_sys_call4:
_sys_call5:
_sys_call6:
trap {t0}
nop
ret ?prx.b
.func_end 3 _sys_call0

View file

@ -0,0 +1,111 @@
/****************************************************************************
* arch/ceva/src/xm6/up_hardfault.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 <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include "cpm.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define REG_P_ECADD 0x051c
#define REG_P_MAPAR 0x0520
#define REG_P_MAPSR 0x0524
#define REG_P_MECCCOR 0x0530
#define REG_D_ECCCOR 0x0784
#define REG_D_ECCERR 0x0788
#define REG_D_MECCCOR 0x078c
#define REG_D_MECCERR 0x0790
#define REG_D_SECCCOR 0x0794
#define REG_D_SECCERR 0x0798
#define REG_UOP_STS 0x0c58
#define REG_UOP_PAR 0x0c5c
#define REG_MAPAR 0x0c80
#define REG_MAPSR 0x0c84
#define REG_DBG_GEN 0x0d14
#define REG_DBG_GEN_2 0x0d24
#define REG_DBG_DUNMPD 0x0d30
#define REG_HIST_OVERFLOW 0x0d4c
#define REG_DBG_DESC_ID 0x0d84
#define REG_DBG_QMAN_ID 0x0d88
#ifdef CONFIG_DEBUG_HARDFAULT
# define hfalert(format, ...) _alert(format, ##__VA_ARGS__)
#else
# define hfalert(x...)
#endif
#define hfdumpreg1(reg) \
hfalert("%s: %08x\n", \
#reg, getcpm(REG_##reg))
#define hfdumpreg2(reg1, reg2) \
hfalert("%s: %08x %s: %08x\n", \
#reg1, getcpm(REG_##reg1), \
#reg2, getcpm(REG_##reg2))
#define hfdumpreg3(reg1, reg2, reg3) \
hfalert("%s: %08x %s: %08x %s: %08x\n", \
#reg1, getcpm(REG_##reg1), \
#reg2, getcpm(REG_##reg2), \
#reg3, getcpm(REG_##reg3))
#define hfdumpreg4(reg1, reg2, reg3, reg4) \
hfalert("%s: %08x %s: %08x %s: %08x %s: %08x\n",\
#reg1, getcpm(REG_##reg1), \
#reg2, getcpm(REG_##reg2), \
#reg3, getcpm(REG_##reg3), \
#reg4, getcpm(REG_##reg4))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_hardfault
*
* Description:
* This is Hard Fault exception handler.
*
****************************************************************************/
int up_hardfault(int irq, FAR void *context, FAR void *arg)
{
/* Dump some hard fault info */
hfalert("Hard Fault:\n");
hfdumpreg4(P_ECADD P_MAPAR, P_MAPSR, P_MECCCOR);
hfdumpreg4(D_ECCCOR, D_ECCERR, D_MECCCOR, D_MECCERR);
hfdumpreg4(D_SECCCOR, D_SECCERR, UOP_STS, UOP_PAR);
hfdumpreg4(MAPAR, MAPSR, DBG_GEN, DBG_GEN_2);
hfdumpreg4(DBG_DUNMPD, HIST_OVERFLOW, DBG_DESC_ID, DBG_QMAN_ID);
PANIC();
return OK;
}

229
arch/ceva/src/xm6/up_head.S Normal file
View file

@ -0,0 +1,229 @@
/****************************************************************************
* arch/ceva/src/xm6/up_head.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK == 0
# undef CONFIG_ARCH_INTERRUPTSTACK
# define CONFIG_ARCH_INTERRUPTSTACK CONFIG_IDLETHREAD_STACKSIZE
#endif
.IF CONFIG_ARCH_XM6_BUG001
.EQU prx pr14
.ELSE
.EQU prx pr15
.ENDIF
.MACRO IRQ_HANDLER irq retx
push {auxreg10}
push {auxreg2}
mov #irq, r0.ui
callr #exception_common, ?prx.b
pop {auxreg10}
nop #0x04
retx
.ENDM
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "up_head.S"
.extern _g_idle_topstack
.extern _g_idle_basestack
.extern _up_doirq
.extern _up_start
/****************************************************************************
* Interrupt Functions
****************************************************************************/
.CSECT inttbl
.IF CONFIG_ARCH_XM6_BUG001
cmp {eq} r0.ui, r0.ui, prx.b2, pr15.b2
.ENDIF
br #reset_handler, #0x00, #0x00, ?prx.b
.ORG 0x20
IRQ_HANDLER IRQ_TRAPE, retb
.ORG 0x40
IRQ_HANDLER IRQ_TRAP, reti
.ORG 0x60
IRQ_HANDLER IRQ_NMI, retn
.ORG 0x80
IRQ_HANDLER IRQ_INT0, reti
.ORG 0xc0
IRQ_HANDLER IRQ_INT1, reti
.ORG 0x100
IRQ_HANDLER IRQ_INT2, reti
.ORG 0x140
IRQ_HANDLER IRQ_INT3, reti
.ORG 0x180
IRQ_HANDLER IRQ_INT4, reti
.ORG 0x1c0
.GLOBAL _up_vintc_handler
_up_vintc_handler:
IRQ_HANDLER IRQ_VINT, reti
.ORG 0x200
IRQ_HANDLER IRQ_TRAP0, reti
.ORG 0x240
IRQ_HANDLER IRQ_TRAP1, reti
.ORG 0x280
IRQ_HANDLER IRQ_TRAP2, reti
.ORG 0x2c0
IRQ_HANDLER IRQ_TRAP3, reti
reset_handler:
/* Tricky for compiler bug: when codes are placed onto ddr memory, label
* address will be place at the back of its first code line, so when branch
* to this label, its first code line will be skipped.
*/
nop
nop
nop
nop
/* Initialize the C language environment */
ld (#_g_idle_topstack).ui, r0.ui
mov r0.ui, sp.ui
br #_up_start, #0x00, #0x00, ?prx.b
/****************************************************************************
* Private Functions
****************************************************************************/
/* Common exception handling logic, need sync with:
* arch/ceva/include/xm6/reg.h
*/
.func_start 3 exception_common
exception_common:
/* Tricky for compiler bug: when codes are placed onto ddr memory, label address
* will be placed at the back of its first code line, so when branch to
* to this label, its first code line will be skipped.
*/
nop
nop
nop
nop
/* Note: r0 contain exception number
* Complete the context save
*/
push {auxreg3}
push {auxreg4}
push {auxreg5}
push {auxreg6}
push {auxreg7}
push {auxreg8}
push {auxreg9}
push moda.ui
push modc.ui
push modd.ui
push mode.ui
push modg.ui
push modi.ui
modr (sp.ui).ui +#-4
mov sp.ui, r1.ui
st r1.ui, (r1.ui).ui
/* Prepare the C language environment */
lbf {sv} #0x00
/* There are two arguments to up_doirq:
*
* r0 = The IRQ number
* r1 = The top of the stack points to the saved state
*/
/* Switch to the dedicated stack */
mov #_g_intstackbase, r2.ui
mov r2.ui, sp.ui
push retreg.ui
callr #_up_doirq, ?prx.b
pop retreg.ui
/* On return from up_doirq, r0 will hold a pointer to register context
* array to use for the interrupt return.
*/
modr (r0.ui).ui +#4
/* Restore the stack pointer */
mov r0.ui, sp.ui
/* Unwind the same stack frame that we created at entry */
pop modi.ui
pop modg.ui
pop mode.ui
pop modd.ui
pop modc.ui
pop moda.ui
pop {auxreg9}
pop {auxreg8}
pop {auxreg7}
pop {auxreg6}
pop {auxreg5}
pop {auxreg4}
pop {auxreg3}
pop {auxreg2}
ret ?prx.b
.func_end 3 exception_common
.bss
.public _g_intstackalloc
.public _g_intstackbase
_g_intstackalloc:
DD CONFIG_ARCH_INTERRUPTSTACK/4 dup ?
_g_intstackbase:

View file

@ -0,0 +1,298 @@
/****************************************************************************
* arch/ceva/src/xm6/up_icache.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 <nuttx/config.h>
#include <nuttx/cache.h>
#include <nuttx/irq.h>
#include "cpm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MSS_PCR 0x0404
#define P_ADD0_ATT0 0x0418
#define P_CCOSAR 0x0514
#define P_CCOCR 0x0518
#define MSS_HDCFG 0x061c
#define MSS_PCR_CAC_PFE 0x00000004
#define P_ADD0_ATT0_L1IC 0x00000001
#define P_ADD0_ATT0_L1IC_LOCK 0x00000002
#define P_CCOCR_FLUSH 0x00000001
#define P_CCOCR_L1ICO 0x00000002
#define P_CCOCR_OT_PREFETCH 0x00000004
#define P_CCOCR_OT_LOCK 0x00000008
#define P_CCOCR_OT_UNLOCK 0x0000000c
#define P_CCOCR_OT_INVALIDATE 0x00000010
#define P_CCOCR_OT_MASK 0x0000003c
#define P_CCOCR_OS_ENTIRE 0x00000080
#define P_CCOCR_QFILL_SHIFT 12
#define P_CCOCR_QFILL_MASK 0x00007000
#define P_CCOCR_OF 0x00008000
#define P_CCOCR_NOBPL_SHIFT 16
#define P_CCOCR_NOBPL_MASK 0xffff0000
#define MSS_HDCFG_PCAC_SZE_0KB 0x00000000
#define MSS_HDCFG_PCAC_SZE_32KB 0x00001000
#define MSS_HDCFG_PCAC_SZE_64KB 0x00002000
#define MSS_HDCFG_PCAC_SZE_128KB 0x00003000
#define MSS_HDCFG_PCAC_SZE_MASK 0x00007000
#define MSS_CACHE_BLOCK_SIZE 64
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_CEVA_ICACHE
static void maintain_icache_all(uint32_t op)
{
irqstate_t flags;
/* Disable irq */
flags = up_irq_save();
/* Start the operation on the entire cache */
putcpm(P_CCOCR, P_CCOCR_L1ICO | op | P_CCOCR_OS_ENTIRE);
while (getcpm(P_CCOCR) & P_CCOCR_L1ICO)
{
/* Loop until the operation finish */;
}
/* Restore irq */
up_irq_restore(flags);
}
static void maintain_icache(uint32_t op, uintptr_t start, uintptr_t end)
{
static size_t op_maxblocks;
/* Initialize op_maxblocks if not yet */
if (op_maxblocks == 0)
{
switch (getcpm(MSS_HDCFG) & MSS_HDCFG_PCAC_SZE_MASK)
{
case MSS_HDCFG_PCAC_SZE_32KB:
op_maxblocks = 512;
break;
case MSS_HDCFG_PCAC_SZE_64KB:
op_maxblocks = 1024;
break;
case MSS_HDCFG_PCAC_SZE_128KB:
op_maxblocks = 2048;
break;
default:
op_maxblocks = 1;
break;
}
}
/* Align the address to the cache block boundary */
start &= ~(MSS_CACHE_BLOCK_SIZE - 1);
end += (MSS_CACHE_BLOCK_SIZE - 1);
end &= ~(MSS_CACHE_BLOCK_SIZE - 1);
/* Skip dtcm since it never put into dcache */
if (end > CONFIG_ARCH_ITCM_SIZE)
{
if (start < CONFIG_ARCH_ITCM_SIZE)
{
start = CONFIG_ARCH_ITCM_SIZE;
}
while (start < end)
{
irqstate_t flags;
size_t op_blocks;
/* Get the max blocks we can do in one iteration */
op_blocks = (end - start) / MSS_CACHE_BLOCK_SIZE;
if (op_blocks > op_maxblocks)
{
op_blocks = op_maxblocks;
}
/* Disable irq */
flags = up_irq_save();
/* Set the cache address */
putcpm(P_CCOSAR, start);
/* Start the cache operation */
putcpm(P_CCOCR, /* Address based operation */
P_CCOCR_L1ICO | op | (op_blocks << P_CCOCR_NOBPL_SHIFT));
while (getcpm(P_CCOCR) & P_CCOCR_L1ICO)
{
/* Loop until the operation finish */;
}
/* Restore irq */
up_irq_restore(flags);
/* Prepare the next loop */
start += op_blocks * MSS_CACHE_BLOCK_SIZE;
}
}
}
/****************************************************************************
* Name: up_enable_icache
*
* Description:
* Enable the I-Cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void up_enable_icache(void)
{
/* Invalidate the entire icache */
maintain_icache_all(P_CCOCR_OT_INVALIDATE);
/* Enable prefetch */
modifycpm(MSS_PCR, 0, MSS_PCR_CAC_PFE);
/* Enable icache and disable lock */
modifycpm(P_ADD0_ATT0, P_ADD0_ATT0_L1IC_LOCK, P_ADD0_ATT0_L1IC);
}
/****************************************************************************
* Name: up_disable_icache
*
* Description:
* Disable the I-Cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void up_disable_icache(void)
{
/* Disable icache */
modifycpm(P_ADD0_ATT0, P_ADD0_ATT0_L1IC, 0);
/* Invalidate the entire icache */
maintain_icache_all(P_CCOCR_OT_INVALIDATE);
}
/****************************************************************************
* Name: up_invalidate_icache
*
* Description:
* Invalidate the instruction cache within the specified region.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
void up_invalidate_icache(uintptr_t start, uintptr_t end)
{
maintain_icache(P_CCOCR_OT_INVALIDATE, start, end);
}
/****************************************************************************
* Name: up_invalidate_icache_all
*
* Description:
* Invalidate the entire contents of I cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void up_invalidate_icache_all(void)
{
maintain_icache_all(P_CCOCR_OT_INVALIDATE);
}
/****************************************************************************
* Name: up_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
* by cleaning the D cache (i.e., flushing the D cache contents to memory
* and invalidating the I cache. This is typically used when code has been
* written to a memory region, and will be executed.
*
* Input Parameters:
* addr - virtual start address of region
* len - Size of the address region in bytes
*
* Returned Value:
* None
*
****************************************************************************/
void up_coherent_dcache(uintptr_t addr, size_t len)
{
/* Invalidate instruction cache is enough */
up_invalidate_icache(addr, addr + len);
}
#endif

View file

@ -0,0 +1,96 @@
/****************************************************************************
* arch/ceva/src/xm6/up_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 <nuttx/config.h>
#include <string.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define REG_MODE_DEFAULT 0x40004000 /* PR14H and PR14L */
/****************************************************************************
* 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 intial 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));
if (tcb->adj_stack_ptr)
{
xcp->regs = tcb->adj_stack_ptr - XCPTCONTEXT_SIZE;
memset(xcp->regs, 0, XCPTCONTEXT_SIZE);
/* Save the initial stack pointer */
xcp->regs[REG_SP] = (uint32_t)xcp->regs;
/* Save the task entry point */
xcp->regs[REG_PC] = (uint32_t)tcb->start;
/* Initialize all no zero registers */
xcp->regs[REG_MODA] = REG_MODA_DEFAULT;
/* All tasks start via a stub function in kernel space.
* So all tasks must start in privileged thread mode.
* If CONFIG_BUILD_PROTECTED is defined,
* then that stub function will switch to unprivileged
* mode before transferring control to the user task.
*/
xcp->regs[REG_OM] = REG_OM_DEFAULT;
#ifdef CONFIG_ARCH_XM6_BUG001
/* See BUG 001 in CEVA-XM6 Bug List */
xcp->regs[REG_MODE] = REG_MODE_DEFAULT;
#endif
}
}

217
arch/ceva/src/xm6/up_intc.c Normal file
View file

@ -0,0 +1,217 @@
/****************************************************************************
* arch/ceva/src/xm6/up_intc.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 <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include "cpm.h"
#include "up_internal.h"
#include "vintc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define DBG_GEN_MASK 0x0d28
#define DBG_GEN_MASK_OVRFLW_EXCPTN 0x10000000
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_disable_irq
*
* Description:
* This function implements disabling of the device specified by 'irq'
* at the interrupt controller level if supported by the architecture
* (up_irq_save() supports the global level, the device level is hardware
* specific).
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
void up_disable_irq(int irq)
{
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
up_vintc_disable_irq(irq);
}
else if (irq >= IRQ_TRAP0)
{
switch (irq)
{
case IRQ_TRAP0:
__asm__ __volatile__("rstp {imaskt} #0x01");
break;
case IRQ_TRAP1:
__asm__ __volatile__("rstp {imaskt} #0x02");
break;
case IRQ_TRAP2:
__asm__ __volatile__("rstp {imaskt} #0x04");
break;
case IRQ_TRAP3:
__asm__ __volatile__("rstp {imaskt} #0x08");
break;
}
}
}
/****************************************************************************
* Name: up_enable_irq
*
* Description:
* On many architectures, there are three levels of interrupt enabling: (1)
* at the global level, (2) at the level of the interrupt controller,
* and (3) at the device level. In order to receive interrupts, they
* must be enabled at all three levels.
*
* This function implements enabling of the device specified by 'irq'
* at the interrupt controller level if supported by the architecture
* (up_irq_restore() supports the global level, the device level is
* hardware specific).
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
void up_enable_irq(int irq)
{
/* Note: All INTx is enabled by REG_MODA_DEFAULT */
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
up_vintc_enable_irq(irq);
}
else if (irq >= IRQ_TRAP0)
{
switch (irq)
{
case IRQ_TRAP0:
__asm__ __volatile__("setp {imaskt} #0x01");
break;
case IRQ_TRAP1:
__asm__ __volatile__("setp {imaskt} #0x02");
break;
case IRQ_TRAP2:
__asm__ __volatile__("setp {imaskt} #0x04");
break;
case IRQ_TRAP3:
__asm__ __volatile__("setp {imaskt} #0x08");
break;
}
}
}
/****************************************************************************
* Name: up_prioritize_irq
*
* Description:
* Set the priority of an IRQ.
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
#ifdef CONFIG_ARCH_IRQPRIO
int up_prioritize_irq(int irq, int priority)
{
int ret = -EINVAL;
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
ret = up_vintc_prioritize_irq(irq, priority);
}
return ret;
}
#endif
/****************************************************************************
* Name: up_trigger_irq
*
* Description:
* Trigger an IRQ by software. May not be supported by all architectures.
*
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_IRQTRIGGER
void up_trigger_irq(int irq)
{
if (irq >= IRQ_VINT_FIRST)
{
/* Forward to the secondary interrupt controller */
up_vintc_trigger_irq(irq);
}
}
#endif /* CONFIG_ARCH_HAVE_IRQTRIGGER */
/****************************************************************************
* Name: up_irqinitialize
****************************************************************************/
void up_irqinitialize(void)
{
/* Set the INTBASE in case inttbl not equal zero. */
__asm__ __volatile__("movp #inttbl.0, modh.ui");
/* Disable the integer overflow exception. */
modifycpm(DBG_GEN_MASK, 0, DBG_GEN_MASK_OVRFLW_EXCPTN);
/* Initialize the secondary interrupt controller */
up_vintc_initialize();
/* Attach and enable SVCall exception handler */
irq_attach(IRQ_TRAP0, up_svcall, NULL);
up_enable_irq(IRQ_TRAP0);
/* Attach and enable Hard Fault exception handler */
#if CONFIG_ARCH_HARDFAULT_IRQ >= 0
irq_attach(CONFIG_ARCH_HARDFAULT_IRQ, up_hardfault, NULL);
up_enable_irq(CONFIG_ARCH_HARDFAULT_IRQ);
#endif
/* And finally, enable interrupts */
up_irq_enable();
}

130
arch/ceva/src/xm6/up_mpu.c Normal file
View file

@ -0,0 +1,130 @@
/****************************************************************************
* arch/ceva/src/xm6/up_mpu.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 <nuttx/config.h>
#include "cpm.h"
#include "mpu.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_ARCH_MPU
/****************************************************************************
* Name: mpu_control
*
* Description:
* Configure and enable (or disable) the MPU
*
****************************************************************************/
void mpu_control(bool enable)
{
}
/****************************************************************************
* Name: mpu_user_code
*
* Description:
* Configure a region for user code
*
****************************************************************************/
void mpu_user_code(const void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_priv_code
*
* Description:
* Configure a region for privileged code
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void mpu_priv_code(const void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_user_data
*
* Description:
* Configure a region as user data
*
****************************************************************************/
void mpu_user_data(void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_priv_data
*
* Description:
* Configure a region as privileged data
*
* Caution:
* The writable global variables aren't initialized yet.
*
****************************************************************************/
void mpu_priv_data(void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_peripheral
*
* Description:
* Configure a region as privileged peripheral address space
*
****************************************************************************/
void mpu_peripheral(void *base, size_t size)
{
}
/****************************************************************************
* Name: mpu_stronglyordered
*
* Description:
* Configure a region for privileged, strongly ordered memory
*
****************************************************************************/
void mpu_stronglyordered(void *base, size_t size)
{
}
#endif

View file

@ -0,0 +1,69 @@
/****************************************************************************
* arch/ceva/src/xm6/up_psu.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 <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* disable psu function temporily */
#define CEVAXM6_PSU_ENABLE 0
#if CEVAXM6_PSU_ENABLE
/* Core auto restore to DPS here after wakeup */
#define up_cpu_pmod(pmod_inst) \
__asm__ __volatile__ \
( \
"nop #0x04\nnop\n" \
"movp %0.ui, moda.ui\n" /* Enable the interrupt */ \
pmod_inst /* Enter the low power mode */ \
"nop #0x04\nnop #0x04\nnop\n" /* Clear the pipe of instruction */ \
"movp %1.ui, moda.ui" /* restore the interrupt */ \
: : "r"(REG_MODA_ENABLE), "r"(REG_MODA_DISABLE) \
)
#else
#define up_cpu_pmod(pmod_inst)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
void up_cpu_doze(void)
{
up_cpu_pmod("psu {lightsleep}\n");
}
void up_cpu_idle(void)
{
up_cpu_pmod("psu {standby}\n");
}

View file

@ -0,0 +1,96 @@
/****************************************************************************
* arch/ceva/src/xm6/up_signal_handler.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "svcall.h"
#if (defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)) && \
!defined(CONFIG_DISABLE_SIGNALS)
/****************************************************************************
* File info
****************************************************************************/
.file "up_signal_handler.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_dispatch() in user-mode.
*
* Inputs:
* r0 = sighand
* The address user-space signal handling function
* r1, r2, r3 = signo, info, and ucontext
* Standard arguments to be passed to the signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via the SYS_signal_handler_return (see svcall.h)
*
****************************************************************************/
.text
.public _up_signal_handler
.func_start 3 _up_signal_handler
_up_signal_handler:
/* Save some register */
push retreg.ui /* Save LR on the stack */
/* Call the signal handler */
mov r0.ui, r4.ui /* r4=sighand */
mov r1.ui, r0.ui /* r0=signo */
mov r2.ui, r1.ui /* r1=info */
mov r3.ui, r2.ui /* r2=ucontext */
nop #0x03
callar r4.ui /* Call the signal handler */
/* Restore the registers */
pop retreg.ui
/* Execute the SYS_signal_handler_return SVCall (will not return) */
mov #SYS_signal_handler_return, r0.ui
trap {t0}
.func_end 3 _up_signal_handler
#else /* Add dummy symbol to avoid cofflib crash */
.text
dummy_signal_handler:
#endif

View file

@ -0,0 +1,103 @@
/****************************************************************************
* arch/ceva/src/xm6/up_svcall_handler.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "svcall.h"
#ifdef CONFIG_LIB_SYSCALL
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "up_svcall_handler.S"
.extern _g_stublookup
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_svcall_handler
*
* Description:
* This function is the kernel-space, syscall handler trampoline function. It
* is called from up_svcall() in interrupt handler.
*
* Call the stub function corresponding to the system call. NOTE the non-
* standard parameter passing:
*
* r0 = SYS_ call number
* r1 = parm0
* r2 = parm1
* r3 = parm2
* r4 = parm3
* r5 = parm4
* r6 = parm5
*
* Return:
* None. This function does not return in the normal sense. It returns
* via the SYS_syscall_return (see svcall.h)
*
****************************************************************************/
.text
.public _up_svcall_handler
.func_start 3 _up_svcall_handler
_up_svcall_handler:
/* Create a stack frame to hold LR */
push retreg.ui
/* Call the stub function */
mov #_g_stublookup, r7.ui
shiftladd r0.ui, #0x02, r7.ui, r7.ui
nop #0x02
ld (r7.ui).ui, r7.ui
nop #0x04
nop
callar r7.ui
/* Destroy the stack frame */
pop retreg.ui
/* Execute the SYS_syscall_return SVCall (will not return) */
/* Save return value in r2 */
mov r0.ui, r2.ui /* will restore in up_svcall */
mov #SYS_syscall_return, r0.ui
trap {t0}
.func_end 3 _up_svcall_handler
#else /* Add dummy symbol to avoid cofflib crash */
.text
dummy_svcall_handler:
#endif /* CONFIG_LIB_SYSCALL */

121
arch/ceva/src/xm6/vfork.S Normal file
View file

@ -0,0 +1,121 @@
/****************************************************************************
* arch/ceva/src/xm6/vfork.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include "svcall.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
.IF CONFIG_ARCH_XM6_BUG001
.EQU prx pr14
.ELSE
.EQU prx pr15
.ENDIF
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "vfork.S"
.extern _up_vfork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the vfork()
* context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls nxtask_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart()
* 6) nxtask_vforkstart() then executes the child thread.
*
* Input Paremeters:
* None
*
* Return:
* Upon successful completion, vfork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
*
****************************************************************************/
.text
.public _vfork
.func_start 3 _vfork
_vfork:
/* Create a stack frame */
modr (sp.ui).ui +#-XCPTCONTEXT_SIZE /* Allocate the structure on the stack */
/* Save the volatile registers by svcall(SYS_save_context) */
mov #SYS_save_context, r0.ui
mov sp.ui, r1.ui
trap {t0}
/* Then, call up_vfork(), passing it a pointer to the stack structure */
mov sp.ui, r0.ui
nop
push retreg.ui
callr #_up_vfork, ?prx.b
pop retreg.ui
nop
/* Release the stack data and return the value returned by up_vfork */
modr (sp.ui).ui +#XCPTCONTEXT_SIZE
ret ?prx.b
.func_end 3 _vfork