mirror of
https://github.com/apache/nuttx.git
synced 2026-05-18 00:34:10 +08:00
Porting arch/armv8-m support
1. Add dsp extension; float point based on hardware and software. 2. Delete folder "iar" 3. Add tool chain for cortex-M23 and cortex-M35p Signed-off-by: qiaowei <qiaowei@xiaomi.com> Change-Id: I5bfc78abb025adb0ad4fae37e2b444915f477fe7
This commit is contained in:
+51
-8
@@ -517,10 +517,6 @@ config ARCH_CORTEXM0
|
||||
select ARCH_HAVE_RESET
|
||||
select ARCH_HAVE_HARDFAULT_DEBUG
|
||||
|
||||
config ARCH_CORTEXM23
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_ARMV7M
|
||||
bool
|
||||
default n
|
||||
@@ -540,10 +536,6 @@ config ARCH_CORTEXM3
|
||||
select ARCH_HAVE_HARDFAULT_DEBUG
|
||||
select ARCH_HAVE_MEMFAULT_DEBUG
|
||||
|
||||
config ARCH_CORTEXM33
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_CORTEXM4
|
||||
bool
|
||||
default n
|
||||
@@ -648,6 +640,53 @@ config ARCH_CORTEXR7
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_HAVE_TESTSET
|
||||
|
||||
config ARCH_ARMV8M
|
||||
bool
|
||||
default n
|
||||
select ARCH_HAVE_SETJMP
|
||||
|
||||
config ARCH_CORTEXM23
|
||||
bool
|
||||
default n
|
||||
select ARCH_ARMV8M
|
||||
select ARCH_HAVE_IRQPRIO
|
||||
select ARCH_HAVE_IRQTRIGGER
|
||||
select ARCH_HAVE_RAMVECTORS
|
||||
select ARCH_HAVE_LAZYFPU
|
||||
select ARCH_HAVE_HIPRI_INTERRUPT
|
||||
select ARCH_HAVE_RESET
|
||||
select ARCH_HAVE_TESTSET
|
||||
select ARCH_HAVE_HARDFAULT_DEBUG
|
||||
select ARCH_HAVE_MEMFAULT_DEBUG
|
||||
|
||||
config ARCH_CORTEXM33
|
||||
bool
|
||||
default n
|
||||
select ARCH_ARMV8M
|
||||
select ARCH_HAVE_IRQPRIO
|
||||
select ARCH_HAVE_IRQTRIGGER
|
||||
select ARCH_HAVE_RAMVECTORS
|
||||
select ARCH_HAVE_LAZYFPU
|
||||
select ARCH_HAVE_HIPRI_INTERRUPT
|
||||
select ARCH_HAVE_RESET
|
||||
select ARCH_HAVE_TESTSET
|
||||
select ARCH_HAVE_HARDFAULT_DEBUG
|
||||
select ARCH_HAVE_MEMFAULT_DEBUG
|
||||
|
||||
config ARCH_CORTEXM35P
|
||||
bool
|
||||
default n
|
||||
select ARCH_ARMV8M
|
||||
select ARCH_HAVE_IRQPRIO
|
||||
select ARCH_HAVE_IRQTRIGGER
|
||||
select ARCH_HAVE_RAMVECTORS
|
||||
select ARCH_HAVE_LAZYFPU
|
||||
select ARCH_HAVE_HIPRI_INTERRUPT
|
||||
select ARCH_HAVE_RESET
|
||||
select ARCH_HAVE_TESTSET
|
||||
select ARCH_HAVE_HARDFAULT_DEBUG
|
||||
select ARCH_HAVE_MEMFAULT_DEBUG
|
||||
|
||||
config ARCH_FAMILY
|
||||
string
|
||||
default "arm" if ARCH_ARM7TDMI || ARCH_ARM926EJS || ARCH_ARM920T
|
||||
@@ -655,6 +694,7 @@ config ARCH_FAMILY
|
||||
default "armv7-a" if ARCH_ARMV7A
|
||||
default "armv7-m" if ARCH_ARMV7M
|
||||
default "armv7-r" if ARCH_ARMV7R
|
||||
default "armv8-m" if ARCH_ARMV8M
|
||||
|
||||
config ARCH_CHIP
|
||||
string
|
||||
@@ -845,6 +885,9 @@ endif
|
||||
if ARCH_ARMV7R
|
||||
source arch/arm/src/armv7-r/Kconfig
|
||||
endif
|
||||
if ARCH_ARMV8M
|
||||
source arch/arm/src/armv8-m/Kconfig
|
||||
endif
|
||||
if ARCH_ARM7TDMI || ARCH_ARM920T || ARCH_ARM926EJS || ARCH_ARM1136J || ARCH_ARM1156T2 || ARCH_ARM1176JZ
|
||||
source arch/arm/src/arm/Kconfig
|
||||
endif
|
||||
|
||||
Executable
+401
@@ -0,0 +1,401 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/include/armv8-m/irq.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* This file should never be included directly but, rather, only indirectly
|
||||
* through nuttx/irq.h
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <nuttx/compiler.h>
|
||||
# include <arch/armv8-m/nvicpri.h>
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Included implementation-dependent register save structure layouts */
|
||||
|
||||
#ifndef CONFIG_ARMV8M_LAZYFPU
|
||||
# include <arch/armv8-m/irq_cmnvector.h>
|
||||
#else
|
||||
# include <arch/armv8-m/irq_lazyfpu.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* If this is a 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_A1 REG_R0
|
||||
#define REG_A2 REG_R1
|
||||
#define REG_A3 REG_R2
|
||||
#define REG_A4 REG_R3
|
||||
#define REG_V1 REG_R4
|
||||
#define REG_V2 REG_R5
|
||||
#define REG_V3 REG_R6
|
||||
#define REG_V4 REG_R7
|
||||
#define REG_V5 REG_R8
|
||||
#define REG_V6 REG_R9
|
||||
#define REG_V7 REG_R10
|
||||
#define REG_SB REG_R9
|
||||
#define REG_SL REG_R10
|
||||
#define REG_FP REG_R11
|
||||
#define REG_IP REG_R12
|
||||
#define REG_SP REG_R13
|
||||
#define REG_LR REG_R14
|
||||
#define REG_PC REG_R15
|
||||
|
||||
/* The PIC register is usually R10. It can be R9 is stack checking is enabled
|
||||
* or if the user changes it with -mpic-register on the GCC command line.
|
||||
*/
|
||||
|
||||
#define REG_PIC REG_R10
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This structure represents the return state from a system call */
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
struct xcpt_syscall_s
|
||||
{
|
||||
uint32_t excreturn; /* The EXC_RETURN value */
|
||||
uint32_t sysreturn; /* The return PC */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The following structure is included in the TCB and defines the complete
|
||||
* state of the thread.
|
||||
*/
|
||||
|
||||
struct xcptcontext
|
||||
{
|
||||
/* 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 LR, PRIMASK, and xPSR used during
|
||||
* signal processing.
|
||||
*
|
||||
* REVISIT: Because there is only one copy of these save areas,
|
||||
* only a single signal handler can be active. This precludes
|
||||
* queuing of signal actions. As a result, signals received while
|
||||
* another signal handler is executing will be ignored!
|
||||
*/
|
||||
|
||||
uint32_t saved_pc;
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
uint32_t saved_basepri;
|
||||
#else
|
||||
uint32_t saved_primask;
|
||||
#endif
|
||||
uint32_t saved_xpsr;
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
uint32_t saved_lr;
|
||||
|
||||
/* This is the saved address to use when returning from a user-space
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
uint32_t sigreturn;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
/* The following array holds the return address and the exc_return value
|
||||
* needed to return from each nested system call.
|
||||
*/
|
||||
|
||||
uint8_t nsyscalls;
|
||||
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
|
||||
|
||||
#endif
|
||||
|
||||
/* Register save area */
|
||||
|
||||
uint32_t regs[XCPTCONTEXT_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 PRIMASK register */
|
||||
|
||||
static inline uint8_t getprimask(void) inline_function;
|
||||
static inline uint8_t getprimask(void)
|
||||
{
|
||||
uint32_t primask;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, primask\n"
|
||||
: "=r" (primask)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return (uint8_t)primask;
|
||||
}
|
||||
|
||||
static inline void setprimask(uint32_t primask) inline_function;
|
||||
static inline void setprimask(uint32_t primask)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmsr primask, %0\n"
|
||||
:
|
||||
: "r" (primask)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void cpsie(void) inline_function;
|
||||
static inline void cpsie(void)
|
||||
{
|
||||
__asm__ __volatile__ ("\tcpsie i\n");
|
||||
}
|
||||
|
||||
static inline void cpsid(void) inline_function;
|
||||
static inline void cpsid(void)
|
||||
{
|
||||
__asm__ __volatile__ ("\tcpsid i\n");
|
||||
}
|
||||
|
||||
/* Get/set the BASEPRI register. The BASEPRI register defines the minimum
|
||||
* priority for exception processing. When BASEPRI is set to a nonzero
|
||||
* value, it prevents the activation of all exceptions with the same or
|
||||
* lower priority level as the BASEPRI value.
|
||||
*/
|
||||
|
||||
static inline uint8_t getbasepri(void) inline_function;
|
||||
static inline uint8_t getbasepri(void)
|
||||
{
|
||||
uint32_t basepri;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, basepri\n"
|
||||
: "=r" (basepri)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return (uint8_t)basepri;
|
||||
}
|
||||
|
||||
static inline void setbasepri(uint32_t basepri) inline_function;
|
||||
static inline void setbasepri(uint32_t basepri)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmsr basepri, %0\n"
|
||||
:
|
||||
: "r" (basepri)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
|
||||
# define raisebasepri(b) setbasepri(b);
|
||||
|
||||
/* Disable IRQs */
|
||||
|
||||
static inline void up_irq_disable(void) inline_function;
|
||||
static inline void up_irq_disable(void)
|
||||
{
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
/* Probably raising priority */
|
||||
|
||||
raisebasepri(NVIC_SYSH_DISABLE_PRIORITY);
|
||||
#else
|
||||
__asm__ __volatile__ ("\tcpsid i\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Save the current primask state & disable IRQs */
|
||||
|
||||
static inline irqstate_t up_irq_save(void) inline_function;
|
||||
static inline irqstate_t up_irq_save(void)
|
||||
{
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
/* Probably raising priority */
|
||||
|
||||
uint8_t basepri = getbasepri();
|
||||
raisebasepri(NVIC_SYSH_DISABLE_PRIORITY);
|
||||
return (irqstate_t)basepri;
|
||||
|
||||
#else
|
||||
|
||||
unsigned short primask;
|
||||
|
||||
/* Return the current value of primask register and set
|
||||
* bit 0 of the primask register to disable interrupts
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, primask\n"
|
||||
"\tcpsid i\n"
|
||||
: "=r" (primask)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return primask;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Enable IRQs */
|
||||
|
||||
static inline void up_irq_enable(void) inline_function;
|
||||
static inline void up_irq_enable(void)
|
||||
{
|
||||
/* In this case, we are always retaining or lowering the priority value */
|
||||
|
||||
setbasepri(NVIC_SYSH_PRIORITY_MIN);
|
||||
__asm__ __volatile__ ("\tcpsie i\n");
|
||||
}
|
||||
|
||||
/* Restore saved primask state */
|
||||
|
||||
static inline void up_irq_restore(irqstate_t flags) inline_function;
|
||||
static inline void up_irq_restore(irqstate_t flags)
|
||||
{
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
/* In this case, we are always retaining or lowering the priority value */
|
||||
|
||||
setbasepri((uint32_t)flags);
|
||||
|
||||
#else
|
||||
/* If bit 0 of the primask is 0, then we need to restore
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\ttst %0, #1\n"
|
||||
"\tbne.n 1f\n"
|
||||
"\tcpsie i\n"
|
||||
"1:\n"
|
||||
:
|
||||
: "r" (flags)
|
||||
: "memory");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get/set IPSR */
|
||||
|
||||
static inline uint32_t getipsr(void) inline_function;
|
||||
static inline uint32_t getipsr(void)
|
||||
{
|
||||
uint32_t ipsr;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, ipsr\n"
|
||||
: "=r" (ipsr)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return ipsr;
|
||||
}
|
||||
|
||||
/* Get/set CONTROL */
|
||||
|
||||
static inline uint32_t getcontrol(void) inline_function;
|
||||
static inline uint32_t getcontrol(void)
|
||||
{
|
||||
uint32_t control;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, control\n"
|
||||
: "=r" (control)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
static inline void setcontrol(uint32_t control) inline_function;
|
||||
static inline void setcontrol(uint32_t control)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmsr control, %0\n"
|
||||
:
|
||||
: "r" (control)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_H */
|
||||
Executable
+152
@@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/include/armv8-m/irq_cmnvector.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_ARM_INCLUDE_ARMV8_M_IRQ_CMNVECTOR_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_CMNVECTOR_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* IRQ Stack Frame Format: */
|
||||
|
||||
/* The following additional registers are stored by the interrupt handling
|
||||
* logic.
|
||||
*/
|
||||
|
||||
#define REG_R13 (0) /* R13 = SP at time of interrupt */
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
# define REG_BASEPRI (1) /* BASEPRI */
|
||||
#else
|
||||
# define REG_PRIMASK (1) /* PRIMASK */
|
||||
#endif
|
||||
#define REG_R4 (2) /* R4 */
|
||||
#define REG_R5 (3) /* R5 */
|
||||
#define REG_R6 (4) /* R6 */
|
||||
#define REG_R7 (5) /* R7 */
|
||||
#define REG_R8 (6) /* R8 */
|
||||
#define REG_R9 (7) /* R9 */
|
||||
#define REG_R10 (8) /* R10 */
|
||||
#define REG_R11 (9) /* R11 */
|
||||
#define REG_EXC_RETURN (10) /* EXC_RETURN */
|
||||
#define SW_INT_REGS (11)
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
/* If the MCU supports a floating point unit, then it will be necessary
|
||||
* to save the state of the non-volatile registers before calling code
|
||||
* that may save and overwrite them.
|
||||
*/
|
||||
|
||||
# define REG_S16 (SW_INT_REGS + 0) /* S16 */
|
||||
# define REG_S17 (SW_INT_REGS + 1) /* S17 */
|
||||
# define REG_S18 (SW_INT_REGS + 2) /* S18 */
|
||||
# define REG_S19 (SW_INT_REGS + 3) /* S19 */
|
||||
# define REG_S20 (SW_INT_REGS + 4) /* S20 */
|
||||
# define REG_S21 (SW_INT_REGS + 5) /* S21 */
|
||||
# define REG_S22 (SW_INT_REGS + 6) /* S22 */
|
||||
# define REG_S23 (SW_INT_REGS + 7) /* S23 */
|
||||
# define REG_S24 (SW_INT_REGS + 8) /* S24 */
|
||||
# define REG_S25 (SW_INT_REGS + 9) /* S25 */
|
||||
# define REG_S26 (SW_INT_REGS + 10) /* S26 */
|
||||
# define REG_S27 (SW_INT_REGS + 11) /* S27 */
|
||||
# define REG_S28 (SW_INT_REGS + 12) /* S28 */
|
||||
# define REG_S29 (SW_INT_REGS + 13) /* S29 */
|
||||
# define REG_S30 (SW_INT_REGS + 14) /* S30 */
|
||||
# define REG_S31 (SW_INT_REGS + 15) /* S31 */
|
||||
# define SW_FPU_REGS (16)
|
||||
#else
|
||||
# define SW_FPU_REGS (0)
|
||||
#endif
|
||||
|
||||
/* The total number of registers saved by software */
|
||||
|
||||
#define SW_XCPT_REGS (SW_INT_REGS + SW_FPU_REGS)
|
||||
#define SW_XCPT_SIZE (4 * SW_XCPT_REGS)
|
||||
|
||||
/* On entry into an IRQ, the hardware automatically saves the following
|
||||
* registers on the stack in this (address) order:
|
||||
*/
|
||||
|
||||
#define REG_R0 (SW_XCPT_REGS + 0) /* R0 */
|
||||
#define REG_R1 (SW_XCPT_REGS + 1) /* R1 */
|
||||
#define REG_R2 (SW_XCPT_REGS + 2) /* R2 */
|
||||
#define REG_R3 (SW_XCPT_REGS + 3) /* R3 */
|
||||
#define REG_R12 (SW_XCPT_REGS + 4) /* R12 */
|
||||
#define REG_R14 (SW_XCPT_REGS + 5) /* R14 = LR */
|
||||
#define REG_R15 (SW_XCPT_REGS + 6) /* R15 = PC */
|
||||
#define REG_XPSR (SW_XCPT_REGS + 7) /* xPSR */
|
||||
#define HW_INT_REGS (8)
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
/* If the FPU is enabled, the hardware also saves the volatile FP registers.
|
||||
*/
|
||||
|
||||
# define REG_S0 (SW_XCPT_REGS + 8) /* S0 */
|
||||
# define REG_S1 (SW_XCPT_REGS + 9) /* S1 */
|
||||
# define REG_S2 (SW_XCPT_REGS + 10) /* S2 */
|
||||
# define REG_S3 (SW_XCPT_REGS + 11) /* S3 */
|
||||
# define REG_S4 (SW_XCPT_REGS + 12) /* S4 */
|
||||
# define REG_S5 (SW_XCPT_REGS + 13) /* S5 */
|
||||
# define REG_S6 (SW_XCPT_REGS + 14) /* S6 */
|
||||
# define REG_S7 (SW_XCPT_REGS + 15) /* S7 */
|
||||
# define REG_S8 (SW_XCPT_REGS + 16) /* S8 */
|
||||
# define REG_S9 (SW_XCPT_REGS + 17) /* S9 */
|
||||
# define REG_S10 (SW_XCPT_REGS + 18) /* S10 */
|
||||
# define REG_S11 (SW_XCPT_REGS + 19) /* S11 */
|
||||
# define REG_S12 (SW_XCPT_REGS + 20) /* S12 */
|
||||
# define REG_S13 (SW_XCPT_REGS + 21) /* S13 */
|
||||
# define REG_S14 (SW_XCPT_REGS + 22) /* S14 */
|
||||
# define REG_S15 (SW_XCPT_REGS + 23) /* S15 */
|
||||
# define REG_FPSCR (SW_XCPT_REGS + 24) /* FPSCR */
|
||||
# define REG_FP_RESERVED (SW_XCPT_REGS + 25) /* Reserved */
|
||||
# define HW_FPU_REGS (18)
|
||||
#else
|
||||
# define HW_FPU_REGS (0)
|
||||
#endif
|
||||
|
||||
#define HW_XCPT_REGS (HW_INT_REGS + HW_FPU_REGS)
|
||||
#define HW_XCPT_SIZE (4 * HW_XCPT_REGS)
|
||||
|
||||
#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS)
|
||||
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Inline functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_CMNVECTOR_H */
|
||||
Executable
+170
@@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/include/armv8-m/irq_lazyfpu.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_ARM_INCLUDE_ARMV8_M_IRQ_LAZYFPU_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_LAZYFPU_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* IRQ Stack Frame Format: */
|
||||
|
||||
/* The following additional registers are stored by the interrupt handling
|
||||
* logic.
|
||||
*/
|
||||
|
||||
#define REG_R13 (0) /* R13 = SP at time of interrupt */
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
# define REG_BASEPRI (1) /* BASEPRI */
|
||||
#else
|
||||
# define REG_PRIMASK (1) /* PRIMASK */
|
||||
#endif
|
||||
#define REG_R4 (2) /* R4 */
|
||||
#define REG_R5 (3) /* R5 */
|
||||
#define REG_R6 (4) /* R6 */
|
||||
#define REG_R7 (5) /* R7 */
|
||||
#define REG_R8 (6) /* R8 */
|
||||
#define REG_R9 (7) /* R9 */
|
||||
#define REG_R10 (8) /* R10 */
|
||||
#define REG_R11 (9) /* R11 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
# define REG_EXC_RETURN (10) /* EXC_RETURN */
|
||||
# define SW_INT_REGS (11)
|
||||
#else
|
||||
# define SW_INT_REGS (10)
|
||||
#endif
|
||||
|
||||
/* If the MCU supports a floating point unit, then it will be necessary
|
||||
* to save the state of the FPU status register and data registers on
|
||||
* each context switch. These registers are not saved during interrupt
|
||||
* level processing, however. So, as a consequence, floating point
|
||||
* operations may NOT be performed in interrupt handlers.
|
||||
*
|
||||
* The FPU provides an extension register file containing 32 single-
|
||||
* precision registers. These can be viewed as:
|
||||
*
|
||||
* - Sixteen 64-bit doubleword registers, D0-D15
|
||||
* - Thirty-two 32-bit single-word registers, S0-S31
|
||||
* S<2n> maps to the least significant half of D<n>
|
||||
* S<2n+1> maps to the most significant half of D<n>.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
# define REG_D0 (SW_INT_REGS+0) /* D0 */
|
||||
# define REG_S0 (SW_INT_REGS+0) /* S0 */
|
||||
# define REG_S1 (SW_INT_REGS+1) /* S1 */
|
||||
# define REG_D1 (SW_INT_REGS+2) /* D1 */
|
||||
# define REG_S2 (SW_INT_REGS+2) /* S2 */
|
||||
# define REG_S3 (SW_INT_REGS+3) /* S3 */
|
||||
# define REG_D2 (SW_INT_REGS+4) /* D2 */
|
||||
# define REG_S4 (SW_INT_REGS+4) /* S4 */
|
||||
# define REG_S5 (SW_INT_REGS+5) /* S5 */
|
||||
# define REG_D3 (SW_INT_REGS+6) /* D3 */
|
||||
# define REG_S6 (SW_INT_REGS+6) /* S6 */
|
||||
# define REG_S7 (SW_INT_REGS+7) /* S7 */
|
||||
# define REG_D4 (SW_INT_REGS+8) /* D4 */
|
||||
# define REG_S8 (SW_INT_REGS+8) /* S8 */
|
||||
# define REG_S9 (SW_INT_REGS+9) /* S9 */
|
||||
# define REG_D5 (SW_INT_REGS+10) /* D5 */
|
||||
# define REG_S10 (SW_INT_REGS+10) /* S10 */
|
||||
# define REG_S11 (SW_INT_REGS+11) /* S11 */
|
||||
# define REG_D6 (SW_INT_REGS+12) /* D6 */
|
||||
# define REG_S12 (SW_INT_REGS+12) /* S12 */
|
||||
# define REG_S13 (SW_INT_REGS+13) /* S13 */
|
||||
# define REG_D7 (SW_INT_REGS+14) /* D7 */
|
||||
# define REG_S14 (SW_INT_REGS+14) /* S14 */
|
||||
# define REG_S15 (SW_INT_REGS+15) /* S15 */
|
||||
# define REG_D8 (SW_INT_REGS+16) /* D8 */
|
||||
# define REG_S16 (SW_INT_REGS+16) /* S16 */
|
||||
# define REG_S17 (SW_INT_REGS+17) /* S17 */
|
||||
# define REG_D9 (SW_INT_REGS+18) /* D9 */
|
||||
# define REG_S18 (SW_INT_REGS+18) /* S18 */
|
||||
# define REG_S19 (SW_INT_REGS+19) /* S19 */
|
||||
# define REG_D10 (SW_INT_REGS+20) /* D10 */
|
||||
# define REG_S20 (SW_INT_REGS+20) /* S20 */
|
||||
# define REG_S21 (SW_INT_REGS+21) /* S21 */
|
||||
# define REG_D11 (SW_INT_REGS+22) /* D11 */
|
||||
# define REG_S22 (SW_INT_REGS+22) /* S22 */
|
||||
# define REG_S23 (SW_INT_REGS+23) /* S23 */
|
||||
# define REG_D12 (SW_INT_REGS+24) /* D12 */
|
||||
# define REG_S24 (SW_INT_REGS+24) /* S24 */
|
||||
# define REG_S25 (SW_INT_REGS+25) /* S25 */
|
||||
# define REG_D13 (SW_INT_REGS+26) /* D13 */
|
||||
# define REG_S26 (SW_INT_REGS+26) /* S26 */
|
||||
# define REG_S27 (SW_INT_REGS+27) /* S27 */
|
||||
# define REG_D14 (SW_INT_REGS+28) /* D14 */
|
||||
# define REG_S28 (SW_INT_REGS+28) /* S28 */
|
||||
# define REG_S29 (SW_INT_REGS+29) /* S29 */
|
||||
# define REG_D15 (SW_INT_REGS+30) /* D15 */
|
||||
# define REG_S30 (SW_INT_REGS+30) /* S30 */
|
||||
# define REG_S31 (SW_INT_REGS+31) /* S31 */
|
||||
# define REG_FPSCR (SW_INT_REGS+32) /* Floating point status and control */
|
||||
# define SW_FPU_REGS (33)
|
||||
#else
|
||||
# define SW_FPU_REGS (0)
|
||||
#endif
|
||||
|
||||
/* The total number of registers saved by software */
|
||||
|
||||
#define SW_XCPT_REGS (SW_INT_REGS + SW_FPU_REGS)
|
||||
#define SW_XCPT_SIZE (4 * SW_XCPT_REGS)
|
||||
|
||||
/* On entry into an IRQ, the hardware automatically saves the following
|
||||
* registers on the stack in this (address) order:
|
||||
*/
|
||||
|
||||
#define REG_R0 (SW_XCPT_REGS+0) /* R0 */
|
||||
#define REG_R1 (SW_XCPT_REGS+1) /* R1 */
|
||||
#define REG_R2 (SW_XCPT_REGS+2) /* R2 */
|
||||
#define REG_R3 (SW_XCPT_REGS+3) /* R3 */
|
||||
#define REG_R12 (SW_XCPT_REGS+4) /* R12 */
|
||||
#define REG_R14 (SW_XCPT_REGS+5) /* R14 = LR */
|
||||
#define REG_R15 (SW_XCPT_REGS+6) /* R15 = PC */
|
||||
#define REG_XPSR (SW_XCPT_REGS+7) /* xPSR */
|
||||
|
||||
#define HW_XCPT_REGS (8)
|
||||
#define HW_XCPT_SIZE (4 * HW_XCPT_REGS)
|
||||
|
||||
#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS)
|
||||
#define XCPTCONTEXT_SIZE (HW_XCPT_SIZE + SW_XCPT_SIZE)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Inline functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV8_M_IRQ_LAZYFPU_H */
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/include/armv8-m/nvicpri.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_ARM_INCLUDE_ARM8_M_NVICPRI_H
|
||||
#define __ARCH_ARM_INCLUDE_ARM8_M_NVICPRI_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <arch/chip/chip.h>
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* If CONFIG_ARMV8M_USEBASEPRI is selected, then interrupts will be disabled
|
||||
* by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
|
||||
* interrupts will not have execution priority. SVCall must have execution
|
||||
* priority in all cases.
|
||||
*
|
||||
* In the normal cases, interrupts are not nest-able and all interrupts run
|
||||
* at an execution priority between NVIC_SYSH_PRIORITY_MIN and
|
||||
* NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
|
||||
*
|
||||
* If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special
|
||||
* high priority interrupts are supported. These are not "nested" in the
|
||||
* normal sense of the word. These high priority interrupts can interrupt
|
||||
* normal processing but execute outside of OS (although they can "get back
|
||||
* into the game" via a PendSV interrupt).
|
||||
*
|
||||
* In the normal course of things, interrupts must occasionally be disabled
|
||||
* using the up_irq_save() inline function to prevent contention in use of
|
||||
* resources that may be shared between interrupt level and non-interrupt
|
||||
* level logic. Now the question arises, if we are using
|
||||
* CONFIG_ARCH_HIPRI_INTERRUPT=y, do we disable all interrupts except
|
||||
* SVCall (we cannot disable SVCall interrupts). Or do we only disable the
|
||||
* "normal" interrupts?
|
||||
*
|
||||
* If we are using the BASEPRI register to disable interrupts, then the
|
||||
* answer is that we must disable ONLY the "normal interrupts". That
|
||||
* is because we cannot disable SVCALL interrupts and we cannot permit
|
||||
* SVCAll interrupts running at a higher priority than the high priority
|
||||
* interrupts (otherwise, they will introduce jitter in the high priority
|
||||
* interrupt response time.)
|
||||
*
|
||||
* Hence, if you need to disable the high priority interrupt, you will have
|
||||
* to disable the interrupt either at the peripheral that generates the
|
||||
* interrupt or at the NVIC. Disabling global interrupts via the BASEPRI
|
||||
* register cannot effect high priority interrupts.
|
||||
*/
|
||||
|
||||
/* The high priority interrupt must be highest priority. This prevents
|
||||
* SVCALL handling from adding jitter to high priority interrupt response.
|
||||
* Disabling interrupts will disable all interrupts EXCEPT SVCALL and the
|
||||
* high priority interrupts.
|
||||
*/
|
||||
|
||||
#define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
||||
#define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP)
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARM8_M_NVICPRI_H */
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/include/armv8-a/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_ARM_INCLUDE_ARMV8_M_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV8_M_SPINLOCK_H
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV8_M_SPINLOCK_H */
|
||||
Executable
+248
@@ -0,0 +1,248 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/include/armv8-m/syscall.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* This file should never be included directly but, rather, only indirectly
|
||||
* through include/syscall.h or include/sys/sycall.h
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV8_M_SYSCALL_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV8_M_SYSCALL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the value used as the argument to the SVC instruction. It is not
|
||||
* used.
|
||||
*/
|
||||
|
||||
#define SYS_syscall 0x00
|
||||
#define SYS_smhcall 0xab
|
||||
|
||||
/* The SYS_signal_handler_return is executed here... its value is not always
|
||||
* available in this context and so is assumed to be 7.
|
||||
*/
|
||||
|
||||
#ifndef SYS_signal_handler_return
|
||||
# define SYS_signal_handler_return (7)
|
||||
#elif SYS_signal_handler_return != 7
|
||||
# error "SYS_signal_handler_return was assumed to be 7"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Inline functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* SVC call with SYS_ call number and no parameters */
|
||||
|
||||
static inline uintptr_t sys_call0(unsigned int nbr)
|
||||
{
|
||||
register long reg0 __asm__("r0") = (long)(nbr);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"svc %1"
|
||||
: "=r"(reg0)
|
||||
: "i"(SYS_syscall), "r"(reg0)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/* SVC call with SYS_ call number and one parameter */
|
||||
|
||||
static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
|
||||
{
|
||||
register long reg0 __asm__("r0") = (long)(nbr);
|
||||
register long reg1 __asm__("r1") = (long)(parm1);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"svc %1"
|
||||
: "=r"(reg0)
|
||||
: "i"(SYS_syscall), "r"(reg0), "r"(reg1)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/* SVC call with SYS_ call number and two parameters */
|
||||
|
||||
static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2)
|
||||
{
|
||||
register long reg0 __asm__("r0") = (long)(nbr);
|
||||
register long reg2 __asm__("r2") = (long)(parm2);
|
||||
register long reg1 __asm__("r1") = (long)(parm1);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"svc %1"
|
||||
: "=r"(reg0)
|
||||
: "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/* SVC call with SYS_ call number and three parameters */
|
||||
|
||||
static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4);
|
||||
static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3)
|
||||
{
|
||||
return sys_call4(nbr, parm1, parm2, parm3, 0);
|
||||
}
|
||||
|
||||
/* SVC call with SYS_ call number and four parameters.
|
||||
*
|
||||
* NOTE the nonstandard parameter passing: parm4 is in R4
|
||||
*/
|
||||
|
||||
static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4)
|
||||
{
|
||||
register long reg0 __asm__("r0") = (long)(nbr);
|
||||
register long reg4 __asm__("r4") = (long)(parm4);
|
||||
register long reg3 __asm__("r3") = (long)(parm3);
|
||||
register long reg2 __asm__("r2") = (long)(parm2);
|
||||
register long reg1 __asm__("r1") = (long)(parm1);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"svc %1"
|
||||
: "=r"(reg0)
|
||||
: "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
"r"(reg3), "r"(reg4)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/* SVC call with SYS_ call number and five parameters.
|
||||
*
|
||||
* NOTE the nonstandard parameter passing: parm4 and parm5 are in R4 and R5
|
||||
*/
|
||||
|
||||
static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4, uintptr_t parm5,
|
||||
uintptr_t parm6);
|
||||
static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4, uintptr_t parm5)
|
||||
{
|
||||
return sys_call6(nbr, parm1, parm2, parm3, parm4, parm5, 0);
|
||||
}
|
||||
|
||||
/* SVC call with SYS_ call number and six parameters.
|
||||
*
|
||||
* NOTE the nonstandard parameter passing: parm4-parm6 are in R4-R6
|
||||
*/
|
||||
|
||||
static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4, uintptr_t parm5,
|
||||
uintptr_t parm6)
|
||||
{
|
||||
register long reg0 __asm__("r0") = (long)(nbr);
|
||||
register long reg6 __asm__("r6") = (long)(parm6);
|
||||
register long reg5 __asm__("r5") = (long)(parm5);
|
||||
register long reg4 __asm__("r4") = (long)(parm4);
|
||||
register long reg3 __asm__("r3") = (long)(parm3);
|
||||
register long reg2 __asm__("r2") = (long)(parm2);
|
||||
register long reg1 __asm__("r1") = (long)(parm1);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"svc %1"
|
||||
: "=r"(reg0)
|
||||
: "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
"r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/* semihosting(SMH) call with call number and one parameter */
|
||||
|
||||
static inline long smh_call(unsigned int nbr, void *parm)
|
||||
{
|
||||
register long reg0 __asm__("r0") = (long)(nbr);
|
||||
register long reg1 __asm__("r1") = (long)(parm);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"bkpt %1"
|
||||
: "=r"(reg0)
|
||||
: "i"(SYS_smhcall), "r"(reg0), "r"(reg1)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV8_M_SYSCALL_H */
|
||||
@@ -63,6 +63,8 @@
|
||||
# include <arch/armv7-r/irq.h>
|
||||
#elif defined(CONFIG_ARCH_ARMV7M)
|
||||
# include <arch/armv7-m/irq.h>
|
||||
#elif defined(CONFIG_ARCH_ARMV8M)
|
||||
# include <arch/armv8-m/irq.h>
|
||||
#elif defined(CONFIG_ARCH_CORTEXM0)
|
||||
# include <arch/armv6-m/irq.h>
|
||||
#else
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_ARMV7M
|
||||
#if defined(CONFIG_ARCH_ARMV7M) || defined(CONFIG_ARCH_ARMV8M)
|
||||
struct setjmp_buf_s
|
||||
{
|
||||
/* Note: core registers r0-r3 are caller-saved */
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
# include <arch/armv7-r/syscall.h>
|
||||
#elif defined(CONFIG_ARCH_ARMV7M)
|
||||
# include <arch/armv7-m/syscall.h>
|
||||
#elif defined(CONFIG_ARCH_ARMV8M)
|
||||
# include <arch/armv8-m/syscall.h>
|
||||
#elif defined(CONFIG_ARCH_CORTEXM0)
|
||||
# include <arch/armv6-m/syscall.h>
|
||||
#else
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef unsigned int _size_t;
|
||||
*/
|
||||
|
||||
#ifdef __thumb2__
|
||||
#if defined(CONFIG_ARMV7M_USEBASEPRI) || defined(CONFIG_ARCH_ARMV6M)
|
||||
#if defined(CONFIG_ARMV7M_USEBASEPRI) || defined(CONFIG_ARCH_ARMV6M) || defined(CONFIG_ARMV8M_USEBASEPRI)
|
||||
typedef unsigned char irqstate_t;
|
||||
#else
|
||||
typedef unsigned short irqstate_t;
|
||||
|
||||
@@ -43,6 +43,8 @@ else ifeq ($(CONFIG_ARCH_ARMV7R),y) # ARMv7-R
|
||||
ARCH_SUBDIR = armv7-r
|
||||
else ifeq ($(CONFIG_ARCH_ARMV7M),y) # ARMv7-M
|
||||
ARCH_SUBDIR = armv7-m
|
||||
else ifeq ($(CONFIG_ARCH_ARMV8M),y) # ARMv8-M
|
||||
ARCH_SUBDIR = armv8-m
|
||||
else ifeq ($(CONFIG_ARCH_CORTEXM0),y) # Cortex-M0 is ARMv6-M
|
||||
ARCH_SUBDIR = armv6-m
|
||||
else # ARM9, ARM7TDMI, etc.
|
||||
|
||||
Executable
+243
@@ -0,0 +1,243 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
comment "ARMV8M Configuration Options"
|
||||
|
||||
config ARMV8M_HAVE_ICACHE
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARMV8M_HAVE_DCACHE
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARMV8M_LAZYFPU
|
||||
bool "Lazy FPU storage"
|
||||
default n
|
||||
depends on ARCH_HAVE_LAZYFPU
|
||||
---help---
|
||||
There are two forms of the common vector logic. There are pros and
|
||||
cons to each option:
|
||||
|
||||
1) The standard common vector logic exploits features of the ARMv8-M
|
||||
architecture to save the all of floating registers on entry into
|
||||
each interrupt and then to restore the floating registers when
|
||||
the interrupt returns. The primary advantage to this approach is
|
||||
that floating point operations are available in interrupt
|
||||
handling logic. Since the volatile registers are preserved,
|
||||
operations on the floating point registers by interrupt handling
|
||||
logic has no ill effect. The downside is, of course, that more
|
||||
stack operations are required on each interrupt to save and store
|
||||
the floating point registers. Because of the some special
|
||||
features of the ARMv-M, this is not as much overhead as you might
|
||||
expect, but overhead nonetheless.
|
||||
|
||||
2) The lazy FPU common vector logic does not save or restore
|
||||
floating point registers on entry and exit from the interrupt
|
||||
handler. Rather, the floating point registers are not restored
|
||||
until it is absolutely necessary to do so when a context switch
|
||||
occurs and the interrupt handler will be returning to a different
|
||||
floating point context. Since floating point registers are not
|
||||
protected, floating point operations must not be performed in
|
||||
interrupt handling logic. Better interrupt performance is be
|
||||
expected, however.
|
||||
|
||||
By default, the "standard" common vector logic is build. This
|
||||
option selects the alternate lazy FPU common vector logic.
|
||||
|
||||
config ARMV8M_USEBASEPRI
|
||||
bool "Use BASEPRI Register"
|
||||
default y if ARCH_HIPRI_INTERRUPT
|
||||
---help---
|
||||
Use the BASEPRI register to enable and disable interrupts. By
|
||||
default, the PRIMASK register is used for this purpose. This
|
||||
usually results in hardfaults when supervisor calls are made.
|
||||
Though, these hardfaults are properly handled by the RTOS, the
|
||||
hardfaults can confuse some debuggers. With the BASEPRI
|
||||
register, these hardfaults, will be avoided. For more details see
|
||||
http://www.nuttx.org/doku.php?id=wiki:nxinternal:svcall
|
||||
|
||||
WARNING: If CONFIG_ARCH_HIPRI_INTERRUPT is selected, then you
|
||||
MUST select CONFIG_ARMV8M_USEBASEPRI. The Kconfig dependencies
|
||||
here will permit to select an invalid configuration because it
|
||||
cannot enforce that requirement. If you create this invalild
|
||||
configuration, you will encounter some problems that may be
|
||||
very difficult to debug.
|
||||
|
||||
config ARMV8M_ICACHE
|
||||
bool "Use I-Cache"
|
||||
default n
|
||||
depends on ARMV8M_HAVE_ICACHE
|
||||
select ARCH_ICACHE
|
||||
|
||||
config ARMV8M_DCACHE
|
||||
bool "Use D-Cache"
|
||||
default n
|
||||
depends on ARMV8M_HAVE_DCACHE
|
||||
select ARCH_DCACHE
|
||||
|
||||
config ARMV8M_DCACHE_WRITETHROUGH
|
||||
bool "D-Cache Write-Through"
|
||||
default n
|
||||
depends on ARMV8M_DCACHE
|
||||
|
||||
config ARMV8M_HAVE_ITCM
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARMV8M_HAVE_DTCM
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARMV8M_ITCM
|
||||
bool "Use ITCM"
|
||||
default n
|
||||
depends on ARMV8M_HAVE_ITCM
|
||||
|
||||
config ARMV8M_DTCM
|
||||
bool "Use DTCM"
|
||||
default n
|
||||
depends on ARMV8M_HAVE_DTCM
|
||||
|
||||
choice
|
||||
prompt "Toolchain Selection"
|
||||
default ARMV8M_TOOLCHAIN_GNU_EABIW if TOOLCHAIN_WINDOWS
|
||||
default ARMV8M_TOOLCHAIN_GNU_EABIL if !TOOLCHAIN_WINDOWS
|
||||
|
||||
config ARMV8M_TOOLCHAIN_ATOLLIC
|
||||
bool "Atollic Lite/Pro for Windows"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_BUILDROOT
|
||||
bool "Buildroot (Cygwin or Linux)"
|
||||
depends on !WINDOWS_NATIVE
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_CODEREDL
|
||||
bool "CodeRed for Linux"
|
||||
depends on HOST_LINUX
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_CODEREDW
|
||||
bool "CodeRed for Windows"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_CODESOURCERYL
|
||||
bool "CodeSourcery GNU toolchain under Linux"
|
||||
depends on HOST_LINUX
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_CODESOURCERYW
|
||||
bool "CodeSourcery GNU toolchain under Windows"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_DEVKITARM
|
||||
bool "devkitARM GNU toolchain"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_GNU_EABIL
|
||||
bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)"
|
||||
depends on !WINDOWS_NATIVE
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
---help---
|
||||
This option should work for any modern GNU toolchain (GCC 4.5 or newer)
|
||||
configured for arm-none-eabi.
|
||||
|
||||
config ARMV8M_TOOLCHAIN_GNU_EABIW
|
||||
bool "Generic GNU EABI toolchain under Windows"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_CLANGL
|
||||
bool "Generic Clang toolchain under Linux (or other POSIX environment)"
|
||||
depends on !WINDOWS_NATIVE
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
config ARMV8M_TOOLCHAIN_CLANGW
|
||||
bool "Generic Clang toolchain under Windows"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
---help---
|
||||
This option should work for any modern GNU toolchain (GCC 4.5 or newer)
|
||||
configured for arm-none-eabi.
|
||||
|
||||
config ARMV8M_TOOLCHAIN_RAISONANCE
|
||||
bool "STMicro Raisonance for Windows"
|
||||
depends on TOOLCHAIN_WINDOWS
|
||||
select ARCH_TOOLCHAIN_GNU
|
||||
|
||||
endchoice
|
||||
|
||||
config ARMV8M_OABI_TOOLCHAIN
|
||||
bool "OABI (vs EABI)"
|
||||
default n
|
||||
depends on ARMV8M_TOOLCHAIN_BUILDROOT
|
||||
---help---
|
||||
Most of the older buildroot toolchains are OABI and are named
|
||||
arm-nuttx-elf- vs. arm-nuttx-eabi-
|
||||
|
||||
config ARMV8M_TARGET2_PREL
|
||||
bool "R_ARM_TARGET2 is PC relative"
|
||||
default n if !CXX_EXCEPTION
|
||||
default y if CXX_EXCEPTION
|
||||
depends on ELF
|
||||
---help---
|
||||
Perform a PC relative relocation for relocation type R_ARM_TARGET2
|
||||
|
||||
config ARMV8M_HAVE_STACKCHECK
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARMV8M_STACKCHECK
|
||||
bool "Check for stack overflow on each function call"
|
||||
default n
|
||||
depends on ARMV8M_HAVE_STACKCHECK
|
||||
---help---
|
||||
This check uses R10 to check for a stack overflow within each
|
||||
function call. This has performances and code size impacts, but it
|
||||
will be able to catch hard to find stack overflows.
|
||||
|
||||
Currently only available only for the STM32, SAM3/4 and SAMA5D
|
||||
architectures. The changes are not complex and patches for
|
||||
other architectures will be accepted.
|
||||
|
||||
This option requires that you are using a GCC toolchain and that
|
||||
you also include -finstrument-functions in your CFLAGS when you
|
||||
compile. This addition to your CFLAGS should probably be added
|
||||
to the definition of the CFFLAGS in your board Make.defs file.
|
||||
|
||||
config ARMV8M_ITMSYSLOG
|
||||
bool "ITM SYSLOG support"
|
||||
default n
|
||||
select ARCH_SYSLOG
|
||||
select SYSLOG
|
||||
---help---
|
||||
Enable hooks to support ITM syslog output. This requires additional
|
||||
MCU support in order to be used. See arch/arm/src/armv8-m/itm_syslog.h
|
||||
for additional initialization information.
|
||||
|
||||
if ARMV8M_ITMSYSLOG
|
||||
|
||||
config ARMV8M_ITMSYSLOG_PORT
|
||||
int "ITM SYSLOG Port"
|
||||
default 0
|
||||
range 0 31
|
||||
|
||||
config ARMV8M_ITMSYSLOG_SWODIV
|
||||
int "ITM SYSLOG SWO divider"
|
||||
default 15
|
||||
range 1 8192
|
||||
|
||||
endif # ARMV8M_ITMSYSLOG
|
||||
|
||||
config ARMV8M_SYSTICK
|
||||
bool "SysTick timer driver"
|
||||
depends on TIMER
|
||||
---help---
|
||||
Enable SysTick timer driver.
|
||||
Executable
+274
@@ -0,0 +1,274 @@
|
||||
############################################################################
|
||||
# arch/arm/src/armv8-m/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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# Setup for the selected toolchain
|
||||
|
||||
#
|
||||
# Handle old-style chip-specific toolchain names in the absence of
|
||||
# a new-style toolchain specification, force the selection of a single
|
||||
# toolchain and allow the selected toolchain to be overridden by a
|
||||
# command-line selection.
|
||||
#
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_ATOLLIC) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= ATOLLIC
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_BUILDROOT) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= BUILDROOT
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_CODEREDL) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= CODEREDL
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_CODEREDW) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= CODEREDW
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_CODESOURCERYL) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= CODESOURCERYL
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_CODESOURCERYW) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= CODESOURCERYW
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_DEVKITARM) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= DEVKITARM
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_RAISONANCE) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= RAISONANCE
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_GNU_EABIL) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= GNU_EABIL
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_GNU_EABIW) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= GNU_EABIW
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_CLANGL) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= CLANGL
|
||||
endif
|
||||
|
||||
ifeq ($(filter y, \
|
||||
$(CONFIG_ARMV8M_TOOLCHAIN_CLANGW) \
|
||||
),y)
|
||||
CONFIG_ARMV8M_TOOLCHAIN ?= CLANGW
|
||||
endif
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y)
|
||||
MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL)
|
||||
endif
|
||||
|
||||
# Parametrization for ARCHCPUFLAGS
|
||||
ifeq ($(CONFIG_ARCH_CORTEXM23),y)
|
||||
TOOLCHAIN_MCPU := -mcpu=cortex-m23
|
||||
TOOLCHAIN_MARCH := -march=armv8-m.main
|
||||
TOOLCHAIN_MFLOAT := -mfloat-abi=soft
|
||||
else ifeq ($(CONFIG_ARCH_CORTEXM33),y)
|
||||
TOOLCHAIN_MCPU := -mcpu=cortex-m33
|
||||
TOOLCHAIN_MARCH := -march=armv8-m.main+dsp
|
||||
ifeq ($(CONFIG_ARCH_FPU),y)
|
||||
TOOLCHAIN_MFLOAT := -mfpu=fpv5-sp-d16 -mfloat-abi=hard
|
||||
else
|
||||
TOOLCHAIN_MFLOAT := -mfloat-abi=soft
|
||||
endif
|
||||
else ifeq ($(CONFIG_ARCH_CORTEXM35P),y)
|
||||
TOOLCHAIN_MCPU := -mcpu=cortex-m35p
|
||||
TOOLCHAIN_MARCH := -march=armv8-m.main+dsp
|
||||
ifeq ($(CONFIG_ARCH_FPU),y)
|
||||
TOOLCHAIN_MFLOAT := -mfpu=fpv5-sp-d16 -mfloat-abi=hard
|
||||
else
|
||||
TOOLCHAIN_MFLOAT := -mfloat-abi=soft
|
||||
endif
|
||||
endif
|
||||
|
||||
# Atollic toolchain under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),ATOLLIC)
|
||||
CROSSDEV ?= arm-atollic-eabi-
|
||||
ARCROSSDEV ?= arm-atollic-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
endif
|
||||
|
||||
# NuttX buildroot under Linux or Cygwin
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),BUILDROOT)
|
||||
ifeq ($(CONFIG_ARMV8M_OABI_TOOLCHAIN),y)
|
||||
CROSSDEV ?= arm-nuttx-elf-
|
||||
ARCROSSDEV ?= arm-nuttx-elf-
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) $(TOOLCHAIN_MFLOAT)
|
||||
else
|
||||
CROSSDEV ?= arm-nuttx-eabi-
|
||||
ARCROSSDEV ?= arm-nuttx-eabi-
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
endif
|
||||
|
||||
# Code Red RedSuite under Linux
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),CODEREDL)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
|
||||
# Code Red RedSuite under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),CODEREDW)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
endif
|
||||
|
||||
# CodeSourcery under Linux
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),CODESOURCERYL)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -O2
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
|
||||
# CodeSourcery under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),CODESOURCERYW)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
endif
|
||||
|
||||
# devkitARM under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),DEVKITARM)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
|
||||
# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),GNU_EABIL)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
|
||||
# Generic GNU EABI toolchain under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),GNU_EABIW)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
endif
|
||||
|
||||
# Clang toolchain on OS X, Linux or any typical Posix system
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),CLANGL)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
|
||||
# Clang toolchain under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),CLANGW)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION ?= -Os
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
endif
|
||||
|
||||
# Raisonance RIDE7 under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV8M_TOOLCHAIN),RAISONANCE)
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT)
|
||||
endif
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/barriers.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_ARM_SRC_COMMON_ARMV8_M_BARRIERS_H
|
||||
#define __ARCH_ARM_SRC_COMMON_ARMV8_M_BARRIERS_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* ARMv8-M memory barriers */
|
||||
|
||||
#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory")
|
||||
#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory")
|
||||
#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory")
|
||||
|
||||
#define ARM_DSB() arm_dsb(15)
|
||||
#define ARM_ISB() arm_isb(15)
|
||||
#define ARM_DMB() arm_dmb(15)
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_COMMON_ARMV8_M_BARRIERS_H */
|
||||
Executable
+191
@@ -0,0 +1,191 @@
|
||||
/***************************************************************************************
|
||||
* arch/arm/src/armv8-m/dwt.h
|
||||
*
|
||||
* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved.
|
||||
* Author: Pierre-noel Bouteville <pnb990@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
***********************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_ARMV8_M_DWT_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_DWT_H
|
||||
|
||||
/***********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
***********************************************************************************************/
|
||||
|
||||
/* Data Watchpoint and Trace Register (DWT) Definitions ****************************************/
|
||||
|
||||
/* DWT Register Base Address *******************************************************************/
|
||||
|
||||
#define DWT_BASE (0xe0001000ul)
|
||||
|
||||
/* DWT Register Addresses **********************************************************************/
|
||||
|
||||
#define DWT_CTRL (DWT_BASE + 0x0000) /* Control Register */
|
||||
#define DWT_CYCCNT (DWT_BASE + 0x0004) /* Cycle Count Register */
|
||||
#define DWT_CPICNT (DWT_BASE + 0x0008) /* CPI Count Register */
|
||||
#define DWT_EXCCNT (DWT_BASE + 0x000c) /* Exception Overhead Count Register */
|
||||
#define DWT_SLEEPCNT (DWT_BASE + 0x0010) /* Sleep Count Register */
|
||||
#define DWT_LSUCNT (DWT_BASE + 0x0014) /* LSU Count Register */
|
||||
#define DWT_FOLDCNT (DWT_BASE + 0x0018) /* Folded-instruction Count Register */
|
||||
#define DWT_PCSR (DWT_BASE + 0x001c) /* Program Counter Sample Register */
|
||||
#define DWT_COMP0 (DWT_BASE + 0x0020) /* Comparator Register 0 */
|
||||
#define DWT_MASK0 (DWT_BASE + 0x0024) /* Mask Register 0 */
|
||||
#define DWT_FUNCTION0 (DWT_BASE + 0x0028) /* Function Register 0 */
|
||||
#define DWT_COMP1 (DWT_BASE + 0x0030) /* Comparator Register 1 */
|
||||
#define DWT_MASK1 (DWT_BASE + 0x0034) /* Mask Register 1 */
|
||||
#define DWT_FUNCTION1 (DWT_BASE + 0x0038) /* Function Register 1 */
|
||||
#define DWT_COMP2 (DWT_BASE + 0x0040) /* Comparator Register 2 */
|
||||
#define DWT_MASK2 (DWT_BASE + 0x0044) /* Mask Register 2 */
|
||||
#define DWT_FUNCTION2 (DWT_BASE + 0x0048) /* Function Register 2 */
|
||||
#define DWT_COMP3 (DWT_BASE + 0x0050) /* Comparator Register 3 */
|
||||
#define DWT_MASK3 (DWT_BASE + 0x0054) /* Mask Register 3 */
|
||||
#define DWT_FUNCTION3 (DWT_BASE + 0x0058) /* Function Register 3 */
|
||||
|
||||
/* DWT Register Bit Field Definitions **********************************************************/
|
||||
|
||||
/* DWT CTRL */
|
||||
|
||||
#define DWT_CTRL_NUMCOMP_SHIFT 28
|
||||
#define DWT_CTRL_NUMCOMP_MASK (0xFul << DWT_CTRL_NUMCOMP_SHIFT)
|
||||
#define DWT_CTRL_NOTRCPKT_SHIFT 27
|
||||
#define DWT_CTRL_NOTRCPKT_MASK (0x1ul << DWT_CTRL_NOTRCPKT_SHIFT)
|
||||
#define DWT_CTRL_NOEXTTRIG_SHIFT 26
|
||||
#define DWT_CTRL_NOEXTTRIG_MASK (0x1ul << DWT_CTRL_NOEXTTRIG_SHIFT)
|
||||
#define DWT_CTRL_NOCYCCNT_SHIFT 25
|
||||
#define DWT_CTRL_NOCYCCNT_MASK (0x1ul << DWT_CTRL_NOCYCCNT_SHIFT)
|
||||
#define DWT_CTRL_NOPRFCNT_SHIFT 24
|
||||
#define DWT_CTRL_NOPRFCNT_MASK (0x1ul << DWT_CTRL_NOPRFCNT_SHIFT)
|
||||
#define DWT_CTRL_CYCEVTENA_SHIFT 22
|
||||
#define DWT_CTRL_CYCEVTENA_MASK (0x1ul << DWT_CTRL_CYCEVTENA_SHIFT)
|
||||
#define DWT_CTRL_FOLDEVTENA_SHIFT 21
|
||||
#define DWT_CTRL_FOLDEVTENA_MASK (0x1ul << DWT_CTRL_FOLDEVTENA_SHIFT)
|
||||
#define DWT_CTRL_LSUEVTENA_SHIFT 20
|
||||
#define DWT_CTRL_LSUEVTENA_MASK (0x1ul << DWT_CTRL_LSUEVTENA_SHIFT)
|
||||
#define DWT_CTRL_SLEEPEVTENA_SHIFT 19
|
||||
#define DWT_CTRL_SLEEPEVTENA_MASK (0x1ul << DWT_CTRL_SLEEPEVTENA_SHIFT)
|
||||
#define DWT_CTRL_EXCEVTENA_SHIFT 18
|
||||
#define DWT_CTRL_EXCEVTENA_MASK (0x1ul << DWT_CTRL_EXCEVTENA_SHIFT)
|
||||
#define DWT_CTRL_CPIEVTENA_SHIFT 17
|
||||
#define DWT_CTRL_CPIEVTENA_MASK (0x1ul << DWT_CTRL_CPIEVTENA_SHIFT)
|
||||
#define DWT_CTRL_EXCTRCENA_SHIFT 16
|
||||
#define DWT_CTRL_EXCTRCENA_MASK (0x1ul << DWT_CTRL_EXCTRCENA_SHIFT)
|
||||
#define DWT_CTRL_PCSAMPLENA_SHIFT 12
|
||||
#define DWT_CTRL_PCSAMPLENA_MASK (0x1ul << DWT_CTRL_PCSAMPLENA_SHIFT)
|
||||
#define DWT_CTRL_SYNCTAP_SHIFT 10
|
||||
#define DWT_CTRL_SYNCTAP_MASK (0x3ul << DWT_CTRL_SYNCTAP_SHIFT)
|
||||
#define DWT_CTRL_CYCTAP_SHIFT 9
|
||||
#define DWT_CTRL_CYCTAP_MASK (0x1ul << DWT_CTRL_CYCTAP_SHIFT)
|
||||
#define DWT_CTRL_POSTINIT_SHIFT 5
|
||||
#define DWT_CTRL_POSTINIT_MASK (0xful << DWT_CTRL_POSTINIT_SHIFT)
|
||||
#define DWT_CTRL_POSTPRESET_SHIFT 1
|
||||
#define DWT_CTRL_POSTPRESET_MASK (0xful << DWT_CTRL_POSTPRESET_SHIFT)
|
||||
#define DWT_CTRL_CYCCNTENA_SHIFT 0
|
||||
#define DWT_CTRL_CYCCNTENA_MASK (0x1ul << DWT_CTRL_CYCCNTENA_SHIFT)
|
||||
|
||||
/* DWT CPICNT */
|
||||
|
||||
#define DWT_CPICNT_CPICNT_SHIFT 0
|
||||
#define DWT_CPICNT_CPICNT_MASK (0xfful << DWT_CPICNT_CPICNT_SHIFT)
|
||||
|
||||
/* DWT EXCCNT */
|
||||
|
||||
#define DWT_EXCCNT_EXCCNT_SHIFT 0
|
||||
#define DWT_EXCCNT_EXCCNT_MASK (0xfful << DWT_EXCCNT_EXCCNT_SHIFT)
|
||||
|
||||
/* DWT SLEEPCNT */
|
||||
|
||||
#define DWT_SLEEPCNT_SLEEPCNT_SHIFT 0
|
||||
#define DWT_SLEEPCNT_SLEEPCNT_MASK (0xfful << DWT_SLEEPCNT_SLEEPCNT_SHIFT)
|
||||
|
||||
/* DWT LSUCNT */
|
||||
|
||||
#define DWT_LSUCNT_LSUCNT_SHIFT 0
|
||||
#define DWT_LSUCNT_LSUCNT_MASK (0xfful << DWT_LSUCNT_LSUCNT_SHIFT)
|
||||
|
||||
/* DWT FOLDCNT */
|
||||
|
||||
#define DWT_FOLDCNT_FOLDCNT_SHIFT 0
|
||||
#define DWT_FOLDCNT_FOLDCNT_MASK (0xfful << DWT_FOLDCNT_FOLDCNT_SHIFT)
|
||||
|
||||
/* DWT MASK */
|
||||
|
||||
#define DWT_MASK_MASK_SHIFT 0
|
||||
#define DWT_MASK_MASK_MASK (0x1ful << DWT_MASK_MASK_SHIFT)
|
||||
|
||||
/* DWT FUNCTION */
|
||||
|
||||
#define DWT_FUNCTION_MATCHED_SHIFT 24
|
||||
#define DWT_FUNCTION_MATCHED_MASK (0x1ul << DWT_FUNCTION_MATCHED_SHIFT)
|
||||
#define DWT_FUNCTION_DATAVADDR1_SHIFT 16
|
||||
#define DWT_FUNCTION_DATAVADDR1_MASK (0xful << DWT_FUNCTION_DATAVADDR1_SHIFT)
|
||||
#define DWT_FUNCTION_DATAVADDR0_SHIFT 12
|
||||
#define DWT_FUNCTION_DATAVADDR0_MASK (0xful << DWT_FUNCTION_DATAVADDR0_SHIFT)
|
||||
#define DWT_FUNCTION_DATAVSIZE_SHIFT 10
|
||||
#define DWT_FUNCTION_DATAVSIZE_MASK (0x3ul << DWT_FUNCTION_DATAVSIZE_SHIFT)
|
||||
#define DWT_FUNCTION_LNK1ENA_SHIFT 9
|
||||
#define DWT_FUNCTION_LNK1ENA_MASK (0x1ul << DWT_FUNCTION_LNK1ENA_SHIFT)
|
||||
#define DWT_FUNCTION_DATAVMATCH_SHIFT 8
|
||||
#define DWT_FUNCTION_DATAVMATCH_MASK (0x1ul << DWT_FUNCTION_DATAVMATCH_SHIFT)
|
||||
#define DWT_FUNCTION_CYCMATCH_SHIFT 7
|
||||
#define DWT_FUNCTION_CYCMATCH_MASK 0x1ul << DWT_FUNCTION_CYCMATCH_SHIFT)
|
||||
#define DWT_FUNCTION_EMITRANGE_SHIFT 5
|
||||
#define DWT_FUNCTION_EMITRANGE_MASK (0x1ul << DWT_FUNCTION_EMITRANGE_SHIFT)
|
||||
#define DWT_FUNCTION_FUNCTION_SHIFT 0
|
||||
#define DWT_FUNCTION_FUNCTION_MASK (0xful << DWT_FUNCTION_FUNCTION_SHIFT)
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_DWT_H */
|
||||
Executable
+916
File diff suppressed because it is too large
Load Diff
Executable
+104
@@ -0,0 +1,104 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/exc_return.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_ARM_SRC_ARMV8_M_EXC_RETURN_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_EXC_RETURN_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* The processor saves an EXC_RETURN value to the LR on exception entry. The
|
||||
* exception mechanism relies on this value to detect when the processor has
|
||||
* completed an exception handler.
|
||||
*
|
||||
* Bits [31:28] of an EXC_RETURN value are always 1. When the processor loads a
|
||||
* value matching this pattern to the PC it detects that the operation is a not
|
||||
* a normal branch operation and instead, that the exception is complete.
|
||||
* Therefore, it starts the exception return sequence.
|
||||
*
|
||||
* Bits[4:0] of the EXC_RETURN value indicate the required return stack and eventual
|
||||
* processor mode. The remaining bits of the EXC_RETURN value should be set to 1.
|
||||
*/
|
||||
|
||||
/* EXC_RETURN_BASE: Bits that are always set in an EXC_RETURN value. */
|
||||
|
||||
#define EXC_RETURN_BASE 0xffffffe1
|
||||
|
||||
/* EXC_RETURN_PROCESS_STACK: The exception saved (and will restore) the hardware
|
||||
* context using the process stack pointer (if not set, the context was saved
|
||||
* using the main stack pointer)
|
||||
*/
|
||||
|
||||
#define EXC_RETURN_PROCESS_STACK (1 << 2)
|
||||
|
||||
/* EXC_RETURN_THREAD_MODE: The exception will return to thread mode (if not set,
|
||||
* return stays in handler mode)
|
||||
*/
|
||||
|
||||
#define EXC_RETURN_THREAD_MODE (1 << 3)
|
||||
|
||||
/* EXC_RETURN_STD_CONTEXT: The state saved on the stack does not include the
|
||||
* volatile FP registers and FPSCR. If this bit is clear, the state does include
|
||||
* these registers.
|
||||
*/
|
||||
|
||||
#define EXC_RETURN_STD_CONTEXT (1 << 4)
|
||||
|
||||
/* EXC_RETURN_HANDLER: Return to handler mode. Exception return gets state from
|
||||
* the main stack. Execution uses MSP after return.
|
||||
*/
|
||||
|
||||
#define EXC_RETURN_HANDLER 0xfffffff1
|
||||
|
||||
/* EXC_RETURN_PRIVTHR: Return to privileged thread mode. Exception return gets
|
||||
* state from the main stack. Execution uses MSP after return.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_ARMV8M_LAZYFPU) && defined(CONFIG_ARCH_FPU)
|
||||
# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE)
|
||||
#else
|
||||
# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \
|
||||
EXC_RETURN_THREAD_MODE)
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN_UNPRIVTHR: Return to unprivileged thread mode. Exception return gets
|
||||
* state from the process stack. Execution uses PSP after return.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_ARMV8M_LAZYFPU) && defined(CONFIG_ARCH_FPU)
|
||||
# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE | \
|
||||
EXC_RETURN_PROCESS_STACK)
|
||||
#else
|
||||
# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \
|
||||
EXC_RETURN_THREAD_MODE | EXC_RETURN_PROCESS_STACK)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
************************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_EXC_RETURN_H */
|
||||
Executable
+167
@@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/fpb.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_ARM_SRC_ARMV8-M_FPB_H
|
||||
#define __ARCH_ARM_SRC_ARMV8-M_FPB_H
|
||||
|
||||
/******************************************************************************
|
||||
* Pre-processor Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Flash Patch and Breakpoint Unit FPB ***************************************/
|
||||
|
||||
/* FPB Register Base Address *************************************************/
|
||||
|
||||
#define FPB_BASE 0xe0002000
|
||||
|
||||
/* FPB Register Offsets *******************************************************/
|
||||
|
||||
#define FPB_CTRL_OFFSET 0x0000 /* Control */
|
||||
#define FPB_REMAP_OFFSET 0x0004 /* Remap */
|
||||
#define FPB_COMP0_OFFSET 0x0008 /* Comparator 0 */
|
||||
#define FPB_COMP1_OFFSET 0x000c /* Comparator 1 */
|
||||
#define FPB_COMP2_OFFSET 0x0010 /* Comparator 2 */
|
||||
#define FPB_COMP3_OFFSET 0x0014 /* Comparator 3 */
|
||||
#define FPB_COMP4_OFFSET 0x0018 /* Comparator 4 */
|
||||
#define FPB_COMP5_OFFSET 0x001C /* Comparator 5 */
|
||||
#define FPB_COMP6_OFFSET 0x0020 /* Comparator 6 */
|
||||
#define FPB_COMP7_OFFSET 0x0024 /* Comparator 7 */
|
||||
|
||||
/* FPB Register Addresses *****************************************************/
|
||||
|
||||
#define FPB_CTRL (FPB_BASE + FPB_CTRL_OFFSET)
|
||||
#define FPB_REMAP (FPB_BASE + FPB_REMAP_OFFSET)
|
||||
#define FPB_COMP0 (FPB_BASE + FPB_COMP0_OFFSET)
|
||||
#define FPB_COMP1 (FPB_BASE + FPB_COMP1_OFFSET)
|
||||
#define FPB_COMP2 (FPB_BASE + FPB_COMP2_OFFSET)
|
||||
#define FPB_COMP3 (FPB_BASE + FPB_COMP3_OFFSET)
|
||||
#define FPB_COMP4 (FPB_BASE + FPB_COMP4_OFFSET)
|
||||
#define FPB_COMP5 (FPB_BASE + FPB_COMP5_OFFSET)
|
||||
#define FPB_COMP6 (FPB_BASE + FPB_COMP6_OFFSET)
|
||||
#define FPB_COMP7 (FPB_BASE + FPB_COMP7_OFFSET
|
||||
|
||||
/* FPB Register Bitfield Definitions ******************************************/
|
||||
|
||||
/* FPB_CTRL */
|
||||
|
||||
/* NUM_CODE2
|
||||
*
|
||||
* Number of full banks of code comparators, sixteen comparators per bank.
|
||||
* Where less than sixteen code comparators are provided, the bank count is
|
||||
* zero, and the number present indicated by NUM_CODE1. This read only field
|
||||
* contains 3'b000 to indicate 0 banks for Cortex-M processor.
|
||||
*/
|
||||
|
||||
#define FPB_CTRL_NUM_CODE2_SHIFT 12
|
||||
#define FPB_CTRL_NUM_CODE2_MASK 0x00003000
|
||||
|
||||
/* NUM_LIT
|
||||
*
|
||||
* Number of literal slots field.
|
||||
*
|
||||
* 0: No literal slots
|
||||
* 2: Two literal slots
|
||||
*/
|
||||
|
||||
#define FPB_CTRL_NUM_LIT_SHIFT 8
|
||||
#define FPB_CTRL_NUM_LIT_MASK 0x00000f00
|
||||
|
||||
/* NUM_CODE1
|
||||
*
|
||||
* Number of code slots field.
|
||||
*
|
||||
* 0: No code slots
|
||||
* 2: Two code slots
|
||||
* 6: Six code slots
|
||||
*/
|
||||
|
||||
#define FPB_CTRL_NUM_CODE1_SHIFT 4
|
||||
#define FPB_CTRL_NUM_CODE1_MASK 0x000000f0
|
||||
|
||||
/* KEY
|
||||
*
|
||||
* Key field. In order to write to this register, this bit-field must be
|
||||
* written to '1'. This bit always reads 0.
|
||||
*/
|
||||
|
||||
#define FPB_CTRL_KEY_SHIFT 1
|
||||
#define FPB_CTRL_KEY_MASK 0x00000002
|
||||
# define FPB_CTRL_KEY 0x00000002
|
||||
|
||||
/* ENABLE
|
||||
*
|
||||
* Flash patch unit enable bit
|
||||
*
|
||||
* 0: Flash patch unit disabled
|
||||
* 1: Flash patch unit enabled
|
||||
*/
|
||||
|
||||
#define FPB_CTRL_ENABLE_SHIFT 0
|
||||
#define FPB_CTRL_ENABLE_MASK 0x00000001
|
||||
# define FPB_CTRL_ENABLE 0x00000001
|
||||
|
||||
/* FPB_REMAP */
|
||||
|
||||
/* REMAP
|
||||
*
|
||||
* Remap base address field.
|
||||
*/
|
||||
|
||||
#define FPB_REMAP_REMAP_SHIFT 5
|
||||
#define FPB_REMAP_REMAP_MASK 0x1fffffe0
|
||||
|
||||
/* FPB_COMP0 - FPB_COMP7 */
|
||||
|
||||
/* REPLACE
|
||||
*
|
||||
* This selects what happens when the COMP address is matched. Address
|
||||
* remapping only takes place for the 0x0 setting.
|
||||
*
|
||||
* 0: Remap to remap address. See REMAP.REMAP
|
||||
* 1: Set BKPT on lower halfword, upper is unaffected
|
||||
* 2: Set BKPT on upper halfword, lower is unaffected
|
||||
* 3: Set BKPT on both lower and upper halfwords.
|
||||
*/
|
||||
|
||||
#define FPB_COMP0_REPLACE_SHIFT 30
|
||||
#define FPB_COMP0_REPLACE_MASK 0xc0000000
|
||||
|
||||
/* COMP
|
||||
*
|
||||
* Comparison address.
|
||||
*/
|
||||
|
||||
#define FPB_COMP0_COMP_SHIFT 2
|
||||
#define FPB_COMP0_COMP_MASK 0x1ffffffc
|
||||
|
||||
/* ENABLE
|
||||
*
|
||||
* Compare and remap enable comparator. CTRL.ENABLE must also be set to
|
||||
* enable comparisons.
|
||||
*
|
||||
* 0: Compare and remap for comparator 0 disabled
|
||||
* 1: Compare and remap for comparator 0 enabled
|
||||
*/
|
||||
|
||||
#define FPB_COMP0_ENABLE_MASK 0x00000001
|
||||
#define FPB_COMP0_ENABLE_SHIFT 0
|
||||
# define FPB_COMP0_ENABLE 0x00000001
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8-M_FPB_H */
|
||||
Executable
+184
@@ -0,0 +1,184 @@
|
||||
/***********************************************************************************************
|
||||
* arch/arm/src/armv8-m/itm.h
|
||||
*
|
||||
* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved.
|
||||
* Author: Pierre-noel Bouteville <pnb990@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
***********************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_ARMV8_M_ITM_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_ITM_H
|
||||
|
||||
/***********************************************************************************************
|
||||
* Included Files
|
||||
***********************************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/***********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
***********************************************************************************************/
|
||||
|
||||
/* Instrumentation Trace Macrocell Register (ITM) Definitions **********************************/
|
||||
/* ITM Register Base Address *******************************************************************/
|
||||
|
||||
#define ITM_BASE (0xe0000000ul)
|
||||
|
||||
/* ITM Register Addresses **********************************************************************/
|
||||
|
||||
#define ITM_PORT(i) (ITM_BASE + (i * 4)) /* Stimulus Port 32-bit */
|
||||
#define ITM_TER (ITM_BASE + 0x0e00) /* Trace Enable Register */
|
||||
#define ITM_TPR (ITM_BASE + 0x0e40) /* Trace Privilege Register */
|
||||
#define ITM_TCR (ITM_BASE + 0x0e80) /* Trace Control Register */
|
||||
#define ITM_IWR (ITM_BASE + 0x0ef8) /* Integration Write Register */
|
||||
#define ITM_IRR (ITM_BASE + 0x0efc) /* Integration Read Register */
|
||||
#define ITM_IMCR (ITM_BASE + 0x0f00) /* Integration Mode Control Register */
|
||||
#define ITM_LAR (ITM_BASE + 0x0fb0) /* Lock Access Register */
|
||||
#define ITM_LSR (ITM_BASE + 0x0fb4) /* Lock Status Register */
|
||||
#define ITM_PID4 (ITM_BASE + 0x0fd0) /* Peripheral Identification Register #4 */
|
||||
#define ITM_PID5 (ITM_BASE + 0x0fd4) /* Peripheral Identification Register #5 */
|
||||
#define ITM_PID6 (ITM_BASE + 0x0fd8) /* Peripheral Identification Register #6 */
|
||||
#define ITM_PID7 (ITM_BASE + 0x0fdc) /* Peripheral Identification Register #7 */
|
||||
#define ITM_PID0 (ITM_BASE + 0x0fe0) /* Peripheral Identification Register #0 */
|
||||
#define ITM_PID1 (ITM_BASE + 0x0fe4) /* Peripheral Identification Register #1 */
|
||||
#define ITM_PID2 (ITM_BASE + 0x0fe8) /* Peripheral Identification Register #2 */
|
||||
#define ITM_PID3 (ITM_BASE + 0x0fec) /* Peripheral Identification Register #3 */
|
||||
#define ITM_CID0 (ITM_BASE + 0x0ff0) /* Component Identification Register #0 */
|
||||
#define ITM_CID1 (ITM_BASE + 0x0ff4) /* Component Identification Register #1 */
|
||||
#define ITM_CID2 (ITM_BASE + 0x0ff8) /* Component Identification Register #2 */
|
||||
#define ITM_CID3 (ITM_BASE + 0x0ffc) /* Component Identification Register #3 */
|
||||
|
||||
/* ITM Register Bit Field Definitions **********************************************************/
|
||||
|
||||
/* ITM TPR */
|
||||
|
||||
#define ITM_TPR_PRIVMASK_SHIFT 0
|
||||
#define ITM_TPR_PRIVMASK_MASK (0xful << ITM_TPR_PRIVMASK_SHIFT)
|
||||
|
||||
/* ITM TCR */
|
||||
|
||||
#define ITM_TCR_BUSY_SHIFT 23
|
||||
#define ITM_TCR_BUSY_MASK (1ul << ITM_TCR_BUSY_SHIFT)
|
||||
#define ITM_TCR_TraceBusID_SHIFT 16
|
||||
#define ITM_TCR_TraceBusID_MASK (0x7ful << ITM_TCR_TraceBusID_SHIFT)
|
||||
#define ITM_TCR_GTSFREQ_SHIFT 10
|
||||
#define ITM_TCR_GTSFREQ_MASK (3ul << ITM_TCR_GTSFREQ_SHIFT)
|
||||
#define ITM_TCR_TSPrescale_SHIFT 8
|
||||
#define ITM_TCR_TSPrescale_MASK (3ul << ITM_TCR_TSPrescale_SHIFT)
|
||||
#define ITM_TCR_SWOENA_SHIFT 4
|
||||
#define ITM_TCR_SWOENA_MASK (1ul << ITM_TCR_SWOENA_SHIFT)
|
||||
#define ITM_TCR_DWTENA_SHIFT 3
|
||||
#define ITM_TCR_DWTENA_MASK (1ul << ITM_TCR_DWTENA_SHIFT)
|
||||
#define ITM_TCR_SYNCENA_SHIFT 2
|
||||
#define ITM_TCR_SYNCENA_MASK (1ul << ITM_TCR_SYNCENA_SHIFT)
|
||||
#define ITM_TCR_TSENA_SHIFT 1
|
||||
#define ITM_TCR_TSENA_MASK (1ul << ITM_TCR_TSENA_SHIFT)
|
||||
#define ITM_TCR_ITMENA_SHIFT 0
|
||||
#define ITM_TCR_ITMENA_MASK (1ul << ITM_TCR_ITMENA_SHIFT)
|
||||
|
||||
/* ITM IWR */
|
||||
|
||||
#define ITM_IWR_ATVALIDM_SHIFT 0
|
||||
#define ITM_IWR_ATVALIDM_MASK (1ul << ITM_IWR_ATVALIDM_SHIFT)
|
||||
|
||||
/* ITM IRR */
|
||||
|
||||
#define ITM_IRR_ATREADYM_SHIFT 0
|
||||
#define ITM_IRR_ATREADYM_MASK (1ul << ITM_IRR_ATREADYM_SHIFT)
|
||||
|
||||
/* ITM IMCR */
|
||||
|
||||
#define ITM_IMCR_INTEGRATION_SHIFT 0
|
||||
#define ITM_IMCR_INTEGRATION_MASK (1ul << ITM_IMCR_INTEGRATION_SHIFT)
|
||||
|
||||
/* ITM LSR */
|
||||
|
||||
#define ITM_LSR_ByteAcc_SHIFT 2
|
||||
#define ITM_LSR_ByteAcc_MASK (1ul << ITM_LSR_ByteAcc_SHIFT)
|
||||
#define ITM_LSR_Access_SHIFT 1
|
||||
#define ITM_LSR_Access_MASK (1ul << ITM_LSR_Access_SHIFT)
|
||||
#define ITM_LSR_Present_SHIFT 0
|
||||
#define ITM_LSR_Present_MASK (1ul << ITM_LSR_Present_SHIFT)
|
||||
|
||||
/* Value identifying g_itm_rxbuffer is ready for next character. */
|
||||
|
||||
#define ITM_RXBUFFER_EMPTY 0x5aa55aa5
|
||||
|
||||
/***********************************************************************************************
|
||||
* Public Data
|
||||
***********************************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern volatile int32_t g_itm_rxbuffer; /* External variable to receive characters. */
|
||||
|
||||
/***********************************************************************************************
|
||||
* Public Function Prototypes
|
||||
***********************************************************************************************/
|
||||
|
||||
uint32_t itm_sendchar(uint32_t ch);
|
||||
int32_t itm_receivechar(void);
|
||||
int32_t itm_checkchar(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_ITM_H */
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/itm_syslog.h
|
||||
*
|
||||
* Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved.
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Authors: Pierre-noel Bouteville <pnb990@gmail.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_ARMV8_M_ITM_SYSLOG_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_ITM_SYSLOG_H
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_syslog_initialize
|
||||
*
|
||||
* Description:
|
||||
* Performs ARM-specific initialize for the ITM SYSLOG functions.
|
||||
* Additional, board specific logic may be required to:
|
||||
*
|
||||
* - Enable/configured serial wire output pins
|
||||
* - Enable debug clocking.
|
||||
*
|
||||
* Those operations must be performed by MCU-specific logic before this
|
||||
* function is called.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARMV8M_ITMSYSLOG
|
||||
void itm_syslog_initialize(void);
|
||||
#else
|
||||
# define itm_syslog_initialize()
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_ITM_SYSLOG_H */
|
||||
Executable
+446
@@ -0,0 +1,446 @@
|
||||
/*********************************************************************************************
|
||||
* arch/arm/src/armv8-m/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_ARM_SRC_ARMV8M_MPU_H
|
||||
#define __ARCH_ARM_SRC_ARMV8M_MPU_H
|
||||
|
||||
/*********************************************************************************************
|
||||
* Included Files
|
||||
*********************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <sys/types.h>
|
||||
# include <stdint.h>
|
||||
# include <stdbool.h>
|
||||
# include <assert.h>
|
||||
# include <debug.h>
|
||||
|
||||
# include "up_arch.h"
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*********************************************************************************************/
|
||||
|
||||
/* MPU Register Addresses */
|
||||
|
||||
#define MPU_TYPE 0xe000ed90 /* MPU Type Register */
|
||||
#define MPU_CTRL 0xe000ed94 /* MPU Control Register */
|
||||
#define MPU_RNR 0xe000ed98 /* MPU Region Number Register */
|
||||
#define MPU_RBAR 0xe000ed9c /* MPU Region Base Address Register */
|
||||
#define MPU_RASR 0xe000eda0 /* MPU Region Attribute and Size Register */
|
||||
|
||||
#define MPU_RBAR_A1 0xe000eda4 /* MPU alias registers */
|
||||
#define MPU_RASR_A1 0xe000eda8
|
||||
#define MPU_RBAR_A2 0xe000edac
|
||||
#define MPU_RASR_A2 0xe000edb0
|
||||
#define MPU_RBAR_A3 0xe000edb4
|
||||
#define MPU_RASR_A3 0xe000edb8
|
||||
|
||||
/* MPU Type Register Bit Definitions */
|
||||
|
||||
#define MPU_TYPE_SEPARATE (1 << 0) /* Bit 0: 0:unified or 1:separate memory maps */
|
||||
#define MPU_TYPE_DREGION_SHIFT (8) /* Bits 8-15: Number MPU data regions */
|
||||
#define MPU_TYPE_DREGION_MASK (0xff << MPU_TYPE_DREGION_SHIFT)
|
||||
#define MPU_TYPE_IREGION_SHIFT (16) /* Bits 16-23: Number MPU instruction regions */
|
||||
#define MPU_TYPE_IREGION_MASK (0xff << MPU_TYPE_IREGION_SHIFT)
|
||||
|
||||
/* MPU Control Register Bit Definitions */
|
||||
|
||||
#define MPU_CTRL_ENABLE (1 << 0) /* Bit 0: Enable the MPU */
|
||||
#define MPU_CTRL_HFNMIENA (1 << 1) /* Bit 1: Enable MPU during hard fault, NMI, and FAULTMAS */
|
||||
#define MPU_CTRL_PRIVDEFENA (1 << 2) /* Bit 2: Enable privileged access to default memory map */
|
||||
|
||||
/* MPU Region Number Register Bit Definitions */
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_NREGIONS) && defined(CONFIG_ARM_MPU)
|
||||
# if CONFIG_ARM_MPU_NREGIONS <= 8
|
||||
# define MPU_RNR_MASK (0x00000007)
|
||||
# elif CONFIG_ARM_MPU_NREGIONS <= 16
|
||||
# define MPU_RNR_MASK (0x0000000f)
|
||||
# elif CONFIG_ARM_MPU_NREGIONS <= 32
|
||||
# define MPU_RNR_MASK (0x0000001f)
|
||||
# else
|
||||
# error "FIXME: Unsupported number of MPU regions"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MPU Region Base Address Register Bit Definitions */
|
||||
|
||||
#define MPU_RBAR_REGION_SHIFT (0) /* Bits 0-3: MPU region */
|
||||
#define MPU_RBAR_REGION_MASK (15 << MPU_RBAR_REGION_SHIFT)
|
||||
#define MPU_RBAR_VALID (1 << 4) /* Bit 4: MPU Region Number valid */
|
||||
#define MPU_RBAR_ADDR_MASK 0xffffffe0 /* Bits N-31: Region base addrese */
|
||||
|
||||
/* MPU Region Attributes and Size Register Bit Definitions */
|
||||
|
||||
#define MPU_RASR_ENABLE (1 << 0) /* Bit 0: Region enable */
|
||||
#define MPU_RASR_SIZE_SHIFT (1) /* Bits 1-5: Size of the MPU protection region */
|
||||
#define MPU_RASR_SIZE_MASK (31 << MPU_RASR_SIZE_SHIFT)
|
||||
# define MPU_RASR_SIZE_LOG2(n) ((n-1) << MPU_RASR_SIZE_SHIFT)
|
||||
#define MPU_RASR_SRD_SHIFT (8) /* Bits 8-15: Subregion disable */
|
||||
#define MPU_RASR_SRD_MASK (0xff << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_0 (0x01 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_1 (0x02 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_2 (0x04 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_3 (0x08 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_4 (0x10 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_5 (0x20 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_6 (0x40 << MPU_RASR_SRD_SHIFT)
|
||||
# define MPU_RASR_SRD_7 (0x80 << MPU_RASR_SRD_SHIFT)
|
||||
#define MPU_RASR_ATTR_SHIFT (16) /* Bits 16-31: MPU Region Attribute field */
|
||||
#define MPU_RASR_ATTR_MASK (0xffff << MPU_RASR_ATTR_SHIFT)
|
||||
# define MPU_RASR_B (1 << 16) /* Bit 16: Bufferable */
|
||||
# define MPU_RASR_C (1 << 17) /* Bit 17: Cacheable */
|
||||
# define MPU_RASR_S (1 << 18) /* Bit 18: Shareable */
|
||||
# define MPU_RASR_TEX_SHIFT (19) /* Bits 19-21: TEX Address Permission */
|
||||
# define MPU_RASR_TEX_MASK (7 << MPU_RASR_TEX_SHIFT)
|
||||
# define MPU_RASR_TEX_SO (0 << MPU_RASR_TEX_SHIFT) /* Strongly Ordered */
|
||||
# define MPU_RASR_TEX_NOR (1 << MPU_RASR_TEX_SHIFT) /* Normal */
|
||||
# define MPU_RASR_TEX_DEV (2 << MPU_RASR_TEX_SHIFT) /* Device */
|
||||
# define MPU_RASR_TEX_BB(bb) ((4|(bb)) << MPU_RASR_TEX_SHIFT)
|
||||
# define MPU_RASR_CP_NC (0) /* Non-cacheable */
|
||||
# define MPU_RASR_CP_WBRA (1) /* Write back, write and Read- Allocate */
|
||||
# define MPU_RASR_CP_WT (2) /* Write through, no Write-Allocate */
|
||||
# define MPU_RASR_CP_WB (4) /* Write back, no Write-Allocate */
|
||||
# define MPU_RASR_AP_SHIFT (24) /* Bits 24-26: Access permission */
|
||||
# define MPU_RASR_AP_MASK (7 << MPU_RASR_AP_SHIFT)
|
||||
# define MPU_RASR_AP_NONO (0 << MPU_RASR_AP_SHIFT) /* P:None U:None */
|
||||
# define MPU_RASR_AP_RWNO (1 << MPU_RASR_AP_SHIFT) /* P:RW U:None */
|
||||
# define MPU_RASR_AP_RWRO (2 << MPU_RASR_AP_SHIFT) /* P:RW U:RO */
|
||||
# define MPU_RASR_AP_RWRW (3 << MPU_RASR_AP_SHIFT) /* P:RW U:RW */
|
||||
# define MPU_RASR_AP_RONO (5 << MPU_RASR_AP_SHIFT) /* P:RO U:None */
|
||||
# define MPU_RASR_AP_RORO (6 << MPU_RASR_AP_SHIFT) /* P:RO U:RO */
|
||||
# define MPU_RASR_XN (1 << 28) /* Bit 28: Instruction access disable */
|
||||
|
||||
#ifdef CONFIG_ARM_MPU
|
||||
|
||||
/*********************************************************************************************
|
||||
* Public Function Prototypes
|
||||
*********************************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_log2regionceil
|
||||
*
|
||||
* Description:
|
||||
* Determine the smallest value of l2size (log base 2 size) such that the
|
||||
* following is true:
|
||||
*
|
||||
* size <= (1 << l2size)
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionceil(size_t size);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_log2regionfloor
|
||||
*
|
||||
* Description:
|
||||
* Determine the largest value of l2size (log base 2 size) such that the
|
||||
* following is true:
|
||||
*
|
||||
* size >= (1 << l2size)
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionfloor(size_t size);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_subregion
|
||||
*
|
||||
* Description:
|
||||
* Given (1) the offset to the beginning of valid data, (2) the size of the
|
||||
* memory to be mapped and (2) the log2 size of the mapping to use,
|
||||
* determine the minimal sub-region set to span that memory region.
|
||||
*
|
||||
* Assumption:
|
||||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_control
|
||||
*
|
||||
* Description:
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
void mpu_control(bool enable, bool hfnmiena, bool privdefena);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
void mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Inline Functions
|
||||
*********************************************************************************************/
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_showtype
|
||||
*
|
||||
* Description:
|
||||
* Show the characteristics of the MPU
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SCHED_INFO
|
||||
# define mpu_showtype() \
|
||||
do \
|
||||
{ \
|
||||
uint32_t regval = getreg32(MPU_TYPE); \
|
||||
sinfo("%s MPU Regions: data=%d instr=%d\n", \
|
||||
(regval & MPU_TYPE_SEPARATE) != 0 ? "Separate" : "Unified", \
|
||||
(regval & MPU_TYPE_DREGION_MASK) >> MPU_TYPE_DREGION_SHIFT, \
|
||||
(regval & MPU_TYPE_IREGION_MASK) >> MPU_TYPE_IREGION_SHIFT); \
|
||||
} while (0)
|
||||
#else
|
||||
# define mpu_showtype() do { } while (0)
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_priv_stronglyordered
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_priv_stronglyordered(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
/* Not Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_user_flash
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for user program flash
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_user_flash(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Not Shareable */ \
|
||||
MPU_RASR_AP_RORO /* P:RO U:RO */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_priv_flash
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged program flash
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_priv_flash(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Not Shareable */ \
|
||||
MPU_RASR_AP_RONO /* P:RO U:None */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_user_intsram
|
||||
*
|
||||
* Description:
|
||||
* Configure a region as user internal SRAM
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_user_intsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW /* P:RW U:RW */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_priv_intsram
|
||||
*
|
||||
* Description:
|
||||
* Configure a region as privileged internal SRAM
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_priv_intsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size,\
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_user_extsram
|
||||
*
|
||||
* Description:
|
||||
* Configure a region as user external SRAM
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_user_extsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW /* P:RW U:RW */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_priv_extsram
|
||||
*
|
||||
* Description:
|
||||
* Configure a region as privileged external SRAM
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_priv_extsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_peripheral
|
||||
*
|
||||
* Description:
|
||||
* Configure a region as privileged peripheral address space
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_peripheral(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_DEV | /* Device */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO | /* P:RW U:None */ \
|
||||
MPU_RASR_XN /* No Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
/*********************************************************************************************
|
||||
* Name: mpu_user_peripheral
|
||||
*
|
||||
* Description:
|
||||
* Configure a region as user peripheral address space
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#define mpu_user_peripheral(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_DEV | /* Device */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW | /* P:RW U:RW */ \
|
||||
MPU_RASR_XN /* No Instruction access */); \
|
||||
} while (0)
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* CONFIG_ARM_MPU */
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8M_MPU_H */
|
||||
Executable
+696
File diff suppressed because it is too large
Load Diff
Executable
+72
@@ -0,0 +1,72 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/psr.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_ARM_SRC_COMMON_ARMV8_M_PSR_H
|
||||
#define __ARCH_ARM_SRC_COMMON_ARMV8_M_PSR_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* Application Program Status Register (APSR) */
|
||||
|
||||
#define ARMV8M_APSR_Q (1 << 27) /* Bit 27: Sticky saturation flag */
|
||||
#define ARMV8M_APSR_V (1 << 28) /* Bit 28: Overflow flag */
|
||||
#define ARMV8M_APSR_C (1 << 29) /* Bit 29: Carry/borrow flag */
|
||||
#define ARMV8M_APSR_Z (1 << 30) /* Bit 30: Zero flag */
|
||||
#define ARMV8M_APSR_N (1 << 31) /* Bit 31: Negative, less than flag */
|
||||
|
||||
/* Interrupt Program Status Register (IPSR) */
|
||||
|
||||
#define ARMV8M_IPSR_ISR_SHIFT 0 /* Bits 8-0: ISR number */
|
||||
#define ARMV8M_IPSR_ISR_MASK (0x1ff << ARMV8M_IPSR_ISR_SHIFT)
|
||||
|
||||
/* Execution PSR Register (EPSR) */
|
||||
|
||||
#define ARMV8M_EPSR_ICIIT1_SHIFT 10 /* Bits 15-10: Interrupt-Continuable-Instruction/If-Then bits */
|
||||
#define ARMV8M_EPSR_ICIIT1_MASK (3 << ARMV8M_EPSR_ICIIT1_SHIFT)
|
||||
#define ARMV8M_EPSR_T (1 << 24) /* Bit 24: T-bit */
|
||||
#define ARMV8M_EPSR_ICIIT2_SHIFT 25 /* Bits 26-25: Interrupt-Continuable-Instruction/If-Then bits */
|
||||
#define ARMV8M_EPSR_ICIIT2_MASK (3 << ARMV8M_EPSR_ICIIT2_SHIFT)
|
||||
|
||||
/* Save xPSR bits */
|
||||
|
||||
#define ARMV8M_XPSR_ISR_SHIFT ARMV8M_IPSR_ISR_SHIFT
|
||||
#define ARMV8M_XPSR_ISR_MASK ARMV8M_IPSR_ISR_MASK
|
||||
#define ARMV8M_XPSR_ICIIT1_SHIFT ARMV8M_EPSR_ICIIT1_SHIFT/
|
||||
#define ARMV8M_XPSR_ICIIT1_MASK ARMV8M_EPSR_ICIIT1_MASK
|
||||
#define ARMV8M_XPSR_T ARMV8M_EPSR_T
|
||||
#define ARMV8M_XPSR_ICIIT2_SHIFT ARMV8M_EPSR_ICIIT2_SHIFT
|
||||
#define ARMV8M_XPSR_ICIIT2_MASK ARMV8M_EPSR_ICIIT2_MASK
|
||||
#define ARMV8M_XPSR_Q ARMV8M_APSR_Q
|
||||
#define ARMV8M_XPSR_V ARMV8M_APSR_V
|
||||
#define ARMV8M_XPSR_C ARMV8M_APSR_C
|
||||
#define ARMV8M_XPSR_Z ARMV8M_APSR_Z
|
||||
#define ARMV8M_XPSR_N ARMV8M_APSR_N
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
************************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_COMMON_ARMV8_M_PSR_H */
|
||||
Executable
+103
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/ram_vectors.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_ARM_SRC_COMMON_ARMV8_M_RAM_VECTORS_H
|
||||
#define __ARCH_ARM_SRC_COMMON_ARMV8_M_RAM_VECTORS_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "chip.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMVECTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the size of the vector table (in 4-byte entries). This size
|
||||
* includes the (1) the peripheral interrupts, (2) space for 15 Cortex-M
|
||||
* exceptions, and (3) IDLE stack pointer which lies at the beginning of the
|
||||
* table.
|
||||
*/
|
||||
|
||||
#define ARMV8M_VECTAB_SIZE (ARMV8M_PERIPHERAL_INTERRUPTS + 16)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* If CONFIG_ARCH_RAMVECTORS is defined, then the ARM logic must provide
|
||||
* ARM-specific implementations of irq_initialize(), irq_attach(), and
|
||||
* irq_dispatch. In this case, it is also assumed that the ARM vector
|
||||
* table resides in RAM, has the name up_ram_vectors, and has been
|
||||
* properly positioned and aligned in memory by the linker script.
|
||||
*
|
||||
* REVISIT: Can this alignment requirement vary from core-to-core? Yes, it
|
||||
* depends on the number of vectors supported by the MCU. The safest thing
|
||||
* to do is to put the vector table at the beginning of RAM in order toforce
|
||||
* the highest alignment possible.
|
||||
*/
|
||||
|
||||
extern up_vector_t g_ram_vectors[ARMV8M_VECTAB_SIZE]
|
||||
__attribute__ ((section (".ram_vectors"), aligned (128)));
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ramvec_initialize
|
||||
*
|
||||
* Description:
|
||||
* Copy vectors to RAM an configure the NVIC to use the RAM vectors.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_ramvec_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: exception_common
|
||||
*
|
||||
* Description:
|
||||
* This is the default, common vector handling entrypoint.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void exception_common(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ramvec_attach
|
||||
*
|
||||
* Description:
|
||||
* Configure the ram vector table so that IRQ number 'irq' will be
|
||||
* dipatched by hardware to 'vector'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_ramvec_attach(int irq, up_vector_t vector);
|
||||
|
||||
#endif /* CONFIG_ARCH_RAMVECTORS */
|
||||
#endif /* __ARCH_ARM_SRC_COMMON_ARMV8_M_RAM_VECTORS_H */
|
||||
Executable
+131
@@ -0,0 +1,131 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/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_ARM_SRC_ARMV8_M_SVCALL_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_SVCALL_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
# include <syscall.h>
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* 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
|
||||
|
||||
/* Cortex-M system calls ************************************************************/
|
||||
|
||||
/* SYS call 0:
|
||||
*
|
||||
* int up_saveusercontext(uint32_t *saveregs);
|
||||
*/
|
||||
|
||||
#define SYS_save_context (0)
|
||||
|
||||
/* SYS call 1:
|
||||
*
|
||||
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
|
||||
*/
|
||||
|
||||
#define SYS_restore_context (1)
|
||||
|
||||
/* SYS call 2:
|
||||
*
|
||||
* void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
|
||||
*/
|
||||
|
||||
#define SYS_switch_context (2)
|
||||
|
||||
#ifdef CONFIG_LIB_SYSCALL
|
||||
/* SYS call 3:
|
||||
*
|
||||
* void up_syscall_return(void);
|
||||
*/
|
||||
|
||||
#define SYS_syscall_return (3)
|
||||
|
||||
#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 (4)
|
||||
|
||||
/* SYS call 5:
|
||||
*
|
||||
* void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
|
||||
* noreturn_function
|
||||
*/
|
||||
|
||||
#define SYS_pthread_start (5)
|
||||
|
||||
/* SYS call 6:
|
||||
*
|
||||
* void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info,
|
||||
* FAR void *ucontext);
|
||||
*/
|
||||
|
||||
#define SYS_signal_handler (6)
|
||||
|
||||
/* SYS call 7:
|
||||
*
|
||||
* void signal_handler_return(void);
|
||||
*/
|
||||
|
||||
#define SYS_signal_handler_return (7)
|
||||
|
||||
#endif /* CONFIG_BUILD_PROTECTED */
|
||||
#endif /* CONFIG_LIB_SYSCALL */
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
************************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_SVCALL_H */
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/systick.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_ARM_SRC_ARMV8_M_SYSTICK_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_SYSTICK_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/timers/timer.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: systick_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function initialize SYSTICK hardware module which is part of NVIC
|
||||
* and return an instance of a "lower half" timer interface.
|
||||
*
|
||||
* Input parameters:
|
||||
* coreclk - false if SYSTICK working clock come from the external
|
||||
* reference clock, otherwise true.
|
||||
* freq - The clock frequency in Hz. If freq is zero, calculate the value
|
||||
* from NVIC_SYSTICK_CALIB register.
|
||||
* minor - The timer driver minor number, skip the registration if minor
|
||||
* < 0.
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL timer_lowerhalf_s is returned to the caller.
|
||||
* In the event of any failure, a NULL value is returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARMV8M_SYSTICK
|
||||
struct timer_lowerhalf_s *systick_initialize(bool coreclk, unsigned int freq,
|
||||
int minor);
|
||||
#else
|
||||
# define systick_initialize(coreclk, freq, minor) NULL
|
||||
#endif /* CONFIG_ARMV8M_SYSTICK */
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_SYSTICK_H */
|
||||
Executable
+200
@@ -0,0 +1,200 @@
|
||||
/***********************************************************************************************
|
||||
* arch/arm/src/armv8-m/tpi.h
|
||||
*
|
||||
* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved.
|
||||
* Author: Pierre-noel Bouteville <pnb990@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
***********************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_ARMV8_M_TPI_H
|
||||
#define __ARCH_ARM_SRC_ARMV8_M_TPI_H
|
||||
|
||||
/***********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
***********************************************************************************************/
|
||||
|
||||
/* Trace Port Interface Register (TPI) Definitions *********************************************/
|
||||
|
||||
/* TPI Register Base Address *******************************************************************/
|
||||
|
||||
#define TPI_BASE (0xe0040000ul)
|
||||
|
||||
/* TPI Register Addresses **********************************************************************/
|
||||
|
||||
#define TPI_SSPSR (TPI_BASE + 0x0000) /* Supported Parallel Port Size Register */
|
||||
#define TPI_CSPSR (TPI_BASE + 0x0004) /* Current Parallel Port Size Register */
|
||||
#define TPI_ACPR (TPI_BASE + 0x0010) /* Asynchronous Clock Prescaler Register */
|
||||
#define TPI_SPPR (TPI_BASE + 0x00f0) /* Selected Pin Protocol Register */
|
||||
#define TPI_FFSR (TPI_BASE + 0x0300) /* Formatter and Flush Status Register */
|
||||
#define TPI_FFCR (TPI_BASE + 0x0304) /* Formatter and Flush Control Register */
|
||||
#define TPI_FSCR (TPI_BASE + 0x0308) /* Formatter Synchronization Counter Register */
|
||||
#define TPI_TRIGGER (TPI_BASE + 0x0ee8) /* TRIGGER */
|
||||
#define TPI_FIFO0 (TPI_BASE + 0x0eec) /* Integration ETM Data */
|
||||
#define TPI_ITATBCTR2 (TPI_BASE + 0x0ef0) /* ITATBCTR2 */
|
||||
#define TPI_ITATBCTR0 (TPI_BASE + 0x0ef8) /* ITATBCTR0 */
|
||||
#define TPI_FIFO1 (TPI_BASE + 0x0efc) /* Integration ITM Data */
|
||||
#define TPI_ITCTRL (TPI_BASE + 0x0f00) /* Integration Mode Control */
|
||||
#define TPI_CLAIMSET (TPI_BASE + 0x0fa0) /* Claim tag set */
|
||||
#define TPI_CLAIMCLR (TPI_BASE + 0x0fa4) /* Claim tag clear */
|
||||
#define TPI_DEVID (TPI_BASE + 0x0fc8) /* TPIU_DEVID */
|
||||
#define TPI_DEVTYPE (TPI_BASE + 0x0fcc) /* TPIU_DEVTYPE */
|
||||
|
||||
/* TPI Register Bit Field Definitions **********************************************************/
|
||||
|
||||
/* TPI ACPR */
|
||||
|
||||
#define TPI_ACPR_PRESCALER_SHIFT 0
|
||||
#define TPI_ACPR_PRESCALER_MASK (0x1ffful << TPI_ACPR_PRESCALER_SHIFT)
|
||||
|
||||
/* TPI SPPR */
|
||||
|
||||
#define TPI_SPPR_TXMODE_SHIFT 0
|
||||
#define TPI_SPPR_TXMODE_MASK (0x3ul << TPI_SPPR_TXMODE_SHIFT)
|
||||
|
||||
/* TPI FFSR */
|
||||
|
||||
#define TPI_FFSR_FtNonStop_SHIFT 3
|
||||
#define TPI_FFSR_FtNonStop_MASK (0x1ul << TPI_FFSR_FtNonStop_SHIFT)
|
||||
#define TPI_FFSR_TCPresent_SHIFT 2
|
||||
#define TPI_FFSR_TCPresent_MASK (0x1ul << TPI_FFSR_TCPresent_SHIFT)
|
||||
#define TPI_FFSR_FtStopped_SHIFT 1
|
||||
#define TPI_FFSR_FtStopped_MASK (0x1ul << TPI_FFSR_FtStopped_SHIFT)
|
||||
#define TPI_FFSR_FlInProg_SHIFT 0
|
||||
#define TPI_FFSR_FlInProg_MASK (0x1ul << TPI_FFSR_FlInProg_SHIFT)
|
||||
|
||||
/* TPI FFCR */
|
||||
|
||||
#define TPI_FFCR_TrigIn_SHIFT 8
|
||||
#define TPI_FFCR_TrigIn_MASK (0x1ul << TPI_FFCR_TrigIn_SHIFT)
|
||||
#define TPI_FFCR_EnFCont_SHIFT 1
|
||||
#define TPI_FFCR_EnFCont_MASK (0x1ul << TPI_FFCR_EnFCont_SHIFT)
|
||||
|
||||
#define TPI_TRIGGER_TRIGGER_SHIFT 0
|
||||
#define TPI_TRIGGER_TRIGGER_MASK (0x1ul << TPI_TRIGGER_TRIGGER_SHIFT)
|
||||
|
||||
/* TPI FIFO0 */
|
||||
|
||||
#define TPI_FIFO0_ITM_ATVALID_SHIFT 29
|
||||
#define TPI_FIFO0_ITM_ATVALID_MASK (0x3ul << TPI_FIFO0_ITM_ATVALID_SHIFT)
|
||||
#define TPI_FIFO0_ITM_bytecount_SHIFT 27
|
||||
#define TPI_FIFO0_ITM_bytecount_MASK (0x3ul << TPI_FIFO0_ITM_bytecount_SHIFT)
|
||||
#define TPI_FIFO0_ETM_ATVALID_SHIFT 26
|
||||
#define TPI_FIFO0_ETM_ATVALID_MASK (0x3ul << TPI_FIFO0_ETM_ATVALID_SHIFT)
|
||||
#define TPI_FIFO0_ETM_bytecount_SHIFT 24
|
||||
#define TPI_FIFO0_ETM_bytecount_MASK (0x3ul << TPI_FIFO0_ETM_bytecount_SHIFT)
|
||||
#define TPI_FIFO0_ETM2_SHIFT 16
|
||||
#define TPI_FIFO0_ETM2_MASK (0xfful << TPI_FIFO0_ETM2_SHIFT)
|
||||
#define TPI_FIFO0_ETM1_SHIFT 8
|
||||
#define TPI_FIFO0_ETM1_MASK (0xfful << TPI_FIFO0_ETM1_SHIFT)
|
||||
#define TPI_FIFO0_ETM0_SHIFT 0
|
||||
#define TPI_FIFO0_ETM0_MASK (0xfful << TPI_FIFO0_ETM0_SHIFT)
|
||||
|
||||
/* TPI ITATBCTR2 */
|
||||
|
||||
#define TPI_ITATBCTR2_ATREADY_SHIFT 0
|
||||
#define TPI_ITATBCTR2_ATREADY_MASK (0x1ul << TPI_ITATBCTR2_ATREADY_SHIFT)
|
||||
|
||||
/* TPI FIFO1 */
|
||||
|
||||
#define TPI_FIFO1_ITM_ATVALID_SHIFT 29
|
||||
#define TPI_FIFO1_ITM_ATVALID_MASK (0x3ul << TPI_FIFO1_ITM_ATVALID_SHIFT)
|
||||
#define TPI_FIFO1_ITM_bytecount_SHIFT 27
|
||||
#define TPI_FIFO1_ITM_bytecount_MASK (0x3ul << TPI_FIFO1_ITM_bytecount_SHIFT)
|
||||
#define TPI_FIFO1_ETM_ATVALID_SHIFT 26
|
||||
#define TPI_FIFO1_ETM_ATVALID_MASK (0x3ul << TPI_FIFO1_ETM_ATVALID_SHIFT)
|
||||
#define TPI_FIFO1_ETM_bytecount_SHIFT 24
|
||||
#define TPI_FIFO1_ETM_bytecount_MASK (0x3ul << TPI_FIFO1_ETM_bytecount_SHIFT)
|
||||
#define TPI_FIFO1_ITM2_SHIFT 16
|
||||
#define TPI_FIFO1_ITM2_MASK (0xfful << TPI_FIFO1_ITM2_SHIFT)
|
||||
#define TPI_FIFO1_ITM1_SHIFT 8
|
||||
#define TPI_FIFO1_ITM1_MASK (0xfful << TPI_FIFO1_ITM1_SHIFT)
|
||||
#define TPI_FIFO1_ITM0_SHIFT 0
|
||||
#define TPI_FIFO1_ITM0_MASK (0xfful << TPI_FIFO1_ITM0_SHIFT)
|
||||
|
||||
/* TPI ITATBCTR0 */
|
||||
|
||||
#define TPI_ITATBCTR0_ATREADY_SHIFT 0
|
||||
#define TPI_ITATBCTR0_ATREADY_MASK (0x1ul << TPI_ITATBCTR0_ATREADY_SHIFT)
|
||||
|
||||
/* TPI ITCTRL */
|
||||
|
||||
#define TPI_ITCTRL_Mode_SHIFT 0
|
||||
#define TPI_ITCTRL_Mode_MASK (0x1ul << TPI_ITCTRL_Mode_SHIFT)
|
||||
|
||||
/* TPI DEVID */
|
||||
|
||||
#define TPI_DEVID_NRZVALID_SHIFT 11
|
||||
#define TPI_DEVID_NRZVALID_MASK (0x1ul << TPI_DEVID_NRZVALID_SHIFT)
|
||||
#define TPI_DEVID_MANCVALID_SHIFT 10
|
||||
#define TPI_DEVID_MANCVALID_MASK (0x1ul << TPI_DEVID_MANCVALID_SHIFT)
|
||||
#define TPI_DEVID_PTINVALID_SHIFT 9
|
||||
#define TPI_DEVID_PTINVALID_MASK (0x1ul << TPI_DEVID_PTINVALID_SHIFT)
|
||||
#define TPI_DEVID_MinBufSz_SHIFT 6
|
||||
#define TPI_DEVID_MinBufSz_MASK (0x7ul << TPI_DEVID_MinBufSz_SHIFT)
|
||||
#define TPI_DEVID_AsynClkIn_SHIFT 5
|
||||
#define TPI_DEVID_AsynClkIn_MASK (0x1ul << TPI_DEVID_AsynClkIn_SHIFT)
|
||||
#define TPI_DEVID_NrTraceInput_SHIFT 0
|
||||
#define TPI_DEVID_NrTraceInput_MASK (0x1ful << TPI_DEVID_NrTraceInput_SHIFT)
|
||||
|
||||
/* TPI DEVTYPE */
|
||||
|
||||
#define TPI_DEVTYPE_SubType_SHIFT 0
|
||||
#define TPI_DEVTYPE_SubType_MASK (0xful << TPI_DEVTYPE_SubType_SHIFT)
|
||||
#define TPI_DEVTYPE_MajorType_SHIFT 4
|
||||
#define TPI_DEVTYPE_MajorType_MASK (0xful << TPI_DEVTYPE_MajorType_SHIFT)
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV8_M_TPI_H */
|
||||
Executable
+457
@@ -0,0 +1,457 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/syslog/syslog.h>
|
||||
#include <nuttx/usb/usbdev_trace.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "irq/irq.h"
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
#include "chip.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_getsp
|
||||
****************************************************************************/
|
||||
|
||||
/* I don't know if the builtin to get SP is enabled */
|
||||
|
||||
static inline uint32_t up_getsp(void)
|
||||
{
|
||||
uint32_t sp;
|
||||
__asm__
|
||||
(
|
||||
"\tmov %0, sp\n\t"
|
||||
: "=r"(sp)
|
||||
);
|
||||
return sp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_stackdump
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
static void up_stackdump(uint32_t sp, uint32_t stack_base)
|
||||
{
|
||||
uint32_t stack ;
|
||||
|
||||
for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
|
||||
{
|
||||
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, (unsigned long)up_check_tcbstack(tcb),
|
||||
(unsigned long)tcb->adj_stack_size);
|
||||
#else
|
||||
_alert("PID: %d Stack Used=%lu of %lu\n",
|
||||
tcb->pid, (unsigned long)up_check_tcbstack(tcb),
|
||||
(unsigned long)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;
|
||||
|
||||
/* 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 */
|
||||
|
||||
_alert("R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
|
||||
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
|
||||
_alert("R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
|
||||
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
|
||||
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
_alert("xPSR: %08x BASEPRI: %08x CONTROL: %08x\n",
|
||||
regs[REG_XPSR], regs[REG_BASEPRI], getcontrol());
|
||||
#else
|
||||
_alert("xPSR: %08x PRIMASK: %08x CONTROL: %08x\n",
|
||||
regs[REG_XPSR], regs[REG_PRIMASK], getcontrol());
|
||||
#endif
|
||||
|
||||
#ifdef REG_EXC_RETURN
|
||||
_alert("EXC_RETURN: %08x\n", regs[REG_EXC_RETURN]);
|
||||
#endif
|
||||
}
|
||||
#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;
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
uint32_t istackbase;
|
||||
uint32_t istacksize;
|
||||
#endif
|
||||
|
||||
/* Dump the registers (if available) */
|
||||
|
||||
up_registerdump();
|
||||
|
||||
/* Get the limits on the user stack memory */
|
||||
|
||||
if (rtcb->pid == 0) /* Check for CPU0 IDLE thread */
|
||||
{
|
||||
ustackbase = g_idle_topstack - 4;
|
||||
ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ustackbase = (uint32_t)rtcb->adj_stack_ptr;
|
||||
ustacksize = (uint32_t)rtcb->adj_stack_size;
|
||||
}
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
istackbase = (uint32_t)up_intstack_base();
|
||||
#else
|
||||
istackbase = (uint32_t)&g_intstackbase;
|
||||
#endif
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7);
|
||||
|
||||
/* 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 = CURRENT_REGS[REG_R13];
|
||||
_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)
|
||||
{
|
||||
up_stackdump(sp, ustackbase);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alert("ERROR: Stack pointer is not within the allocated stack\n");
|
||||
up_stackdump(ustackbase - ustacksize, ustackbase);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Show user stack info */
|
||||
|
||||
_alert("sp: %08x\n", sp);
|
||||
_alert("stack base: %08x\n", ustackbase);
|
||||
_alert("stack size: %08x\n", ustacksize);
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
_alert("stack 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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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())->flink == NULL)
|
||||
{
|
||||
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
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
board_autoled_on(LED_PANIC);
|
||||
up_mdelay(250);
|
||||
board_autoled_off(LED_PANIC);
|
||||
up_mdelay(250);
|
||||
#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
|
||||
|
||||
board_autoled_on(LED_ASSERTION);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <stdbool.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.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.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should 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.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.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 */
|
||||
|
||||
up_restorestate(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.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+823
File diff suppressed because it is too large
Load Diff
Executable
+90
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/up_copyarmstate.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 <stdint.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) && defined(CONFIG_ARMV8M_LAZYFPU)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_copyarmstate
|
||||
*
|
||||
* Description:
|
||||
* Copy the ARM portion of the register save area (omitting the floating
|
||||
* point registers) and save the floating pointer register directly.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_copyarmstate(uint32_t *dest, uint32_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* In the Cortex-M3 model, the state is copied from the stack to the TCB,
|
||||
* but only a reference is passed to get the state from the TCB. So the
|
||||
* following check avoids copying the TCB save area onto itself:
|
||||
*/
|
||||
|
||||
if (src != dest)
|
||||
{
|
||||
/* Save the floating point registers: This will initialize the floating
|
||||
* registers at indices SW_INT_REGS through (SW_INT_REGS+SW_FPU_REGS-1)
|
||||
*/
|
||||
|
||||
up_savefpu(dest);
|
||||
|
||||
/* Save the block of ARM registers that were saved by the interrupt
|
||||
* handling logic. Indices: 0 through (SW_INT_REGS-1).
|
||||
*/
|
||||
|
||||
for (i = 0; i < SW_INT_REGS; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
/* Skip over the floating point registers and save the block of ARM
|
||||
* registers that were saved by the hardware when the interrupt was
|
||||
* taken. Indices: (SW_INT_REGS+SW_FPU_REGS) through
|
||||
* (XCPTCONTEXT_REGS-1)
|
||||
*/
|
||||
|
||||
src += SW_FPU_REGS;
|
||||
dest += SW_FPU_REGS;
|
||||
|
||||
for (i = 0; i < HW_XCPT_REGS; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ARCH_FPU && CONFIG_ARMV8M_LAZYFPU */
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/up_copyfullstate.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 <stdint.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_copyfullstate
|
||||
*
|
||||
* Description:
|
||||
* Copy the entire register save area (including the floating point
|
||||
* registers if applicable). This is a little faster than most memcpy's
|
||||
* since it does 32-bit transfers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_copyfullstate(uint32_t *dest, uint32_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* In the Cortex-M3 model, the state is copied from the stack to the TCB,
|
||||
* but only a reference is passed to get the state from the TCB. So the
|
||||
* following check avoids copying the TCB save area onto itself:
|
||||
*/
|
||||
|
||||
if (src != dest)
|
||||
{
|
||||
for (i = 0; i < XCPTCONTEXT_REGS; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t *up_doirq(int irq, uint32_t *regs)
|
||||
{
|
||||
board_autoled_on(LED_INIRQ);
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
PANIC();
|
||||
#else
|
||||
uint32_t *savestate;
|
||||
|
||||
/* Nested interrupts are not supported in this implementation. If you
|
||||
* want to implement nested interrupts, you would have to (1) change the
|
||||
* way that CURRENT_REGS is handled and (2) the design associated with
|
||||
* CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for
|
||||
* that purpose as implemented here because only the outermost nested
|
||||
* interrupt can result in a context switch.
|
||||
*/
|
||||
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*/
|
||||
|
||||
savestate = (uint32_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = regs;
|
||||
|
||||
/* Acknowledge the interrupt */
|
||||
|
||||
up_ack_irq(irq);
|
||||
|
||||
/* 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 = (uint32_t *)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 = savestate;
|
||||
#endif
|
||||
board_autoled_off(LED_INIRQ);
|
||||
return regs;
|
||||
}
|
||||
Executable
+331
@@ -0,0 +1,331 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/gnu/up_exception.S
|
||||
*
|
||||
* Copyright (C) 2009-2013, 2015-2016, 2018 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012 Michael Smith. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/armv8-m/nvicpri.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "exc_return.h"
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
/* Configuration ********************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
/* In kernel mode without an interrupt stack, this interrupt handler will set the
|
||||
* MSP to the stack pointer of the interrupted thread. If the interrupted thread
|
||||
* was a privileged thread, that will be the MSP otherwise it will be the PSP. If
|
||||
* the PSP is used, then the value of the MSP will be invalid when the interrupt
|
||||
* handler returns because it will be a pointer to an old position in the
|
||||
* unprivileged stack. Then when the high priority interrupt occurs and uses this
|
||||
* stale MSP, there will most likely be a system failure.
|
||||
*
|
||||
* If the interrupt stack is selected, on the other hand, then the interrupt
|
||||
* handler will always set the MSP to the interrupt stack. So when the high
|
||||
* priority interrupt occurs, it will either use the MSP of the last privileged
|
||||
* thread to run or, in the case of the nested interrupt, the interrupt stack if
|
||||
* no privileged task has run.
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4
|
||||
# error Interrupt stack must be used with high priority interrupts in kernel mode
|
||||
# endif
|
||||
|
||||
/* Use the BASEPRI to control interrupts is required if nested, high
|
||||
* priority interrupts are supported.
|
||||
*/
|
||||
|
||||
# ifndef CONFIG_ARMV8M_USEBASEPRI
|
||||
# error CONFIG_ARMV8M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.globl exception_common
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "up_exception.S"
|
||||
|
||||
/************************************************************************************
|
||||
* Macro Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: setintstack
|
||||
*
|
||||
* Description:
|
||||
* Set the current stack pointer to the "top" the interrupt stack. Single CPU
|
||||
* case. Must be provided by MCU-specific logic in the SMP case.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.macro setintstack, tmp1, tmp2
|
||||
ldr sp, =g_intstackbase
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* .text
|
||||
************************************************************************************/
|
||||
|
||||
/* Common exception handling logic. On entry here, the return stack is on either
|
||||
* the PSP or the MSP and looks like the following:
|
||||
*
|
||||
* REG_XPSR
|
||||
* REG_R15
|
||||
* REG_R14
|
||||
* REG_R12
|
||||
* REG_R3
|
||||
* REG_R2
|
||||
* REG_R1
|
||||
* MSP->REG_R0
|
||||
*
|
||||
* And
|
||||
* IPSR contains the IRQ number
|
||||
* R14 Contains the EXC_RETURN value
|
||||
* We are in handler mode and the current SP is the MSP
|
||||
*
|
||||
* If CONFIG_ARCH_FPU is defined, the volatile FP registers and FPSCR are on the
|
||||
* return stack immediately above REG_XPSR.
|
||||
*/
|
||||
|
||||
.text
|
||||
.type exception_common, function
|
||||
.thumb_func
|
||||
exception_common:
|
||||
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
|
||||
/* Complete the context save */
|
||||
|
||||
/* The EXC_RETURN value tells us whether the context is on the MSP or PSP */
|
||||
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 1f /* Branch if context already on the MSP */
|
||||
mrs r1, psp /* R1=The process stack pointer (PSP) */
|
||||
mov sp, r1 /* Set the MSP to the PSP */
|
||||
|
||||
1:
|
||||
mov r2, sp /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
mrs r3, basepri /* R3=Current BASEPRI setting */
|
||||
#else
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
/* Save the non-volatile FP registers here.
|
||||
*
|
||||
* This routine is the only point where we can save these registers; either before
|
||||
* or after calling up_doirq. The compiler is free to use them at any time as long
|
||||
* as they are restored before returning, so we can't assume that we can get at the
|
||||
* true values of these registers in any routine called from here.
|
||||
*
|
||||
* REVISIT: we could do all this saving lazily on the context switch side if we knew
|
||||
* where to put the registers.
|
||||
*/
|
||||
|
||||
vstmdb sp!, {s16-s31} /* Save the non-volatile FP context */
|
||||
|
||||
#endif
|
||||
|
||||
stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */
|
||||
|
||||
/* There are two arguments to up_doirq:
|
||||
*
|
||||
* R0 = The IRQ number
|
||||
* R1 = The top of the stack points to the saved state
|
||||
*/
|
||||
|
||||
mov r1, sp
|
||||
|
||||
/* Also save the top of the stack in a preserved register */
|
||||
|
||||
mov r4, sp
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
/* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use
|
||||
* a special special interrupt stack pointer. The way that this is done
|
||||
* here prohibits nested interrupts without some additional logic!
|
||||
*/
|
||||
|
||||
setintstack r2, r3
|
||||
|
||||
#else
|
||||
/* Otherwise, we will re-use the interrupted thread's stack. That may
|
||||
* mean using either MSP or PSP stack for interrupt level processing (in
|
||||
* kernel mode).
|
||||
*/
|
||||
|
||||
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
|
||||
mov sp, r2 /* Instantiate the aligned stack */
|
||||
|
||||
#endif
|
||||
|
||||
bl up_doirq /* R0=IRQ, R1=register save (msp) */
|
||||
mov r1, r4 /* Recover R1=main stack pointer */
|
||||
|
||||
/* On return from up_doirq, R0 will hold a pointer to register context
|
||||
* array to use for the interrupt return. If that return value is the same
|
||||
* as current stack pointer, then things are relatively easy.
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 2f /* Branch if no context switch */
|
||||
|
||||
/* 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 a TCB structure. We'll have to copy some
|
||||
* values to the stack.
|
||||
*/
|
||||
|
||||
/* Copy the hardware-saved context to the stack, and restore the software
|
||||
* saved context directly.
|
||||
*
|
||||
* XXX In the normal case, it appears that this entire operation is unnecessary;
|
||||
* context switch time would be improved if we could work out when the stack
|
||||
* is dirty and avoid the work...
|
||||
*/
|
||||
|
||||
add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */
|
||||
ldmia r1!, {r4-r11} /* Fetch eight registers in HW save area */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vldmia r1!, {s0-s15} /* Fetch sixteen FP registers in HW save area */
|
||||
ldmia r1, {r2-r3} /* Fetch FPSCR and Reserved in HW save area */
|
||||
#endif
|
||||
ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
stmdb r1!, {r2-r3} /* Store FPSCR and Reserved on the return stack */
|
||||
vstmdb r1!, {s0-s15} /* Store sixteen FP registers on the return stack */
|
||||
#endif
|
||||
stmdb r1!, {r4-r11} /* Store eight registers on the return stack */
|
||||
ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vldmia r0, {s16-s31} /* Recover S16-S31 */
|
||||
#endif
|
||||
|
||||
b 3f /* Re-join common logic */
|
||||
|
||||
2:
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created at entry.
|
||||
*/
|
||||
|
||||
ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vldmia r1!, {s16-s31} /* Recover S16-S31 */
|
||||
#endif
|
||||
|
||||
3:
|
||||
/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
|
||||
* (handler mode) if the stack is on the MSP. It can only be on the PSP if
|
||||
* EXC_RETURN is 0xfffffffd (unprivileged thread)
|
||||
*/
|
||||
|
||||
mrs r2, control /* R2=Contents of the control register */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 4f /* Branch if privileged */
|
||||
|
||||
orr r2, r2, #1 /* Unprivileged mode */
|
||||
msr psp, r1 /* R1=The process stack pointer */
|
||||
b 5f
|
||||
4:
|
||||
bic r2, r2, #1 /* Privileged mode */
|
||||
msr msp, r1 /* R1=The main stack pointer */
|
||||
5:
|
||||
msr control, r2 /* Save the updated control register */
|
||||
#else
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
ite eq /* next two instructions conditional */
|
||||
msreq msp, r1 /* R1=The main stack pointer */
|
||||
msrne psp, r1 /* R1=The process stack pointer */
|
||||
#endif
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
msr basepri, r3 /* Restore interrupts priority masking */
|
||||
#else
|
||||
msr primask, r3 /* Restore interrupts */
|
||||
#endif
|
||||
|
||||
/* Always return with R14 containing the special value that will: (1)
|
||||
* return to thread mode, and (2) select the correct stack.
|
||||
*/
|
||||
|
||||
bx r14 /* And return */
|
||||
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
/************************************************************************************
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.bss
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.align 8
|
||||
g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK + 4) & ~7)
|
||||
g_intstackbase:
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
.end
|
||||
Executable
+242
@@ -0,0 +1,242 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/gnu/up_fetchadd.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>
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "up_fetchadd.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchadd32
|
||||
*
|
||||
* Description:
|
||||
* Perform an atomic fetch add operation on the provided 32-bit value.
|
||||
*
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of 32-bit value to be incremented.
|
||||
* value - The 32-bit addend
|
||||
*
|
||||
* Returned Value:
|
||||
* The incremented value (volatile!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fetchadd32
|
||||
.type up_fetchadd32, %function
|
||||
|
||||
up_fetchadd32:
|
||||
|
||||
1:
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd32, . - up_fetchadd32
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchsub32
|
||||
*
|
||||
* Description:
|
||||
* Perform an atomic fetch subtract operation on the provided 32-bit value.
|
||||
*
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of 32-bit value to be decremented.
|
||||
* value - The 32-bit subtrahend
|
||||
*
|
||||
* Returned Value:
|
||||
* The decremented value (volatile!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fetchsub32
|
||||
.type up_fetchsub32, %function
|
||||
|
||||
up_fetchsub32:
|
||||
|
||||
1:
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub32, . - up_fetchsub32
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchadd16
|
||||
*
|
||||
* Description:
|
||||
* Perform an atomic fetch add operation on the provided 16-bit value.
|
||||
*
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of 16-bit value to be incremented.
|
||||
* value - The 16-bit addend
|
||||
*
|
||||
* Returned Value:
|
||||
* The incremented value (volatile!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fetchadd16
|
||||
.type up_fetchadd16, %function
|
||||
|
||||
up_fetchadd16:
|
||||
|
||||
1:
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd16, . - up_fetchadd16
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchsub16
|
||||
*
|
||||
* Description:
|
||||
* Perform an atomic fetch subtract operation on the provided 16-bit value.
|
||||
*
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of 16-bit value to be decremented.
|
||||
* value - The 16-bit subtrahend
|
||||
*
|
||||
* Returned Value:
|
||||
* The decremented value (volatile!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fetchsub16
|
||||
.type up_fetchsub16, %function
|
||||
|
||||
up_fetchsub16:
|
||||
|
||||
1:
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
/* Attempt to save the decremented value */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub16, . - up_fetchsub16
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchadd8
|
||||
*
|
||||
* Description:
|
||||
* Perform an atomic fetch add operation on the provided 8-bit value.
|
||||
*
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of 8-bit value to be incremented.
|
||||
* value - The 8-bit addend
|
||||
*
|
||||
* Returned Value:
|
||||
* The incremented value (volatile!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fetchadd8
|
||||
.type up_fetchadd8, %function
|
||||
|
||||
up_fetchadd8:
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd8, . - up_fetchadd8
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchsub8
|
||||
*
|
||||
* Description:
|
||||
* Perform an atomic fetch subtract operation on the provided 8-bit value.
|
||||
*
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of 8-bit value to be decremented.
|
||||
* value - The 8-bit subtrahend
|
||||
*
|
||||
* Returned Value:
|
||||
* The decremented value (volatile!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fetchsub8
|
||||
.type up_fetchsub8, %function
|
||||
|
||||
up_fetchsub8:
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub8, . - up_fetchsub8
|
||||
.end
|
||||
Executable
+270
@@ -0,0 +1,270 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/gnu/up_fpu.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.
|
||||
*
|
||||
************************************************************************************/
|
||||
/*
|
||||
* When this file is assembled, it will require the following GCC options:
|
||||
*
|
||||
* -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfp -meabi=5 -mthumb
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_savefpu
|
||||
.globl up_restorefpu
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "up_fpu.S"
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_savefpu
|
||||
*
|
||||
* Description:
|
||||
* Given the pointer to a register save area (in R0), save the state of the
|
||||
* floating point registers.
|
||||
*
|
||||
* C Function Prototype:
|
||||
* void up_savefpu(uint32_t *regs);
|
||||
*
|
||||
* Input Parameters:
|
||||
* regs - A pointer to the register save area in which to save the floating point
|
||||
* registers
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.thumb_func
|
||||
.type up_savefpu, function
|
||||
up_savefpu:
|
||||
|
||||
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
|
||||
|
||||
/* Some older GNU assemblers don't support all the newer UAL mnemonics. */
|
||||
|
||||
#if 1 /* Use UAL mnemonics */
|
||||
/* Store all floating point registers. Registers are stored in numeric order,
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
|
||||
/* Store the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
#else
|
||||
/* Store all floating point registers */
|
||||
|
||||
#if 1 /* Use store multiple */
|
||||
fstmias r1!, {s0-s31} /* Save the full FP context */
|
||||
#else
|
||||
vmov r2, r3, d0 /* r2, r3 = d0 */
|
||||
str r2, [r1], #4 /* Save S0 and S1 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d1 /* r2, r3 = d1 */
|
||||
str r2, [r1], #4 /* Save S2 and S3 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d2 /* r2, r3 = d2 */
|
||||
str r2, [r1], #4 /* Save S4 and S5 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d3 /* r2, r3 = d3 */
|
||||
str r2, [r1], #4 /* Save S6 and S7 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d4 /* r2, r3 = d4 */
|
||||
str r2, [r1], #4 /* Save S8 and S9 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d5 /* r2, r3 = d5 */
|
||||
str r2, [r1], #4 /* Save S10 and S11 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d6 /* r2, r3 = d6 */
|
||||
str r2, [r1], #4 /* Save S12 and S13 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d7 /* r2, r3 = d7 */
|
||||
str r2, [r1], #4 /* Save S14 and S15 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d8 /* r2, r3 = d8 */
|
||||
str r2, [r1], #4 /* Save S16 and S17 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d9 /* r2, r3 = d9 */
|
||||
str r2, [r1], #4 /* Save S18 and S19 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d10 /* r2, r3 = d10 */
|
||||
str r2, [r1], #4 /* Save S20 and S21 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d11 /* r2, r3 = d11 */
|
||||
str r2, [r1], #4 /* Save S22 and S23 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d12 /* r2, r3 = d12 */
|
||||
str r2, [r1], #4 /* Save S24 and S25 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d13 /* r2, r3 = d13 */
|
||||
str r2, [r1], #4 /* Save S26 and S27 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d14 /* r2, r3 = d14 */
|
||||
str r2, [r1], #4 /* Save S28 and S29 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d15 /* r2, r3 = d15 */
|
||||
str r2, [r1], #4 /* Save S30 and S31 values */
|
||||
str r3, [r1], #4
|
||||
#endif
|
||||
|
||||
/* Store the floating point control and status register */
|
||||
|
||||
fmrx r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
#endif
|
||||
bx lr
|
||||
|
||||
.size up_savefpu, .-up_savefpu
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_restorefpu
|
||||
*
|
||||
* Description:
|
||||
* Given the pointer to a register save area (in R0), restore the state of the
|
||||
* floating point registers.
|
||||
*
|
||||
* C Function Prototype:
|
||||
* void up_restorefpu(const uint32_t *regs);
|
||||
*
|
||||
* Input Parameters:
|
||||
* regs - A pointer to the register save area containing the floating point
|
||||
* registers.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function does not return anything explicitly. However, it is called from
|
||||
* interrupt level assembly logic that assumes that r0 is preserved.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.thumb_func
|
||||
.type up_restorefpu, function
|
||||
up_restorefpu:
|
||||
|
||||
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
|
||||
|
||||
/* Some older GNU assemblers don't support all the newer UAL mnemonics. */
|
||||
|
||||
#if 1 /* Use UAL mnemonics */
|
||||
/* Load all floating point registers. Registers are loaded in numeric order,
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
|
||||
/* Load the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
ldr r2, [r1], #4 /* Fetch the floating point control and status register */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
#else
|
||||
/* Load all floating point registers Registers are loaded in numeric order,
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
#if 1 /* Use load multiple */
|
||||
fldmias r1!, {s0-s31} /* Restore the full FP context */
|
||||
#else
|
||||
ldr r2, [r1], #4 /* Fetch S0 and S1 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d0, r2, r3 /* Save as d0 */
|
||||
ldr r2, [r1], #4 /* Fetch S2 and S3 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d1, r2, r3 /* Save as d1 */
|
||||
ldr r2, [r1], #4 /* Fetch S4 and S5 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d2, r2, r3 /* Save as d2 */
|
||||
ldr r2, [r1], #4 /* Fetch S6 and S7 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d3, r2, r3 /* Save as d3 */
|
||||
ldr r2, [r1], #4 /* Fetch S8 and S9 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d4, r2, r3 /* Save as d4 */
|
||||
ldr r2, [r1], #4 /* Fetch S10 and S11 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d5, r2, r3 /* Save as d5 */
|
||||
ldr r2, [r1], #4 /* Fetch S12 and S13 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d6, r2, r3 /* Save as d6 */
|
||||
ldr r2, [r1], #4 /* Fetch S14 and S15 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d7, r2, r3 /* Save as d7 */
|
||||
ldr r2, [r1], #4 /* Fetch S16 and S17 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d8, r2, r3 /* Save as d8 */
|
||||
ldr r2, [r1], #4 /* Fetch S18 and S19 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d9, r2, r3 /* Save as d9 */
|
||||
ldr r2, [r1], #4 /* Fetch S20 and S21 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d10, r2, r3 /* Save as d10 */
|
||||
ldr r2, [r1], #4 /* Fetch S22 and S23 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d11, r2, r3 /* Save as d11 */
|
||||
ldr r2, [r1], #4 /* Fetch S24 and S25 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d12, r2, r3 /* Save as d12 */
|
||||
ldr r2, [r1], #4 /* Fetch S26 and S27 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d13, r2, r3 /* Save as d13 */
|
||||
ldr r2, [r1], #4 /* Fetch S28 and S29 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d14, r2, r3 /* Save as d14 */
|
||||
ldr r2, [r1], #4 /* Fetch S30 and S31 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d15, r2, r3 /* Save as d15 */
|
||||
#endif
|
||||
|
||||
/* Load the floating point control and status register. r1 points t
|
||||
* the address of the FPCSR register.
|
||||
*/
|
||||
|
||||
ldr r2, [r1], #4 /* Fetch the floating point control and status register */
|
||||
fmxr fpscr, r2 /* Restore the FPCSR */
|
||||
#endif
|
||||
bx lr
|
||||
|
||||
.size up_restorefpu, .-up_restorefpu
|
||||
#endif /* CONFIG_ARCH_FPU */
|
||||
.end
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/gnu/up_fullcontextrestore.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 <arch/irq.h>
|
||||
|
||||
#include "nvic.h"
|
||||
#include "svcall.h"
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "up_fullcontextrestore.S"
|
||||
|
||||
/************************************************************************************
|
||||
* Macros
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_fullcontextrestore
|
||||
*
|
||||
* Description:
|
||||
* Restore the current thread context. Full prototype is:
|
||||
*
|
||||
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.thumb_func
|
||||
.globl up_fullcontextrestore
|
||||
.type up_fullcontextrestore, function
|
||||
up_fullcontextrestore:
|
||||
|
||||
/* Perform the System call with R0=1 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_restore_context /* R0: restore context */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* This call should not return */
|
||||
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
.size up_fullcontextrestore, .-up_fullcontextrestore
|
||||
.end
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/userspace.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "nvic.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* If CONFIG_ARMV8M_USEBASEPRI=n, then debug output from this file may
|
||||
* interfere with context switching!
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_HARDFAULT_ALERT
|
||||
# define hfalert(format, ...) _alert(format, ##__VA_ARGS__)
|
||||
#else
|
||||
# define hfalert(x...)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_HARDFAULT_INFO
|
||||
# define hfinfo(format, ...) _info(format, ##__VA_ARGS__)
|
||||
#else
|
||||
# define hfinfo(x...)
|
||||
#endif
|
||||
|
||||
#define INSN_SVC0 0xdf00 /* insn: svc 0 */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_hardfault
|
||||
*
|
||||
* Description:
|
||||
* This is Hard Fault exception handler. It also catches SVC call
|
||||
* exceptions that are performed in bad contexts.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_hardfault(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
/* Get the value of the program counter where the fault occurred */
|
||||
|
||||
#ifndef CONFIG_ARMV8M_USEBASEPRI
|
||||
uint32_t *regs = (uint32_t *)context;
|
||||
uint16_t *pc = (uint16_t *)regs[REG_PC] - 1;
|
||||
|
||||
/* Check if the pc lies in known FLASH memory.
|
||||
* REVISIT: What if the PC lies in "unknown" external memory? Best
|
||||
* use the BASEPRI register if you have external memory.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* In the kernel build, SVCalls are expected in either the base, kernel
|
||||
* FLASH region or in the user FLASH region.
|
||||
*/
|
||||
|
||||
if (((uintptr_t)pc >= (uintptr_t)_START_TEXT &&
|
||||
(uintptr_t)pc < (uintptr_t)_END_TEXT) ||
|
||||
((uintptr_t)pc >= (uintptr_t)USERSPACE->us_textstart &&
|
||||
(uintptr_t)pc < (uintptr_t)USERSPACE->us_textend))
|
||||
#else
|
||||
/* SVCalls are expected only from the base, kernel FLASH region */
|
||||
|
||||
if ((uintptr_t)pc >= (uintptr_t)_START_TEXT &&
|
||||
(uintptr_t)pc < (uintptr_t)_END_TEXT)
|
||||
#endif
|
||||
{
|
||||
/* Fetch the instruction that caused the Hard fault */
|
||||
|
||||
uint16_t insn = *pc;
|
||||
hfinfo(" PC: %p INSN: %04x\n", pc, insn);
|
||||
|
||||
/* If this was the instruction 'svc 0', then forward processing
|
||||
* to the SVCall handler
|
||||
*/
|
||||
|
||||
if (insn == INSN_SVC0)
|
||||
{
|
||||
hfinfo("Forward SVCall\n");
|
||||
return up_svcall(irq, context, arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Dump some hard fault info */
|
||||
|
||||
hfalert("Hard Fault:\n");
|
||||
hfalert(" IRQ: %d regs: %p\n", irq, context);
|
||||
hfalert(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
|
||||
getbasepri(), getprimask(), getipsr(), getcontrol());
|
||||
hfalert(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x "
|
||||
"AFAULTS: %08x\n",
|
||||
getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS),
|
||||
getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR),
|
||||
getreg32(NVIC_AFAULTS));
|
||||
|
||||
up_irq_save();
|
||||
_alert("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS));
|
||||
PANIC();
|
||||
return OK;
|
||||
}
|
||||
Executable
+144
@@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/armv8-m/nvicpri.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "psr.h"
|
||||
#include "exc_return.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_initial_state
|
||||
*
|
||||
* Description:
|
||||
* A new thread is being started and a new TCB
|
||||
* has been created. This function is called to initialize
|
||||
* the processor specific portions of the new TCB.
|
||||
*
|
||||
* This function must setup the initial architecture registers
|
||||
* and/or stack so that execution will begin at tcb->start
|
||||
* on the next context switch.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_initial_state(struct tcb_s *tcb)
|
||||
{
|
||||
struct xcptcontext *xcp = &tcb->xcp;
|
||||
|
||||
/* Initialize the initial exception register context structure */
|
||||
|
||||
memset(xcp, 0, sizeof(struct xcptcontext));
|
||||
|
||||
/* Save the initial stack pointer */
|
||||
|
||||
xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
|
||||
|
||||
#ifdef CONFIG_ARMV8M_STACKCHECK
|
||||
/* Set the stack limit value */
|
||||
|
||||
xcp->regs[REG_R10] = (uint32_t)tcb->stack_alloc_ptr + 64;
|
||||
#endif
|
||||
|
||||
/* Save the task entry point (stripping off the thumb bit) */
|
||||
|
||||
xcp->regs[REG_PC] = (uint32_t)tcb->start & ~1;
|
||||
|
||||
/* Specify thumb mode */
|
||||
|
||||
xcp->regs[REG_XPSR] = ARMV8M_XPSR_T;
|
||||
|
||||
/* If this task is running PIC, then set the PIC base register to the
|
||||
* address of the allocated D-Space region.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PIC
|
||||
if (tcb->dspace != NULL)
|
||||
{
|
||||
/* Set the PIC base register (probably R10) to the address of the
|
||||
* alloacated D-Space region.
|
||||
*/
|
||||
|
||||
xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NXFLAT
|
||||
/* Make certain that bit 0 is set in the main entry address. This
|
||||
* is only an issue when NXFLAT is enabled. NXFLAT doesn't know
|
||||
* anything about thumb; the addresses that NXFLAT sets are based
|
||||
* on file header info and won't have bit 0 set.
|
||||
*/
|
||||
|
||||
tcb->entry.main = (main_t)((uint32_t)tcb->entry.main | 1);
|
||||
#endif
|
||||
#endif /* CONFIG_PIC */
|
||||
|
||||
#if !defined(CONFIG_ARMV8M_LAZYFPU) || defined(CONFIG_BUILD_PROTECTED)
|
||||
/* 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_EXC_RETURN] = EXC_RETURN_PRIVTHR;
|
||||
|
||||
#endif /* !CONFIG_ARMV8M_LAZYFPU || CONFIG_BUILD_PROTECTED */
|
||||
|
||||
#if !defined(CONFIG_ARMV8M_LAZYFPU) && defined(CONFIG_ARCH_FPU)
|
||||
|
||||
xcp->regs[REG_FPSCR] = 0; /* REVISIT: Initial FPSCR should be configurable */
|
||||
xcp->regs[REG_FP_RESERVED] = 0;
|
||||
|
||||
#endif /* !CONFIG_ARMV8M_LAZYFPU && CONFIG_ARCH_FPU */
|
||||
|
||||
/* Enable or disable interrupts, based on user configuration */
|
||||
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
xcp->regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
|
||||
#else
|
||||
xcp->regs[REG_PRIMASK] = 1;
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_SUPPRESS_INTERRUPTS */
|
||||
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
xcp->regs[REG_BASEPRI] = NVIC_SYSH_PRIORITY_MIN;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
|
||||
}
|
||||
Executable
+156
@@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/up_itm.c
|
||||
*
|
||||
* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved.
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Authors: Pierre-noel Bouteville <pnb990@gmail.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "itm.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_sendchar
|
||||
*
|
||||
* Description:
|
||||
* The function transmits a character via the ITM channel 0, and
|
||||
* - Just returns when no debugger is connected that has booked the output.
|
||||
* - Is blocking when a debugger is connected, but the previous character
|
||||
* sent has not been transmitted.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ch - Character to transmit.
|
||||
*
|
||||
* Returned Value:
|
||||
* Character to transmit.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t itm_sendchar(uint32_t ch)
|
||||
{
|
||||
if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_MASK) && /* ITM enabled */
|
||||
(getreg32(ITM_TER) & (1UL << 0))) /* ITM Port #0 enabled */
|
||||
{
|
||||
while (getreg32(ITM_PORT(0)) == 0);
|
||||
putreg8((uint8_t)ch, ITM_PORT(0));
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_receivechar
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input Parameters:
|
||||
* The function inputs a character via the external variable g_itm_rxbuffer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Received character or -1 No character pending.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int32_t itm_receivechar(void)
|
||||
{
|
||||
int32_t ch = -1; /* Assume no character available */
|
||||
|
||||
if (g_itm_rxbuffer != ITM_RXBUFFER_EMPTY)
|
||||
{
|
||||
ch = g_itm_rxbuffer;
|
||||
g_itm_rxbuffer = ITM_RXBUFFER_EMPTY; /* Ready for next character */
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_checkchar
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input Parameters:
|
||||
* The function checks whether a character is pending for reading in the
|
||||
* variable g_itm_rxbuffer.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 No character available.
|
||||
* 1 Character available.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int32_t itm_checkchar (void)
|
||||
{
|
||||
return (g_itm_rxbuffer != ITM_RXBUFFER_EMPTY);
|
||||
}
|
||||
Executable
+192
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/up_itm_syslog.c
|
||||
*
|
||||
* Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved.
|
||||
* Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Authors: Pierre-noel Bouteville <pnb990@gmail.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nuttx/syslog/syslog.h>
|
||||
|
||||
#include "nvic.h"
|
||||
#include "itm.h"
|
||||
#include "tpi.h"
|
||||
#include "dwt.h"
|
||||
#include "up_arch.h"
|
||||
#include "itm_syslog.h"
|
||||
|
||||
#ifdef CONFIG_ARMV8M_ITMSYSLOG
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ARMV8M_ITMSYSLOG_SWODIV
|
||||
# define CONFIG_ARMV8M_ITMSYSLOG_SWODIV 15
|
||||
#endif
|
||||
|
||||
#if CONFIG_ARMV8M_ITMSYSLOG_SWODIV < 0
|
||||
# error CONFIG_ARMV8M_ITMSYSLOG_SWODIV should be at least equal to 1
|
||||
#endif
|
||||
|
||||
/* Use Port #0 at default */
|
||||
|
||||
#ifndef CONFIG_ARMV8M_ITMSYSLOG_PORT
|
||||
# define CONFIG_ARMV8M_ITMSYSLOG_PORT 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* SYSLOG channel methods */
|
||||
|
||||
static int itm_putc(int ch);
|
||||
static int itm_flush(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure describes the ITM SYSLOG channel */
|
||||
|
||||
static const struct syslog_channel_s g_itm_channel =
|
||||
{
|
||||
.sc_putc = itm_putc,
|
||||
.sc_force = itm_putc,
|
||||
.sc_flush = itm_flush,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_putc
|
||||
*
|
||||
* Description:
|
||||
* This is the low-level system logging interface.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int itm_putc(int ch)
|
||||
{
|
||||
/* ITM enabled */
|
||||
|
||||
if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_MASK) == 0)
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* ITM Port "CONFIG_ARMV8M_ITMSYSLOG_PORT" enabled */
|
||||
|
||||
if (getreg32(ITM_TER) & (1 << CONFIG_ARMV8M_ITMSYSLOG_PORT))
|
||||
{
|
||||
while (getreg32(ITM_PORT(CONFIG_ARMV8M_ITMSYSLOG_PORT)) == 0);
|
||||
putreg8((uint8_t)ch, ITM_PORT(CONFIG_ARMV8M_ITMSYSLOG_PORT));
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_flush
|
||||
*
|
||||
* Description:
|
||||
* A dummy FLUSH method
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int itm_flush(void)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: itm_syslog_initialize
|
||||
*
|
||||
* Description:
|
||||
* Performs ARM-specific initialize for the ITM SYSLOG functions.
|
||||
* Additional, board specific logic may be required to:
|
||||
*
|
||||
* - Enable/configured serial wire output pins
|
||||
* - Enable debug clocking.
|
||||
*
|
||||
* Those operations must be performed by MCU-specific logic before this
|
||||
* function is called.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void itm_syslog_initialize(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable trace in core debug */
|
||||
|
||||
regval = getreg32(NVIC_DEMCR);
|
||||
regval |= NVIC_DEMCR_TRCENA;
|
||||
putreg32(regval, NVIC_DEMCR);
|
||||
|
||||
putreg32(0xc5acce55, ITM_LAR);
|
||||
putreg32(0, ITM_TER);
|
||||
putreg32(0, ITM_TCR);
|
||||
putreg32(2, TPI_SPPR); /* Pin protocol: 2=> Manchester (USART) */
|
||||
|
||||
/* Default 880kbps */
|
||||
|
||||
regval = CONFIG_ARMV8M_ITMSYSLOG_SWODIV - 1;
|
||||
putreg32(regval, TPI_ACPR); /* TRACECLKIN/(ACPR+1) SWO speed */
|
||||
|
||||
putreg32(0, ITM_TPR);
|
||||
putreg32(0x400003fe, DWT_CTRL);
|
||||
putreg32(0x0001000d, ITM_TCR);
|
||||
putreg32(0x00000100, TPI_FFCR);
|
||||
putreg32(0xffffffff, ITM_TER); /* Enable 32 Ports */
|
||||
|
||||
/* Setup the SYSLOG channel */
|
||||
|
||||
syslog_channel(&g_itm_channel);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ARMV8M_ITMSYSLOG */
|
||||
Executable
+350
@@ -0,0 +1,350 @@
|
||||
/************************************************************************************************
|
||||
* arch/arm/src/armv8-m/gnu/up_lazyexcption.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 <arch/irq.h>
|
||||
#include <arch/armv8-m/nvicpri.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "exc_return.h"
|
||||
|
||||
/************************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************************/
|
||||
|
||||
/* Configuration ********************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
/* In kernel mode without an interrupt stack, this interrupt handler will set the MSP to the
|
||||
* stack pointer of the interrupted thread. If the interrupted thread was a privileged
|
||||
* thread, that will be the MSP otherwise it will be the PSP. If the PSP is used, then the
|
||||
* value of the MSP will be invalid when the interrupt handler returns because it will be a
|
||||
* pointer to an old position in the unprivileged stack. Then when the high priority
|
||||
* interrupt occurs and uses this stale MSP, there will most likely be a system failure.
|
||||
*
|
||||
* If the interrupt stack is selected, on the other hand, then the interrupt handler will
|
||||
* always set the MSP to the interrupt stack. So when the high priority interrupt occurs,
|
||||
* it will either use the MSP of the last privileged thread to run or, in the case of the
|
||||
* nested interrupt, the interrupt stack if no privileged task has run.
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4
|
||||
# error Interrupt stack must be used with high priority interrupts in kernel mode
|
||||
# endif
|
||||
|
||||
/* Use the BASEPRI to control interrupts is required if nested, high
|
||||
* priority interrupts are supported.
|
||||
*/
|
||||
|
||||
# ifndef CONFIG_ARMV8M_USEBASEPRI
|
||||
# error CONFIG_ARMV8M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/************************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************************/
|
||||
|
||||
.globl exception_common
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "up_lazyexception.S"
|
||||
|
||||
/************************************************************************************************
|
||||
* Macro Definitions
|
||||
************************************************************************************************/
|
||||
|
||||
/************************************************************************************************
|
||||
* Name: setintstack
|
||||
*
|
||||
* Description:
|
||||
* Set the current stack pointer to the "top" the interrupt stack. Single CPU case. Must be
|
||||
* provided by MCU-specific logic in chip.h for the SMP case.
|
||||
*
|
||||
************************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.macro setintstack, tmp1, tmp2
|
||||
ldr sp, =g_intstackbase
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/************************************************************************************************
|
||||
* .text
|
||||
************************************************************************************************/
|
||||
|
||||
/* Common IRQ handling logic. On entry here, the return stack is on either
|
||||
* the PSP or the MSP and looks like the following:
|
||||
*
|
||||
* REG_XPSR
|
||||
* REG_R15
|
||||
* REG_R14
|
||||
* REG_R12
|
||||
* REG_R3
|
||||
* REG_R2
|
||||
* REG_R1
|
||||
* MSP->REG_R0
|
||||
*
|
||||
* And
|
||||
* IPSR contains the IRQ number
|
||||
* R14 Contains the EXC_RETURN value
|
||||
* We are in handler mode and the current SP is the MSP
|
||||
*/
|
||||
|
||||
.text
|
||||
.type exception_common, function
|
||||
|
||||
exception_common:
|
||||
|
||||
/* Get the IRQ number from the IPSR */
|
||||
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
|
||||
/* Complete the context save */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
|
||||
* (handler mode) if the stack is on the MSP. It can only be on the PSP if
|
||||
* EXC_RETURN is 0xfffffffd (unprivileged thread)
|
||||
*/
|
||||
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 1f /* Branch if context already on the MSP */
|
||||
mrs r1, psp /* R1=The process stack pointer (PSP) */
|
||||
mov sp, r1 /* Set the MSP to the PSP */
|
||||
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* r1 holds the value of the stack pointer AFTER the exception handling logic
|
||||
* pushed the various registers onto the stack. Get r2 = the value of the
|
||||
* stack pointer BEFORE the interrupt modified it.
|
||||
*/
|
||||
|
||||
mov r2, sp /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
mrs r3, basepri /* R3=Current BASEPRI setting */
|
||||
#else
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Skip over the block of memory reserved for floating pointer register save.
|
||||
* Lazy FPU register saving is used. FPU registers will be saved in this
|
||||
* block only if a context switch occurs (this means, of course, that the FPU
|
||||
* cannot be used in interrupt processing).
|
||||
*/
|
||||
|
||||
sub sp, #(4*SW_FPU_REGS)
|
||||
#endif
|
||||
|
||||
/* Save the remaining registers on the stack after the registers pushed
|
||||
* by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11,
|
||||
* r14=register values.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
|
||||
#else
|
||||
stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */
|
||||
#endif
|
||||
|
||||
/* There are two arguments to up_doirq:
|
||||
*
|
||||
* R0 = The IRQ number
|
||||
* R1 = The top of the stack points to the saved state
|
||||
*/
|
||||
|
||||
mov r1, sp
|
||||
|
||||
/* Also save the top of the stack in a preserved register */
|
||||
|
||||
mov r4, sp
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
/* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use
|
||||
* a special special interrupt stack pointer. The way that this is done
|
||||
* here prohibits nested interrupts without some additional logic!
|
||||
*/
|
||||
|
||||
setintstack r2, r3
|
||||
|
||||
#else
|
||||
/* Otherwise, we will re-use the interrupted thread's stack. That may
|
||||
* mean using either MSP or PSP stack for interrupt level processing (in
|
||||
* kernel mode).
|
||||
*/
|
||||
|
||||
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
|
||||
mov sp, r2 /* Instantiate the aligned stack */
|
||||
|
||||
#endif
|
||||
|
||||
bl up_doirq /* R0=IRQ, R1=register save (msp) */
|
||||
mov r1, r4 /* Recover R1=main stack pointer */
|
||||
|
||||
/* On return from up_doirq, R0 will hold a pointer to register context
|
||||
* array to use for the interrupt return. If that return value is the same
|
||||
* as current stack pointer, then things are relatively easy.
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 2f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch.
|
||||
*
|
||||
* If the FPU is enabled, then we will need to restore FPU registers.
|
||||
* This is not done in normal interrupt save/restore because the cost
|
||||
* is prohibitive. This is only done when switching contexts. A
|
||||
* consequence of this is that floating point operations may not be
|
||||
* performed in interrupt handling logic.
|
||||
*
|
||||
* Here:
|
||||
* r0 = Address of the register save area
|
||||
*
|
||||
* NOTE: It is a requirement that up_restorefpu() preserve the value of
|
||||
* r0!
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
bl up_restorefpu /* Restore the FPU registers */
|
||||
#endif
|
||||
|
||||
/* We are returning with a pending context switch. This case is different
|
||||
* because in this case, the register save structure does not lie in the
|
||||
* stack but, rather, within a TCB structure. We'll have to copy some
|
||||
* values to the stack.
|
||||
*/
|
||||
|
||||
add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */
|
||||
ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */
|
||||
ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */
|
||||
stmdb r1!, {r4-r11} /* Store eight registers in HW save area */
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#else
|
||||
ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
#endif
|
||||
b 3f /* Re-join common logic */
|
||||
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created
|
||||
*
|
||||
* Here:
|
||||
* r1 = Address of the return stack (same as r0)
|
||||
*/
|
||||
|
||||
2:
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#else
|
||||
ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Skip over the block of memory reserved for floating pointer register
|
||||
* save. Then R1 is the address of the HW save area
|
||||
*/
|
||||
|
||||
add r1, #(4*SW_FPU_REGS)
|
||||
#endif
|
||||
|
||||
/* Set up to return from the exception
|
||||
*
|
||||
* Here:
|
||||
* r1 = Address on the target thread's stack position at the start of
|
||||
* the registers saved by hardware
|
||||
* r3 = primask or basepri
|
||||
* r4-r11 = restored register values
|
||||
*/
|
||||
|
||||
3:
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
|
||||
* (handler mode) if the stack is on the MSP. It can only be on the PSP if
|
||||
* EXC_RETURN is 0xfffffffd (unprivileged thread)
|
||||
*/
|
||||
|
||||
mrs r2, control /* R2=Contents of the control register */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 4f /* Branch if privileged */
|
||||
|
||||
orr r2, r2, #1 /* Unprivileged mode */
|
||||
msr psp, r1 /* R1=The process stack pointer */
|
||||
b 5f
|
||||
4:
|
||||
bic r2, r2, #1 /* Privileged mode */
|
||||
msr msp, r1 /* R1=The main stack pointer */
|
||||
5:
|
||||
msr control, r2 /* Save the updated control register */
|
||||
#else
|
||||
msr msp, r1 /* Recover the return MSP value */
|
||||
|
||||
/* Preload r14 with the special return value first (so that the return
|
||||
* actually occurs with interrupts still disabled).
|
||||
*/
|
||||
|
||||
ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */
|
||||
#endif
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
#ifdef CONFIG_ARMV8M_USEBASEPRI
|
||||
msr basepri, r3 /* Restore interrupts priority masking */
|
||||
#else
|
||||
msr primask, r3 /* Restore interrupts */
|
||||
#endif
|
||||
|
||||
/* Always return with R14 containing the special value that will: (1)
|
||||
* return to thread mode, and (2) continue to use the MSP
|
||||
*/
|
||||
|
||||
bx r14 /* And return */
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
/************************************************************************************************
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
************************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.bss
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.align 8
|
||||
g_intstackalloc:
|
||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK + 4) & ~7)
|
||||
g_intstackbase:
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
.end
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/up_memfault.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 <arch/irq.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "nvic.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_MEMFAULT
|
||||
# define mferr(format, ...) _alert(format, ##__VA_ARGS__)
|
||||
# define mfinfo(format, ...) _alert(format, ##__VA_ARGS__)
|
||||
#else
|
||||
# define mferr(x...)
|
||||
# define mfinfo(x...)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_memfault
|
||||
*
|
||||
* Description:
|
||||
* This is Memory Management Fault exception handler. Normally we get
|
||||
* here when the Cortex M3 MPU is enabled and an MPU fault is detected.
|
||||
* However, I understand that there are other error conditions that can
|
||||
* also generate memory management faults.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_memfault(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
/* Dump some memory management fault info */
|
||||
|
||||
up_irq_save();
|
||||
_alert("PANIC!!! Memory Management Fault:\n");
|
||||
mfinfo(" IRQ: %d context: %p\n", irq, context);
|
||||
_alert(" CFAULTS: %08x MMFAR: %08x\n",
|
||||
getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
|
||||
mfinfo(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
|
||||
getbasepri(), getprimask(), getipsr(), getcontrol());
|
||||
|
||||
PANIC();
|
||||
return OK; /* Won't get here */
|
||||
}
|
||||
Executable
+388
@@ -0,0 +1,388 @@
|
||||
/*****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mpu.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/* Configuration *************************************************************/
|
||||
|
||||
#ifndef CONFIG_ARM_MPU_NREGIONS
|
||||
# define CONFIG_ARM_MPU_NREGIONS 8
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
*****************************************************************************/
|
||||
|
||||
/* These sets represent the set of disabled memory sub-regions. A bit set
|
||||
* corresponds to a disabled sub-region; the LS bit corresponds to the first
|
||||
* region.
|
||||
*
|
||||
* The g_ms_regionmask array is indexed by the number of subregions at the
|
||||
* end of the region: 0 means no sub-regions are available(0xff) and 8 means
|
||||
* all subregions are available (0x00).
|
||||
*/
|
||||
|
||||
static const uint8_t g_ms_regionmask[9] =
|
||||
{
|
||||
0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00
|
||||
};
|
||||
|
||||
/* The g_ls_regionmask array is indexed by the number of subregions at the
|
||||
* beginning of the region: 0 means no sub-regions need be disabled (0x00)
|
||||
* and 8 means all subregions must be disabled (0xff).
|
||||
*/
|
||||
|
||||
static const uint8_t g_ls_regionmask[9] =
|
||||
{
|
||||
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
|
||||
};
|
||||
|
||||
/* The next available region number */
|
||||
|
||||
static uint8_t g_region;
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_subregion_ms
|
||||
*
|
||||
* Description:
|
||||
* Given (1) the size of the memory to be mapped and (2) the log2 size
|
||||
* of the mapping to use, determine the minimal sub-region set at the
|
||||
* to be disabled at the higher end of the region.
|
||||
*
|
||||
* Assumption:
|
||||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size)
|
||||
{
|
||||
unsigned int nsrs;
|
||||
uint32_t asize;
|
||||
uint32_t mask;
|
||||
|
||||
/* Examples with l2size = 12:
|
||||
*
|
||||
* Shifted Adjusted Number Sub-Region
|
||||
* Size Mask Size Shift Sub-Regions Bitset
|
||||
* 0x1000 0x01ff 0x1000 9 8 0x00
|
||||
* 0x0c00 0x01ff 0x0c00 9 6 0xc0
|
||||
* 0x0c40 0x01ff 0x0e00 9 7 0x80
|
||||
*/
|
||||
|
||||
if (l2size < 32)
|
||||
{
|
||||
mask = ((1 << l2size) - 1) >> 3; /* Shifted mask */
|
||||
}
|
||||
|
||||
/* The 4Gb region size is a special case */
|
||||
|
||||
else
|
||||
{
|
||||
/* NOTE: There is no way to represent a 4Gb region size in the 32-bit
|
||||
* input.
|
||||
*/
|
||||
|
||||
mask = 0x1fffffff; /* Shifted mask */
|
||||
}
|
||||
|
||||
asize = (size + mask) & ~mask; /* Adjusted size */
|
||||
nsrs = asize >> (l2size - 3); /* Number of subregions */
|
||||
return g_ms_regionmask[nsrs];
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_subregion_ls
|
||||
*
|
||||
* Description:
|
||||
* Given (1) the offset to the beginning of data in the region and (2) the
|
||||
* log2 size of the mapping to use, determine the minimal sub-region set
|
||||
* to span that memory region sub-region set at the to be disabled at the
|
||||
* lower end of the region
|
||||
*
|
||||
* Assumption:
|
||||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
||||
{
|
||||
unsigned int nsrs;
|
||||
uint32_t aoffset;
|
||||
uint32_t mask;
|
||||
|
||||
/* Examples with l2size = 12:
|
||||
*
|
||||
* Shifted Adjusted Number Sub-Region
|
||||
* Offset Mask Offset Shift Sub-Regions Bitset
|
||||
* 0x0000 0x01ff 0x0000 9 8 0x00
|
||||
* 0x0400 0x01ff 0x0400 9 6 0x03
|
||||
* 0x02c0 0x01ff 0x0200 9 7 0x01
|
||||
*/
|
||||
|
||||
if (l2size < 32)
|
||||
{
|
||||
mask = ((1 << l2size)-1) >> 3; /* Shifted mask */
|
||||
}
|
||||
|
||||
/* The 4Gb region size is a special case */
|
||||
|
||||
else
|
||||
{
|
||||
/* NOTE: There is no way to represent a 4Gb region size in the 32-bit
|
||||
* input.
|
||||
*/
|
||||
|
||||
mask = 0x1fffffff; /* Shifted mask */
|
||||
}
|
||||
|
||||
aoffset = offset & ~mask; /* Adjusted offset */
|
||||
nsrs = aoffset >> (l2size - 3); /* Number of subregions */
|
||||
return g_ls_regionmask[nsrs];
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Assumptions:
|
||||
* - Regions are never deallocated
|
||||
* - Regions are only allocated early in initialization, so no special
|
||||
* protection against re-entrancy is required;
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void)
|
||||
{
|
||||
DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS);
|
||||
return (unsigned int)g_region++;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_log2regionceil
|
||||
*
|
||||
* Description:
|
||||
* Determine the smallest value of l2size (log base 2 size) such that the
|
||||
* following is true:
|
||||
*
|
||||
* size <= (1 << l2size)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionceil(size_t size)
|
||||
{
|
||||
uint8_t l2size;
|
||||
|
||||
/* The minimum permitted region size is 32 bytes (log2(32) = 5. */
|
||||
|
||||
for (l2size = 5; l2size < 32 && size > (1 << l2size); l2size++);
|
||||
return l2size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_log2regionfloor
|
||||
*
|
||||
* Description:
|
||||
* Determine the largest value of l2size (log base 2 size) such that the
|
||||
* following is true:
|
||||
*
|
||||
* size >= (1 << l2size)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionfloor(size_t size)
|
||||
{
|
||||
uint8_t l2size = mpu_log2regionceil(size);
|
||||
|
||||
if (l2size > 4 && size < (1 << l2size))
|
||||
{
|
||||
l2size--;
|
||||
}
|
||||
|
||||
return l2size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_subregion
|
||||
*
|
||||
* Description:
|
||||
* Given the size of the (1) memory to be mapped and (2) the log2 size
|
||||
* of the mapping to use, determine the minimal sub-region set to span
|
||||
* that memory region.
|
||||
*
|
||||
* Assumption:
|
||||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
||||
{
|
||||
uint32_t mask;
|
||||
size_t offset;
|
||||
uint32_t ret;
|
||||
|
||||
/* Eight subregions are supported. The representation is as an 8-bit
|
||||
* value with the LS bit corresponding to subregion 0. A bit is set
|
||||
* to disable the sub-region.
|
||||
*
|
||||
* l2size: Log2 of the actual region size is <= (1 << l2size);
|
||||
*/
|
||||
|
||||
DEBUGASSERT(l2size > 4 && size <= (1 << l2size));
|
||||
|
||||
/* For region sizes of 32, 64, and 128 bytes, the effect of setting
|
||||
* one or more bits of the SRD field to 1 is UNPREDICTABLE.
|
||||
*/
|
||||
|
||||
if (l2size < 8)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate the offset of the base address into the aligned region. */
|
||||
|
||||
mask = (1 << l2size) - 1;
|
||||
offset = base & mask;
|
||||
|
||||
/* Calculate the mask need to handle disabled subregions at the end of the
|
||||
* region
|
||||
*/
|
||||
|
||||
ret = mpu_subregion_ms(size + offset, l2size);
|
||||
|
||||
/* Then OR in the mask need to handle disabled subregions at the beginning
|
||||
* of the region.
|
||||
*/
|
||||
|
||||
ret |= mpu_subregion_ls(offset, l2size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_control
|
||||
*
|
||||
* Description:
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void mpu_control(bool enable, bool hfnmiena, bool privdefena)
|
||||
{
|
||||
uint32_t regval = 0;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
regval |= MPU_CTRL_ENABLE; /* Enable the MPU */
|
||||
|
||||
if (hfnmiena)
|
||||
{
|
||||
regval |= MPU_CTRL_HFNMIENA; /* Enable MPU during hard fault, NMI, and FAULTMAS */
|
||||
}
|
||||
|
||||
if (privdefena)
|
||||
{
|
||||
regval |= MPU_CTRL_PRIVDEFENA; /* Enable privileged access to default memory map */
|
||||
}
|
||||
}
|
||||
|
||||
putreg32(regval, MPU_CTRL);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
uintptr_t alignedbase;
|
||||
|
||||
/* Ensure the base address alignment
|
||||
*
|
||||
* ARMv8-M Architecture Reference Manual
|
||||
* B3.5.8 MPU Region Base Address Register, MPU_RBAR
|
||||
* "Software must ensure that the value written to the ADDR field
|
||||
* aligns with the size of the selected region."
|
||||
*/
|
||||
|
||||
alignedbase = base & MPU_RBAR_ADDR_MASK;
|
||||
l2size = mpu_log2regionceil(size + base - alignedbase);
|
||||
alignedbase &= ~((1 << l2size) - 1);
|
||||
l2size = mpu_log2regionceil(size + base - alignedbase);
|
||||
|
||||
DEBUGASSERT(alignedbase + (1 << l2size) >= base + size);
|
||||
DEBUGASSERT(l2size == 5 || alignedbase + (1 << (l2size - 1)) < base + size);
|
||||
DEBUGASSERT((alignedbase & MPU_RBAR_ADDR_MASK) == alignedbase);
|
||||
DEBUGASSERT((alignedbase & ((1 << l2size) - 1)) == 0);
|
||||
|
||||
/* Select the region */
|
||||
|
||||
putreg32(region, MPU_RNR);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
putreg32(alignedbase | region | MPU_RBAR_VALID, MPU_RBAR);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */
|
||||
flags;
|
||||
putreg32(regval, MPU_RASR);
|
||||
}
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/irq/up_ramvec_attach.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 <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMVECTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Common exception entrypoint */
|
||||
|
||||
void exception_common(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ramvec_attach
|
||||
*
|
||||
* Description:
|
||||
* Configure the ram vector table so that IRQ number 'irq' will be
|
||||
* dispatched by hardware to 'vector'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_ramvec_attach(int irq, up_vector_t vector)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
irqinfo("%s IRQ%d\n", vector ? "Attaching" : "Detaching", irq);
|
||||
|
||||
if ((unsigned)irq < ARMV8M_VECTAB_SIZE)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* If the new vector is NULL, then the vector is being detached. In
|
||||
* this case, disable the itnerrupt and direct any interrupts to the
|
||||
* common exception handler.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (vector == NULL)
|
||||
{
|
||||
/* Disable the interrupt if we can before detaching it. We might
|
||||
* not be able to do this for all interrupts.
|
||||
*/
|
||||
|
||||
up_disable_irq(irq);
|
||||
|
||||
/* Detaching the vector really means re-attaching it to the
|
||||
* common exception handler.
|
||||
*/
|
||||
|
||||
vector = exception_common;
|
||||
}
|
||||
|
||||
/* Save the new vector in the vector table */
|
||||
|
||||
g_ram_vectors[irq] = vector;
|
||||
leave_critical_section(flags);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_ARCH_RAMVECTORS */
|
||||
Executable
+154
@@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/up_ramvec_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/irq.h>
|
||||
|
||||
#include "nvic.h"
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#include "chip.h" /* May redefine VECTAB fields */
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMVECTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Vector Table Offset Register (VECTAB). This mask seems to vary among
|
||||
* ARMv8-M implementations. It may need to be redefined in some
|
||||
* architecture-specific header file. By default, the base address of the
|
||||
* new vector table must be aligned to the size of the vector table extended
|
||||
* to the next larger power of 2.
|
||||
*/
|
||||
|
||||
#ifndef NVIC_VECTAB_TBLOFF_MASK
|
||||
# if ARMV8M_VECTAB_SIZE > 512
|
||||
# define NVIC_VECTAB_TBLOFF_MASK (0xfffff000)
|
||||
# elif ARMV8M_VECTAB_SIZE > 256
|
||||
# define NVIC_VECTAB_TBLOFF_MASK (0xfffff800)
|
||||
# elif ARMV8M_VECTAB_SIZE > 128
|
||||
# define NVIC_VECTAB_TBLOFF_MASK (0xfffffc00)
|
||||
# elif ARMV8M_VECTAB_SIZE > 64
|
||||
# define NVIC_VECTAB_TBLOFF_MASK (0xfffffe00)
|
||||
# elif ARMV8M_VECTAB_SIZE > 32
|
||||
# define NVIC_VECTAB_TBLOFF_MASK (0xffffff00)
|
||||
# else
|
||||
# define NVIC_VECTAB_TBLOFF_MASK (0xffffff80)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Alignment ****************************************************************/
|
||||
|
||||
/* Per the ARMv8M Architecture reference manual, the NVIC vector table
|
||||
* requires 7-bit address alignment (i.e, bits 0-6 of the address of the
|
||||
* vector table must be zero). In this case alignment to a 128 byte address
|
||||
* boundary is sufficient.
|
||||
*
|
||||
* Some parts, such as the LPC17xx/LPC40xx family, require alignment to a 256
|
||||
* byte address boundary. Any other unusual alignment requirements for the
|
||||
* vector can be specified for a given architecture be redefining
|
||||
* NVIC_VECTAB_TBLOFF_MASK in the chip-specific chip.h header file for the
|
||||
* appropriate mask.
|
||||
*/
|
||||
|
||||
#define RAMVEC_ALIGN ((~NVIC_VECTAB_TBLOFF_MASK & 0xffff) + 1)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* If CONFIG_ARCH_RAMVECTORS is defined, then the ARM logic must provide
|
||||
* ARM-specific implementations of up_ramvec_initialize(), irq_attach(), and
|
||||
* irq_dispatch. In this case, it is also assumed that the ARM vector
|
||||
* table resides in RAM, has the name up_ram_vectors, and has been
|
||||
* properly positioned and aligned in memory by the linker script.
|
||||
*
|
||||
* REVISIT: Can this alignment requirement vary from core-to-core? Yes, it
|
||||
* depends on the number of vectors supported by the MCU. The safest thing
|
||||
* to do is to put the vector table at the beginning of RAM in order toforce
|
||||
* the highest alignment possible.
|
||||
*/
|
||||
|
||||
up_vector_t g_ram_vectors[ARMV8M_VECTAB_SIZE]
|
||||
__attribute__ ((section (".ram_vectors"), aligned (RAMVEC_ALIGN)));
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ramvec_initialize
|
||||
*
|
||||
* Description:
|
||||
* Copy vectors to RAM an configure the NVIC to use the RAM vectors.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_ramvec_initialize(void)
|
||||
{
|
||||
const up_vector_t *src;
|
||||
up_vector_t *dest;
|
||||
int i;
|
||||
|
||||
/* The vector table must be aligned */
|
||||
|
||||
DEBUGASSERT(((uint32_t)g_ram_vectors & ~NVIC_VECTAB_TBLOFF_MASK) == 0);
|
||||
|
||||
/* Copy the ROM vector table at address zero to RAM vector table.
|
||||
*
|
||||
* This must be done BEFORE the MPU is enable if the MPU is being used to
|
||||
* protect against NULL pointer references.
|
||||
*/
|
||||
|
||||
src = (const CODE up_vector_t *)getreg32(NVIC_VECTAB);
|
||||
dest = g_ram_vectors;
|
||||
|
||||
irqinfo("src=%p dest=%p\n", src, dest);
|
||||
|
||||
for (i = 0; i < ARMV8M_VECTAB_SIZE; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
/* Now configure the NVIC to use the new vector table. */
|
||||
|
||||
putreg32((uint32_t)g_ram_vectors, NVIC_VECTAB);
|
||||
|
||||
/* The number bits required to align the RAM vector table seem to vary
|
||||
* from part-to-part. The following assertion will catch the case where
|
||||
* the table alignment is insufficient.
|
||||
*/
|
||||
|
||||
irqinfo("NVIC_VECTAB=%08x\n", getreg32(NVIC_VECTAB));
|
||||
DEBUGASSERT(getreg32(NVIC_VECTAB) == (uint32_t)g_ram_vectors);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_ARCH_RAMVECTORS */
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.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 0
|
||||
sched_lock();
|
||||
#endif
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.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 */
|
||||
|
||||
up_restorestate(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.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+174
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv8-m/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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.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.
|
||||
*
|
||||
* Input Parameters:
|
||||
* 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.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.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 */
|
||||
|
||||
up_restorestate(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.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv8-m/gnu/up_saveusercontext.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 <arch/irq.h>
|
||||
|
||||
#include "nvic.h"
|
||||
#include "svcall.h"
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "up_saveusercontext.S"
|
||||
|
||||
/************************************************************************************
|
||||
* Macros
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_saveusercontext
|
||||
*
|
||||
* Description:
|
||||
* Save the current thread context. Full prototype is:
|
||||
*
|
||||
* int up_saveusercontext(uint32_t *saveregs);
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: Normal return
|
||||
* 1: Context switch return
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.text
|
||||
.thumb_func
|
||||
.globl up_saveusercontext
|
||||
.type up_saveusercontext, function
|
||||
up_saveusercontext:
|
||||
|
||||
/* Perform the System call with R0=0 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_save_context /* R0: save context (also return value) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* There are two return conditions. On the first return, R0 (the
|
||||
* return value will be zero. On the second return we need to
|
||||
* force R0 to be 1.
|
||||
*/
|
||||
|
||||
add r2, r1, #(4*REG_R0)
|
||||
mov r3, #1
|
||||
str r3, [r2, #0]
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
.size up_saveusercontext, .-up_saveusercontext
|
||||
.end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user