Merge remote-tracking branch 'upstream/master'

This commit is contained in:
pnb 2015-12-20 13:00:17 +01:00
commit 510dc7872d
149 changed files with 17794 additions and 406 deletions

View file

@ -68,6 +68,7 @@ config ARCH_CHIP_KINETIS
bool "Freescale Kinetis"
select ARCH_CORTEXM4
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_FPU
select ARCH_HAVE_RAMFUNCS
---help---
@ -84,6 +85,7 @@ config ARCH_CHIP_LM
bool "TI/Luminary Stellaris"
select ARCH_HAVE_CMNVECTOR
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
---help---
TI/Luminary Stellaris LMS3 and LM4F architectures (ARM Cortex-M3/4)
@ -91,6 +93,7 @@ config ARCH_CHIP_TIVA
bool "TI Tiva"
select ARCH_HAVE_CMNVECTOR
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_FPU
---help---
TI Tiva TM4C architectures (ARM Cortex-M4)
@ -107,6 +110,7 @@ config ARCH_CHIP_LPC17XX
select ARCH_CORTEXM3
select ARCH_HAVE_CMNVECTOR
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
---help---
NXP LPC17xx architectures (ARM Cortex-M3)
@ -137,6 +141,7 @@ config ARCH_CHIP_LPC43XX
select ARCH_HAVE_CMNVECTOR
select ARMV7M_CMNVECTOR
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_FPU
---help---
NPX LPC43XX architectures (ARM Cortex-M4).
@ -178,6 +183,7 @@ config ARCH_CHIP_SAM34
bool "Atmel SAM3/SAM4"
select ARCH_HAVE_CMNVECTOR
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_RAMFUNCS
select ARMV7M_HAVE_STACKCHECK
---help---
@ -189,6 +195,7 @@ config ARCH_CHIP_SAMV7
select ARMV7M_CMNVECTOR
select ARCH_CORTEXM7
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_RAMFUNCS
select ARCH_HAVE_TICKLESS
select ARMV7M_HAVE_STACKCHECK
@ -199,6 +206,7 @@ config ARCH_CHIP_STM32
bool "STMicro STM32 F1/F2/F3/F4"
select ARCH_HAVE_CMNVECTOR
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_I2CRESET
select ARCH_HAVE_HEAPCHECK
select ARMV7M_HAVE_STACKCHECK
@ -211,6 +219,7 @@ config ARCH_CHIP_STM32F7
select ARMV7M_CMNVECTOR
select ARCH_CORTEXM7
select ARCH_HAVE_MPU
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_I2CRESET
select ARCH_HAVE_HEAPCHECK
select ARMV7M_HAVE_STACKCHECK
@ -224,6 +233,14 @@ config ARCH_CHIP_STR71X
---help---
STMicro STR71x architectures (ARM7TDMI).
config ARCH_CHIP_TMS570
bool "TI TMS570"
select ARCH_HAVE_LOWVECTORS
select ARCH_HAVE_RAMFUNCS
select ARMV7R_MEMINIT
---help---
TI TMS570 family
config ARCH_CHIP_MOXART
bool "MoxART"
select ARCH_ARM7TDMI
@ -279,6 +296,7 @@ config ARCH_CORTEXM7
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_RAMVECTORS
select ARCH_HAVE_HIPRI_INTERRUPT
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXA5
bool
@ -286,7 +304,7 @@ config ARCH_CORTEXA5
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MMU
select ARCH_USE_MMU
select ARCH_HAVE_COHERENT_DCACHE if ELF
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXA8
bool
@ -294,7 +312,52 @@ config ARCH_CORTEXA8
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MMU
select ARCH_USE_MMU
select ARCH_HAVE_COHERENT_DCACHE if ELF
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXR4
bool
default n
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MPU
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXR4F
bool
default n
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MPU
select ARCH_HAVE_FPU
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXR5
bool
default n
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MPU
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEX5F
bool
default n
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MPU
select ARCH_HAVE_FPU
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXR7
bool
default n
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MPU
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_CORTEXR7F
bool
default n
select ARCH_HAVE_IRQPRIO
select ARCH_HAVE_MPU
select ARCH_HAVE_FPU
select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE
config ARCH_FAMILY
string
@ -302,6 +365,7 @@ config ARCH_FAMILY
default "armv6-m" if ARCH_CORTEXM0
default "armv7-a" if ARCH_CORTEXA5 || ARCH_CORTEXA8
default "armv7-m" if ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7
default "armv7-r" if ARCH_CORTEXR4 || ARCH_CORTEXR4F || ARCH_CORTEXR5 || ARCH_CORTEXR5F || ARCH_CORTEX74 || ARCH_CORTEXR7F
config ARCH_CHIP
string
@ -328,6 +392,7 @@ config ARCH_CHIP
default "stm32" if ARCH_CHIP_STM32
default "stm32f7" if ARCH_CHIP_STM32F7
default "str71x" if ARCH_CHIP_STR71X
default "tms570" if ARCH_CHIP_TMS570
default "moxart" if ARCH_CHIP_MOXART
config ARMV7M_USEBASEPRI
@ -415,7 +480,11 @@ config ARCH_DPFPU
Enable toolchain support for double precision (64-bit) floating
point if both the toolchain and the hardware support it.
config ARMV7M_MPU
config ARM_HAVE_MPU_UNIFIED
bool
default n
config ARM_MPU
bool "MPU support"
default n
depends on ARCH_HAVE_MPU
@ -425,11 +494,11 @@ config ARMV7M_MPU
Check your chip specifications first; not all Cortex-M3/4 chips
support the MPU.
config ARMV7M_MPU_NREGIONS
config ARM_MPU_NREGIONS
int "Number of MPU regions"
default 16 if ARCH_CORTEXM7
default 8 if !ARCH_CORTEXM7
depends on ARMV7M_MPU
depends on ARM_MPU
---help---
This is the number of protection regions supported by the MPU.
@ -468,6 +537,9 @@ endif
if ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7
source arch/arm/src/armv7-m/Kconfig
endif
if ARCH_CORTEXR4 || ARCH_CORTEXR4F || ARCH_CORTEXR5 || ARCH_CORTEXR5F || ARCH_CORTEX74 || ARCH_CORTEXR7F
source arch/arm/src/armv7-r/Kconfig
endif
if ARCH_ARM7TDMI || ARCH_ARM926EJS || ARCH_ARM920T
source arch/arm/src/arm/Kconfig
endif
@ -540,6 +612,9 @@ endif
if ARCH_CHIP_STR71X
source arch/arm/src/str71x/Kconfig
endif
if ARCH_CHIP_TMS570
source arch/arm/src/tms570/Kconfig
endif
if ARCH_CHIP_MOXART
source arch/arm/src/moxart/Kconfig
endif

View file

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/include/armv-7a/syscall.h
* arch/arm/include/armv7-a/syscall.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>

View file

@ -0,0 +1,412 @@
/****************************************************************************
* arch/arm/include/armv7-r/irq.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
****************************************************************************/
/* This file should never be included directed but, rather, only indirectly
* through nuttx/irq.h
*/
#ifndef __ARCH_ARM_INCLUDE_ARMV7_R_IRQ_H
#define __ARCH_ARM_INCLUDE_ARMV7_R_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
# include <arch/arch.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* IRQ Stack Frame Format:
*
* Context is always saved/restored in the same way:
*
* (1) stmia rx, {r0-r14}
* (2) then the PC and CPSR
*
* This results in the following set of indices that can be used to access
* individual registers in the xcp.regs array:
*/
#define REG_R0 (0)
#define REG_R1 (1)
#define REG_R2 (2)
#define REG_R3 (3)
#define REG_R4 (4)
#define REG_R5 (5)
#define REG_R6 (6)
#define REG_R7 (7)
#define REG_R8 (8)
#define REG_R9 (9)
#define REG_R10 (10)
#define REG_R11 (11)
#define REG_R12 (12)
#define REG_R13 (13)
#define REG_R14 (14)
#define REG_R15 (15)
#define REG_CPSR (16)
#define ARM_CONTEXT_REGS (17)
/* 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 double word 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 (ARM_CONTEXT_REGS+0) /* D0 */
# define REG_S0 (ARM_CONTEXT_REGS+0) /* S0 */
# define REG_S1 (ARM_CONTEXT_REGS+1) /* S1 */
# define REG_D1 (ARM_CONTEXT_REGS+2) /* D1 */
# define REG_S2 (ARM_CONTEXT_REGS+2) /* S2 */
# define REG_S3 (ARM_CONTEXT_REGS+3) /* S3 */
# define REG_D2 (ARM_CONTEXT_REGS+4) /* D2 */
# define REG_S4 (ARM_CONTEXT_REGS+4) /* S4 */
# define REG_S5 (ARM_CONTEXT_REGS+5) /* S5 */
# define REG_D3 (ARM_CONTEXT_REGS+6) /* D3 */
# define REG_S6 (ARM_CONTEXT_REGS+6) /* S6 */
# define REG_S7 (ARM_CONTEXT_REGS+7) /* S7 */
# define REG_D4 (ARM_CONTEXT_REGS+8) /* D4 */
# define REG_S8 (ARM_CONTEXT_REGS+8) /* S8 */
# define REG_S9 (ARM_CONTEXT_REGS+9) /* S9 */
# define REG_D5 (ARM_CONTEXT_REGS+10) /* D5 */
# define REG_S10 (ARM_CONTEXT_REGS+10) /* S10 */
# define REG_S11 (ARM_CONTEXT_REGS+11) /* S11 */
# define REG_D6 (ARM_CONTEXT_REGS+12) /* D6 */
# define REG_S12 (ARM_CONTEXT_REGS+12) /* S12 */
# define REG_S13 (ARM_CONTEXT_REGS+13) /* S13 */
# define REG_D7 (ARM_CONTEXT_REGS+14) /* D7 */
# define REG_S14 (ARM_CONTEXT_REGS+14) /* S14 */
# define REG_S15 (ARM_CONTEXT_REGS+15) /* S15 */
# define REG_D8 (ARM_CONTEXT_REGS+16) /* D8 */
# define REG_S16 (ARM_CONTEXT_REGS+16) /* S16 */
# define REG_S17 (ARM_CONTEXT_REGS+17) /* S17 */
# define REG_D9 (ARM_CONTEXT_REGS+18) /* D9 */
# define REG_S18 (ARM_CONTEXT_REGS+18) /* S18 */
# define REG_S19 (ARM_CONTEXT_REGS+19) /* S19 */
# define REG_D10 (ARM_CONTEXT_REGS+20) /* D10 */
# define REG_S20 (ARM_CONTEXT_REGS+20) /* S20 */
# define REG_S21 (ARM_CONTEXT_REGS+21) /* S21 */
# define REG_D11 (ARM_CONTEXT_REGS+22) /* D11 */
# define REG_S22 (ARM_CONTEXT_REGS+22) /* S22 */
# define REG_S23 (ARM_CONTEXT_REGS+23) /* S23 */
# define REG_D12 (ARM_CONTEXT_REGS+24) /* D12 */
# define REG_S24 (ARM_CONTEXT_REGS+24) /* S24 */
# define REG_S25 (ARM_CONTEXT_REGS+25) /* S25 */
# define REG_D13 (ARM_CONTEXT_REGS+26) /* D13 */
# define REG_S26 (ARM_CONTEXT_REGS+26) /* S26 */
# define REG_S27 (ARM_CONTEXT_REGS+27) /* S27 */
# define REG_D14 (ARM_CONTEXT_REGS+28) /* D14 */
# define REG_S28 (ARM_CONTEXT_REGS+28) /* S28 */
# define REG_S29 (ARM_CONTEXT_REGS+29) /* S29 */
# define REG_D15 (ARM_CONTEXT_REGS+30) /* D15 */
# define REG_S30 (ARM_CONTEXT_REGS+30) /* S30 */
# define REG_S31 (ARM_CONTEXT_REGS+31) /* S31 */
# define REG_FPSCR (ARM_CONTEXT_REGS+32) /* Floating point status and control */
# define FPU_CONTEXT_REGS (33)
#else
# define FPU_CONTEXT_REGS (0)
#endif
/* The total number of registers saved by software */
#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS)
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
/* Friendly 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
{
#ifdef CONFIG_BUILD_KERNEL
uint32_t cpsr; /* The CPSR value */
#endif
uint32_t sysreturn; /* The return PC */
};
#endif
/* This struct defines the way the registers are stored. We need to save:
*
* 1 CPSR
* 7 Static registers, v1-v7 (aka r4-r10)
* 1 Frame pointer, fp (aka r11)
* 1 Stack pointer, sp (aka r13)
* 1 Return address, lr (aka r14)
* ---
* 11 (XCPTCONTEXT_USER_REG)
*
* On interrupts, we also need to save:
* 4 Volatile registers, a1-a4 (aka r0-r3)
* 1 Scratch Register, ip (aka r12)
*---
* 5 (XCPTCONTEXT_IRQ_REGS)
*
* For a total of 17 (XCPTCONTEXT_REGS)
*/
#ifndef __ASSEMBLY__
struct xcptcontext
{
/* The following function pointer is non-zero if there are pending signals
* to be processed.
*/
#ifndef CONFIG_DISABLE_SIGNALS
void *sigdeliver; /* Actual type is sig_deliver_t */
/* These are saved copies of LR and CPSR used during signal processing. */
uint32_t saved_pc;
uint32_t saved_cpsr;
# ifdef CONFIG_BUILD_KERNEL
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
uint32_t sigreturn;
# endif
#endif
/* Register save area */
uint32_t regs[XCPTCONTEXT_REGS];
/* Extra fault address register saved for common paging logic. In the
* case of the pre-fetch abort, this value is the same as regs[REG_R15];
* For the case of the data abort, this value is the value of the fault
* address register (FAR) at the time of data abort exception.
*/
#ifdef CONFIG_PAGING
uintptr_t far;
#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
#ifdef CONFIG_ARCH_ADDRENV
#ifdef CONFIG_ARCH_STACK_DYNAMIC
/* This array holds the physical address of the level 2 page table used
* to map the thread's stack memory. This array will be initially of
* zeroed and would be back-up up with pages during page fault exception
* handling to support dynamically sized stacks for each thread.
*/
FAR uintptr_t *ustack[ARCH_STACK_NSECTS];
#endif
#ifdef CONFIG_ARCH_KERNEL_STACK
/* In this configuration, all syscalls execute from an internal kernel
* stack. Why? Because when we instantiate and initialize the address
* environment of the new user process, we will temporarily lose the
* address environment of the old user process, including its stack
* contents. The kernel C logic will crash immediately with no valid
* stack in place.
*/
FAR uint32_t *ustkptr; /* Saved user stack pointer */
FAR uint32_t *kstack; /* Allocate base of the (aligned) kernel stack */
#ifndef CONFIG_DISABLE_SIGNALS
FAR uint32_t *kstkptr; /* Saved kernel stack pointer */
#endif
#endif
#endif
};
#endif
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
/* Return the current IRQ state */
static inline irqstate_t irqstate(void)
{
unsigned int cpsr;
__asm__ __volatile__
(
"\tmrs %0, cpsr\n"
: "=r" (cpsr)
:
: "memory"
);
return cpsr;
}
/* Disable IRQs and return the previous IRQ state */
static inline irqstate_t irqsave(void)
{
unsigned int cpsr;
__asm__ __volatile__
(
"\tmrs %0, cpsr\n"
"\tcpsid i\n"
#if defined(CONFIG_ARMV7A_DECODEFIQ)
"\tcpsid f\n"
#endif
: "=r" (cpsr)
:
: "memory"
);
return cpsr;
}
/* Enable IRQs and return the previous IRQ state */
static inline irqstate_t irqenable(void)
{
unsigned int cpsr;
__asm__ __volatile__
(
"\tmrs %0, cpsr\n"
"\tcpsie i\n"
#if defined(CONFIG_ARMV7A_DECODEFIQ)
"\tcpsie f\n"
#endif
: "=r" (cpsr)
:
: "memory"
);
return cpsr;
}
/* Restore saved IRQ & FIQ state */
static inline void irqrestore(irqstate_t flags)
{
__asm__ __volatile__
(
"msr cpsr_c, %0"
:
: "r" (flags)
: "memory"
);
}
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif
#endif /* __ARCH_ARM_INCLUDE_ARMV7_R_IRQ_H */

View file

@ -0,0 +1,243 @@
/****************************************************************************
* arch/arm/include/armv7-r/syscall.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
****************************************************************************/
/* This file should never be included directed but, rather, only indirectly
* through include/syscall.h or include/sys/sycall.h
*/
#ifndef __ARCH_ARM_INCLUDE_ARMV7_R_SYSCALL_H
#define __ARCH_ARM_INCLUDE_ARMV7_R_SYSCALL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SYS_syscall 0x900001
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
/* SVC with SYS_ call number and no parameters */
static inline uintptr_t sys_call0(unsigned int nbr)
{
register long reg0 __asm__("r0") = (long)(nbr);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(SYS_syscall), "r"(reg0)
: "memory", "r14"
);
return reg0;
}
/* SVC with SYS_ call number and one parameter */
static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg1 __asm__("r1") = (long)(parm1);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(SYS_syscall), "r"(reg0), "r"(reg1)
: "memory", "r14"
);
return reg0;
}
/* SVC with SYS_ call number and two parameters */
static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2)
{
register long reg0 __asm__("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", "r14"
);
return reg0;
}
/* SVC with SYS_ call number and three parameters */
static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3)
{
register long reg0 __asm__("r0") = (long)(nbr);
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)
: "memory", "r14"
);
return reg0;
}
/* SVC with SYS_ call number and four parameters */
static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4)
{
register long reg0 __asm__("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", "r14"
);
return reg0;
}
/* SVC with SYS_ call number and five parameters */
static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5)
{
register long reg0 __asm__("r0") = (long)(nbr);
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)
: "memory", "r14"
);
return reg0;
}
/* SVC with SYS_ call number and six parameters */
static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5,
uintptr_t parm6)
{
register long reg0 __asm__("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", "r14"
);
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_ARMV7_R_SYSCALL_H */

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/include/irq.h
*
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -58,6 +58,10 @@
#if defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8)
# include <arch/armv7-a/irq.h>
#elif defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \
defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \
defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F)
# include <arch/armv7-r/irq.h>
#elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \
defined(CONFIG_ARCH_CORTEXM7)
# include <arch/armv7-m/irq.h>

View file

@ -0,0 +1,361 @@
/****************************************************************************************************
* arch/arm/include/tms570/chip.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
****************************************************************************************************/
#ifndef __ARCH_ARM_INCLUDE_TMS570_CHIP_H
#define __ARCH_ARM_INCLUDE_TMS570_CHIP_H
/****************************************************************************************************
* Included Files
****************************************************************************************************/
#include <nuttx/config.h>
/****************************************************************************************************
* Pre-processor Definitions
****************************************************************************************************/
/* TMS570LS0432PZ TMS570LS0332PZ TMS570LS0232PZ
* Package 100 QFP 100 QFP 100 QFP
* CPU ARM Cortex-R4 ARM Cortex-R4 ARM Cortex-R4
* Frequency (MHz) 80 80 80
* Flash (KB) 384 256 128
* RAM (KB) 32 32 32
* Data Flash (KB) 16 16 16
* EMAC
* FlexRay
* CAN 2 2 2
* MibADC (CH) 1 (16) 1 (16) 1 (16)
* N2HET (Ch) 1 (19) 1 (19) 1 (19)
* ePWM Channels
* eCAP Channels 0 0 0
* eQEP Channels 1 1 1
* MibSPI (CS) 1 (4) 1 (4) 1 (4)
* SPI (CS) 2 2 2
* SCI (LIN) 1 (1) 1 (1) 1 (1)
* I2C
* GPIO (INT) 45 (8) 45 (9) 45 (8)
* EMIF
* ETM (Trace)
* RTP/DMM
*/
#if defined(CONFIG_ARCH_CHIP_TMS570LS0232PZ)
# define TMS570_CORTEX_R4 1 /* Cortex-R4 family */
# undef TMS570_CORTEX_R4F /* Not Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (128*2014) /* 128 KB Program FLASH */
# define TMS570_SRAM (32*1024) /* 32 KB SRAM */
# define TMS570_DFLASH (16*1024) /* 16 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */
# define TMS570_NCAN 2 /* Two CAN */
# define TMS570_NMIBADC 1 /* One MiBADC */
# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */
# define TMS570_NN2HET 1 /* One N2HET */
# define TMS570_N2HET_NCH 19 /* 19 N2HET channels */
# define TMS570_EPWM_NCH 0 /* No ePWM channels */
# define TMS570_ECAP_NCH 0 /* No eCAP channels */
# define TMS570_EQEP_NCH 1 /* One eQEP channel */
# define TMS570_NMIBSPI 1 /* One MibSPI */
# define TMS570_MIBSPI1_NCS 4 /* MibSPI1: 4 chip selects */
# define TMS570_MIBSPI2_NCS 0 /* MibSPI2: No chip selects */
# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */
# define TMS570_NSPI 2 /* Two SPI */
# define TMS570_SPI1_NCS 0 /* SPI1: No chip selects */
# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */
# define TMS570_NSCI 1 /* One SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 0 /* No I2C */
# define TMS570_NGPIOINT 8 /* 8 GPIO interrupts */
# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
#elif defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ)
# define TMS570_CORTEX_R4 1 /* Cortex-R4 family */
# undef TMS570_CORTEX_R4F /* Not Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (256*2014) /* 256 KB Program FLASH */
# define TMS570_SRAM (32*1024) /* 32 KB SRAM */
# define TMS570_DFLASH (16*1024) /* 16 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */
# define TMS570_NCAN 2 /* Two CAN */
# define TMS570_NMIBADC 1 /* One MiBADC */
# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */
# define TMS570_NN2HET 1 /* One N2HET */
# define TMS570_N2HET_NCH 19 /* 19 N2HET channels */
# define TMS570_EPWM_NCH 0 /* No ePWM channels */
# define TMS570_ECAP_NCH 0 /* No eCAP channels */
# define TMS570_EQEP_NCH 1 /* One eQEP channel */
# define TMS570_NMIBSPI 1 /* One MibSPI */
# define TMS570_MIBSPI1_NCS 4 /* MibSPI1: 4 chip selects */
# define TMS570_MIBSPI2_NCS 0 /* MibSPI2: No chip selects */
# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */
# define TMS570_NSPI 2 /* Two SPI */
# define TMS570_SPI1_NCS 0 /* SPI1: No chip selects */
# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */
# define TMS570_NSCI 1 /* One SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 0 /* No I2C */
# define TMS570_NGPIOINT 9 /* 9 GPIO interrupts */
# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
#elif defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ)
# define TMS570_CORTEX_R4 1 /* Cortex-R4 family */
# undef TMS570_CORTEX_R4F /* Not Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (384*2014) /* 384 KB Program FLASH */
# define TMS570_SRAM (32*1024) /* 32 KB SRAM */
# define TMS570_DFLASH (16*1024) /* 16 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */
# define TMS570_NCAN 2 /* Two CAN */
# define TMS570_NMIBADC 1 /* One MiBADC */
# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */
# define TMS570_NN2HET 1 /* One N2HET */
# define TMS570_N2HET_NCH 19 /* 19 N2HET channels */
# define TMS570_EPWM_NCH 0 /* No ePWM channels */
# define TMS570_ECAP_NCH 0 /* No eCAP channels */
# define TMS570_EQEP_NCH 1 /* One eQEP channel */
# define TMS570_NMIBSPI 1 /* One MibSPI */
# define TMS570_MIBSPI1_NCS 4 /* MibSPI1: 4 chip selects */
# define TMS570_MIBSPI2_NCS 0 /* MibSPI2: No chip selects */
# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */
# define TMS570_NSPI 2 /* Two SPI */
# define TMS570_SPI1_NCS 0 /* SPI1: No chip selects */
# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */
# define TMS570_NSCI 1 /* One SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 0 /* No I2C */
# define TMS570_NGPIOINT 8 /* 8 GPIO interrupts */
# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
/* TMS570LS1227ZWT TMS570LS0714ZWT TMS570LS0714PGE TMS570LS0714PZ
* Package 337 BGA 337 BGA 144 QFP 100 QFP
* CPU ARM Cortex-R4F ARM Cortex-R4F ARM Cortex-R4F ARM Cortex-R4F
* Frequency (MHz) 180 180 160 100
* Flash (KB) 1280 768 768 768
* RAM (KB) 192 128 128 128
* Data Flash (KB) 64 64 64 64
* EMAC 10/100
* FlexRay 2-ch
* CAN 3 3 3 2
* MibADC (CH) 2 (24) 2 (24) 2 (24) 2 (16)
* N2HET (Ch) 2 (44) 2 (44) 2 (40) 2 (21)
* ePWM Channels 14 14 14 8
* eCAP Channels 6 6 6 4
* eQEP Channels 2 2 2 1
* MibSPI (CS) 3 (6+6+4) 3 (6+6+4) 3 (5+6+4) 2 (5+1)
* SPI (CS) 2 (2+1) 2 (2+1) 1 (1) 1 (1)
* SCI (LIN) 2 (1) 2 (1) 2 (1) 1 (1)
* I2C 1 1 1
* GPIO (INT) 101 (16) 101 (16) 64 (10) 45 (9)
* EMIF 16-bit data
* ETM (Trace)
* RTP/DMM
*/
#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PZ)
# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */
# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (768*2014) /* 768 KB Program FLASH */
# define TMS570_SRAM (128*1024) /* 128 KB SRAM */
# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */
# define TMS570_NCAN 3 /* Three CAN */
# define TMS570_NMIBADC 2 /* Two MiBADC */
# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */
# define TMS570_NN2HET 2 /* Two N2HET */
# define TMS570_N2HET_NCH 21 /* 21 N2HET channels */
# define TMS570_EPWM_NCH 8 /* 8 ePWM channels */
# define TMS570_ECAP_NCH 4 /* 4 eCAP channels */
# define TMS570_EQEP_NCH 1 /* 1 eQEP channels */
# define TMS570_NMIBSPI 2 /* 2 MibSPI */
# define TMS570_MIBSPI1_NCS 5 /* MibSPI1: 5 chip selects */
# define TMS570_MIBSPI2_NCS 1 /* MibSPI2: 1 chip selects */
# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */
# define TMS570_NSPI 1 /* One SPI */
# define TMS570_SPI1_NCS 1 /* SPI1: One chip selects */
# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */
# define TMS570_NSCI 1 /* One SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 0 /* No I2C */
# define TMS570_NGPIOINT 9 /* 9 GPIO interrupts */
# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PGE)
# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */
# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (768*2014) /* 768 KB Program FLASH */
# define TMS570_SRAM (128*1024) /* 128 KB SRAM */
# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */
# define TMS570_NCAN 3 /* Three CAN */
# define TMS570_NMIBADC 2 /* Two MiBADC */
# define TMS570_MIBADC_NCH 24 /* 24 MibADC channels */
# define TMS570_NN2HET 2 /* Two N2HET */
# define TMS570_N2HET_NCH 40 /* 40 N2HET channels */
# define TMS570_EPWM_NCH 14 /* 14 ePWM channels */
# define TMS570_ECAP_NCH 6 /* 6 eCAP channels */
# define TMS570_EQEP_NCH 2 /* 2 eQEP channels */
# define TMS570_NMIBSPI 3 /* 3 MibSPI */
# define TMS570_MIBSPI1_NCS 5 /* MibSPI1: 5 chip selects */
# define TMS570_MIBSPI2_NCS 6 /* MibSPI2: 6 chip selects */
# define TMS570_MIBSPI3_NCS 4 /* MibSPI3: 4 chip selects */
# define TMS570_NSPI 1 /* One SPI */
# define TMS570_SPI1_NCS 1 /* SPI1: One chip selects */
# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */
# define TMS570_NSCI 2 /* Two SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 1 /* One I2C */
# define TMS570_NGPIOINT 10 /* 16 GPIO interrupts */
# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714ZWT)
# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */
# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (768*2014) /* 768 KB Program FLASH */
# define TMS570_SRAM (128*1024) /* 128 KB SRAM */
# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */
# define TMS570_NCAN 3 /* Three CAN */
# define TMS570_NMIBADC 2 /* Two MiBADC */
# define TMS570_MIBADC_NCH 24 /* 24 MibADC channels */
# define TMS570_NN2HET 2 /* Two N2HET */
# define TMS570_N2HET_NCH 44 /* 44 N2HET channels */
# define TMS570_EPWM_NCH 14 /* 14 ePWM channels */
# define TMS570_ECAP_NCH 6 /* 6 eCAP channels */
# define TMS570_EQEP_NCH 2 /* 2 eQEP channels */
# define TMS570_NMIBSPI 3 /* 3 MibSPI */
# define TMS570_MIBSPI1_NCS 6 /* MibSPI1: 6 chip selects */
# define TMS570_MIBSPI2_NCS 6 /* MibSPI2: 6 chip selects */
# define TMS570_MIBSPI3_NCS 4 /* MibSPI3: 4 chip selects */
# define TMS570_NSPI 2 /* Two SPI */
# define TMS570_SPI1_NCS 2 /* SPI1: Two chip selects */
# define TMS570_SPI2_NCS 1 /* SPI2: One chip selects */
# define TMS570_NSCI 2 /* Two SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 1 /* One I2C */
# define TMS570_NGPIOINT 16 /* 16 GPIO interrupts */
# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
#elif defined(CONFIG_ARCH_CHIP_TMS570LS1227ZWT)
# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */
# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */
# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */
# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */
# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */
# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */
# define TMS570_PFLASH (1280*2014) /* 1,280 KB Program FLASH */
# define TMS570_SRAM (192*1024) /* 192 KB SRAM */
# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */
# define TMS570_NEMAC 1 /* One 10/100 Mbit EMAC */
# define TMS570_FLEXRAY_NCH 2 /* Two Flexray channels */
# define TMS570_NCAN 3 /* Three CAN */
# define TMS570_NMIBADC 2 /* Two MiBADC */
# define TMS570_MIBADC_NCH 24 /* 24 MibADC channels */
# define TMS570_NN2HET 2 /* Two N2HET */
# define TMS570_N2HET_NCH 44 /* 44 N2HET channels */
# define TMS570_EPWM_NCH 14 /* 14 ePWM channels */
# define TMS570_ECAP_NCH 6 /* 6 eCAP channels */
# define TMS570_EQEP_NCH 2 /* 2 eQEP channels */
# define TMS570_NMIBSPI 3 /* 3 MibSPI */
# define TMS570_MIBSPI1_NCS 6 /* MibSPI1: 6 chip selects */
# define TMS570_MIBSPI2_NCS 6 /* MibSPI2: 6 chip selects */
# define TMS570_MIBSPI3_NCS 4 /* MibSPI3: 4 chip selects */
# define TMS570_NSPI 2 /* Two SPI */
# define TMS570_SPI1_NCS 2 /* SPI1: Two chip selects */
# define TMS570_SPI2_NCS 1 /* SPI2: One chip selects */
# define TMS570_NSCI 2 /* Two SCI */
# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */
# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */
# define TMS570_NI2C 1 /* One I2C */
# define TMS570_NGPIOINT 16 /* 16 GPIO interrupts */
# define TMS570_NEMIF16 1 /* One EMIF 16-bit data */
# undef TMS570_ETM /* No ETM (trace) */
# undef TMS570_RTP /* No RAM trace port (RTP) */
# undef TMS570_DMM /* No DMM */
#else
# error Unrecognized TMS570 chip
#endif
#endif /* __ARCH_ARM_INCLUDE_TMS570_CHIP_H */

View file

@ -0,0 +1,94 @@
/****************************************************************************************
* arch/arm/include/tms570/irq.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
****************************************************************************************/
/* This file should never be included directed but, rather, only indirectly through
* nuttx/irq.h
*/
#ifndef __ARCH_ARM_INCLUDE_TMS570_IRQ_H
#define __ARCH_ARM_INCLUDE_TMS570_IRQ_H
/****************************************************************************************
* Included Files
****************************************************************************************/
#include <nuttx/config.h>
#include <arch/tms570/chip.h>
/****************************************************************************************
* Pre-processor Definitions
****************************************************************************************/
/* The interrupt vector table only has 96 entries, one phantom vector and 95 interrupt
* channels. Channel 95 does not have a dedicated vector and shall not be used.
*/
#define TMS570_IRQ_PHANTOM 0 /* The first is the "phantom" interrupt */
#define TMS570_IRQ_NCHANNELS 95 /* The "phantom" vector is followed by 95 real
* interrupt channels */
/* Total number of IRQ numbers */
#define NR_IRQS (95) /* Zero corresponds to channel 0, vector 1 */
/****************************************************************************************
* Public Types
****************************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************************
* Public Data
****************************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************************
* Public Function Prototypes
****************************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif
#endif /* __ARCH_ARM_INCLUDE_TMS570_IRQ_H */

View file

@ -40,6 +40,18 @@ ifeq ($(CONFIG_ARCH_CORTEXA5),y) # Cortex-A5 is ARMv7-A
ARCH_SUBDIR = armv7-a
else ifeq ($(CONFIG_ARCH_CORTEXA8),y) # Cortex-A8 is ARMv7-A
ARCH_SUBDIR = armv7-a
else ifeq ($(CONFIG_ARCH_CORTEXR4),y) # Cortex-R4 is ARMv7-R
ARCH_SUBDIR = armv7-r
else ifeq ($(CONFIG_ARCH_CORTEXR4F),y) # Cortex-R4F is ARMv7-R
ARCH_SUBDIR = armv7-r
else ifeq ($(CONFIG_ARCH_CORTEXR5),y) # Cortex-R5 is ARMv7-R
ARCH_SUBDIR = armv7-r
else ifeq ($(CONFIG_ARCH_CORTEXR5F),y) # Cortex-R5F is ARMv7-R
ARCH_SUBDIR = armv7-r
else ifeq ($(CONFIG_ARCH_CORTEXR7),y) # Cortex-R7 is ARMv7-R
ARCH_SUBDIR = armv7-r
else ifeq ($(CONFIG_ARCH_CORTEXR7F),y) # Cortex-R7F is ARMv7-R
ARCH_SUBDIR = armv7-r
else ifeq ($(CONFIG_ARCH_CORTEXM3),y) # Cortex-M3 is ARMv7-M
ARCH_SUBDIR = armv7-m
else ifeq ($(CONFIG_ARCH_CORTEXM4),y) # Cortex-M4 is ARMv7E-M

View file

@ -112,6 +112,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += arm_elf.c arm_coherent_dcache.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += arm_elf.c arm_coherent_dcache.c
endif
ifeq ($(CONFIG_ARCH_FPU),y)

View file

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/armv7/up_coherent_dcache.c
* arch/arm/src/armv7-a/up_coherent_dcache.c
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -44,7 +44,7 @@
#include "cp15_cacheops.h"
#include <nuttx/binfmt/elf.h>
#include <nuttx/arch.h>
/****************************************************************************
* Pre-processor Definitions

View file

@ -47,18 +47,6 @@
#ifdef CONFIG_ARCH_FPU
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
@ -76,7 +64,7 @@ void up_copyarmstate(uint32_t *dest, uint32_t *src)
{
int i;
/* In the Cortex-M model, the state is copied from the stack to the TCB,
/* In the Cortex-A 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:
*/

View file

@ -54,10 +54,13 @@
* Configuration
**********************************************************************************/
#undef ALIGNMENT_TRAP
/* Hard-coded options */
#undef CPU_ALIGNMENT_TRAP
#undef CPU_CACHE_ROUND_ROBIN
#undef CPU_DCACHE_DISABLE
#undef CPU_ICACHE_DISABLE
#undef CPU_AFE_ENABLE
/* There are three operational memory configurations:
*
@ -465,7 +468,7 @@ __start:
orr r0, r0, #(SCTLR_I)
#endif
#ifdef ALIGNMENT_TRAP
#ifdef CPU_ALIGNMENT_TRAP
/* Alignment abort enable
*
* SCTLR_A Bit 1: Strict alignment enabled
@ -474,7 +477,7 @@ __start:
orr r0, r0, #(SCTLR_A)
#endif
#ifdef CONFIG_AFE_ENABLE
#ifdef CPU_AFE_ENABLE
/* AP[0:2] Permissions model
*
* SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value).
@ -613,7 +616,7 @@ __start:
/* Set up the stack pointer and clear the frame pointer */
ldr sp, .Lstackpointer
mov fp, #0
mov fp, #0
#ifndef CONFIG_BOOT_SDRAM_DATA
/* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is

View file

@ -60,7 +60,6 @@
.global memcpy
.syntax unified
.thumb
.file "arm_memcpy.S"
@ -149,7 +148,6 @@ MEM_LongCopyTable:
************************************************************************************/
.align 4
.thumb_func
memcpy:
push {r14}
@ -160,7 +158,6 @@ memcpy:
.align 4
.thumb_func
_do_memcpy:
push {r14}

View file

@ -461,7 +461,7 @@ __start:
orr r0, r0, #(SCTLR_A)
#endif
#ifdef CONFIG_AFE_ENABLE
#ifdef CPU_AFE_ENABLE
/* AP[0:2] Permissions model
*
* SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value).

View file

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/armv7/arm_undefinedinsn.c
* arch/arm/src/armv7-a/arm_undefinedinsn.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>

View file

@ -74,7 +74,7 @@
#define _CP15(op1,rd,crn,crm,op2) p15, op1, rd, crn, crm, op2
#define CP15_MIDR(r) _CP15(0, r, c0, c0, 0) /* Main ID Register */
#define CP15_TR(r) _CP15(0, r, c0, c0, 1) /* Cache Type Register */
#define CP15_CTR(r) _CP15(0, r, c0, c0, 1) /* Cache Type Register */
#define CP15_TCMTR(r) _CP15(0, r, c0, c0, 2) /* TCM Type Register */
#define CP15_TLBTR(r) _CP15(0, r, c0, c0, 3) /* TLB Type Register */
#define CP15_MPIDR(r) _CP15(0, r, c0, c0, 5) /* Multiprocessor Affinity Register */
@ -158,10 +158,10 @@
#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* Invalidate data TLB by ASID match. CRm = c5, c6, or c7 */
#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* Invalidate unified TLB entry by MVA and ASID. CRm = c5, c6, or c7 */
#define CP15_MCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */
#define CP15_PMCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */
#define CP15_PMCNTENSET(r) _CP15(0, r, c9, c12, 1) /* Count Enable Set Register */
#define CP15_PMCNTENCLR(r) _CP15(0, r, c9, c12, 2) /* Count Enable Clear Register */
#define CP15_MOVSR(r) _CP15(0, r, c9, c12, 3) /* Overflow Flag Status Register */
#define CP15_PMOVSR(r) _CP15(0, r, c9, c12, 3) /* Overflow Flag Status Register */
#define CP15_PMSWINC(r) _CP15(0, r, c9, c12, 4) /* Software Increment Register */
#define CP15_PMSELR(r) _CP15(0, r, c9, c12, 5) /* Event Counter Selection Register */
#define CP15_PMCEID0(r) _CP15(0, r, c9, c12, 6) /* Common Event Identification Registers (Cortex-A5) */
@ -169,7 +169,7 @@
#define CP15_PMCCNTR(r) _CP15(0, r, c9, c13, 0) /* Cycle Count Register */
#define CP15_PMXEVTYPER(r) _CP15(0, r, c9, c13, 1) /* Event Type Select Register */
#define CP15_PMCCFILTR(r) _CP15(0, r, c9, c13, 1) /* Cycle Count Filter Control Register */
#define CP15_MXEVCNTR(r) _CP15(0, r, c9, c13, 2) /* Event Count Registers (Cortex-A5) */
#define CP15_PMXEVCNTR(r) _CP15(0, r, c9, c13, 2) /* Event Count Registers (Cortex-A5) */
#define CP15_PMUSERENR(r) _CP15(0, r, c9, c14, 0) /* User Enable Register */
#define CP15_PMINTENSET(r) _CP15(0, r, c9, c14, 1) /* Interrupt Enable Set Register */
#define CP15_PMINTENCLR(r) _CP15(0, r, c9, c14, 2) /* Interrupt Enable Clear Register */

View file

@ -92,7 +92,7 @@
cp15_clean_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4

View file

@ -93,7 +93,7 @@
.type cp15_coherent_dcache, function
cp15_coherent_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4
@ -111,7 +111,7 @@ cp15_coherent_dcache:
dsb
mrc CP15_TR(r3) /* Read the Cache Type Register */
mrc CP15_CTR(r3) /* Read the Cache Type Register */
and r3, r3, #0xf /* Isolate the IminLine field */
mov r2, #4
mov r2, r2, lsl r3 /* Get the cache line size in bytes */

View file

@ -92,7 +92,7 @@
cp15_flush_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4

View file

@ -93,7 +93,7 @@
cp15_invalidate_dcache:
mrc CP15_TR(r3) /* Read the Cache Type Register */
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4

View file

@ -1,6 +1,5 @@
/****************************************************************************
* arch/arm/src/armv7-a/l2cc.h
* Non-CP15 Registers
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>

View file

@ -342,7 +342,7 @@
* PL2 - Software executing in Hyp mode
*/
#ifdef CONFIG_AFE_ENABLE
#ifdef CPU_AFE_ENABLE
/* AP[2:1] access permissions model. AP[0] is used as an access flag:
*
* AP[2] AP[1] PL1 PL0 Description

View file

@ -72,7 +72,7 @@
# endif
#endif
/* Cortex M3 system calls ***********************************************************/
/* Cortex-A system calls ************************************************************/
/* SYS call 0:
*

View file

@ -33,8 +33,8 @@
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_COMMON_CORTEXM_MPU_H
#define __ARCH_ARM_SRC_COMMON_CORTEXM_MPU_H
#ifndef __ARCH_ARM_SRC_ARMV7M_MPU_H
#define __ARCH_ARM_SRC_ARMV7M_MPU_H
/************************************************************************************
* Included Files
@ -86,7 +86,15 @@
/* MPU Region Number Register Bit Definitions */
#define MPU_RNR_MASK (0xff)
#ifdef 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
/* MPU Region Base Address Register Bit Definitions */
@ -570,5 +578,5 @@ static inline void mpu_peripheral(uintptr_t base, size_t size)
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_COMMON_CORTEXM_MPU_H */
#endif /* __ARCH_ARM_SRC_ARMV7M_MPU_H */

View file

@ -72,7 +72,7 @@
# endif
#endif
/* Cortex M3 system calls ***********************************************************/
/* Cortex-M system calls ************************************************************/
/* SYS call 0:
*

View file

@ -0,0 +1,99 @@
/****************************************************************************
* arch/arm/src/armv7-m/up_coherent_dcache.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <sys/types.h>
#include <stdint.h>
#include "cache.h"
#include <nuttx/arch.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
* by cleaning the D cache (i.e., flushing the D cache contents to memory
* and invalidating the I cache. This is typically used when code has been
* written to a memory region, and will be executed.
*
* Input Parameters:
* addr - virtual start address of region
* len - Size of the address region in bytes
*
* Returned Value:
* None
*
****************************************************************************/
void up_coherent_dcache(uintptr_t addr, size_t len)
{
uintptr_t end;
if (len > 0)
{
/* Flush any dirtcy D-Cache lines to memory */
end = addr + len;
arch_clean_dcache(addr, end);
UNUSED(end);
/* Invalidate the entire I-Cache */
arch_invalidate_icache_all();
}
}

View file

@ -48,20 +48,6 @@
#include <nuttx/arch.h>
#include <nuttx/binfmt/elf.h>
#ifdef CONFIG_ELF
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@ -498,4 +484,3 @@ int up_init_exidx(Elf32_Addr address, Elf32_Word size)
}
#endif
#endif /* CONFIG_ELF */

View file

@ -50,8 +50,8 @@
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_ARMV7M_MPU_NREGIONS
# define CONFIG_ARMV7M_MPU_NREGIONS 8
#ifndef CONFIG_ARM_MPU_NREGIONS
# define CONFIG_ARM_MPU_NREGIONS 8
#endif
/****************************************************************************
@ -210,7 +210,7 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
unsigned int mpu_allocregion(void)
{
DEBUGASSERT(g_region < CONFIG_ARMV7M_MPU_NREGIONS);
DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS);
return (unsigned int)g_region++;
}

View file

@ -0,0 +1,180 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
comment "ARMv7-A Configuration Options"
config ARMV7R_MEMINIT
bool
default y if BOOT_SDRAM_DATA
default n if !BOOT_SDRAM_DATA
---help---
If this configuration *not* selected, then it is assumed that all
memory resources are initialized via arm_data_initialize() and
available at power-up reset time. Other memories, such as SDRAM or
some ECC SRAM memories, require some platform-specific
initialization first. In that case, this option should be selected
and the platform-specific implementation of arm_boot() must perform
the memory initialization first, then explicitly call
arm_data_initialize().
config ARMV7R_HAVE_L2CC
bool
default n
---help---
Selected by the configuration tool if the architecutre supports any
kind of L2 cache.
config ARMV7R_HAVE_L2CC_PL310
bool
default n
select ARMV7R_HAVE_L2CC
---help---
Set by architecture-specific code if the hardware supports a PL310
r3p2 L2 cache (only version r3p2 is supported).
if ARMV7R_HAVE_L2CC
menu "L2 Cache Configuration"
config ARMV7R_L2CC_PL310
bool "ARMv7-A L2CC P310 Support"
default n
depends on ARMV7R_HAVE_L2CC_PL310 && EXPERIMENTAL
select ARCH_L2CACHE
---help---
Enable the 2 Cache Controller (L2CC) is based on the L2CC-PL310 ARM
multi-way cache macrocell, version r3p2. The addition of an on-chip
secondary cache, also referred to as a Level 2 or L2 cache, is a
method of improving the system performance when significant memory
traffic is generated by the processor.
if ARCH_L2CACHE
if ARMV7R_L2CC_PL310
config PL310_LOCKDOWN_BY_MASTER
bool "PL310 Lockdown by Master"
default n
config PL310_LOCKDOWN_BY_LINE
bool "PL310 Lockdown by Line"
default n
config PL310_ADDRESS_FILTERING
bool "PL310 Address Filtering by Line"
default n
endif # ARMV7R_L2CC_PL310
choice
prompt "L2 Cache Associativity"
default ARMV7R_ASSOCIATIVITY_8WAY
depends on ARCH_L2CACHE
---help---
This choice specifies the associativity of L2 cache in terms of the
number of ways. This value could be obtained by querying cache
configuration registers. However, by defining a configuration
setting instead, we can avoid using RAM memory to hold information
about properties of the memory.
config ARMV7R_ASSOCIATIVITY_8WAY
bool "8-Way Associativity"
config ARMV7R_ASSOCIATIVITY_16WAY
bool "16-Way Associativity"
endchoice # L2 Cache Associativity
choice
prompt "L2 Cache Way Size"
default ARMV7R_WAYSIZE_16KB
depends on ARCH_L2CACHE
---help---
This choice specifies size of each way. This value can be obtained
by querying cache configuration registers. However, by defining a
configuration setting instead, we can avoid using RAM memory to hold
information
config ARMV7R_WAYSIZE_16KB
bool "16 KiB"
config ARMV7R_WAYSIZE_32KB
bool "32 KiB"
config ARMV7R_WAYSIZE_64KB
bool "64 KiB"
config ARMV7R_WAYSIZE_128KB
bool "128 KiB"
config ARMV7R_WAYSIZE_256KB
bool "256 KiB"
config ARMV7R_WAYSIZE_512KB
bool "512 KiB"
endchoice # L2 Cache Associativity
endif # ARCH_L2CACHE
endmenu # L2 Cache Configuration
endif # ARMV7R_HAVE_L2CC
choice
prompt "Toolchain Selection"
default ARMV7R_TOOLCHAIN_GNU_EABIW if HOST_WINDOWS
default ARMV7R_TOOLCHAIN_GNU_EABIL if !HOST_WINDOWS
config ARMV7R_TOOLCHAIN_BUILDROOT
bool "Buildroot (Cygwin or Linux)"
depends on !WINDOWS_NATIVE
config ARMV7R_TOOLCHAIN_CODESOURCERYL
bool "CodeSourcery GNU toolchain under Linux"
depends on HOST_LINUX
---help---
For use with the GNU toolchain built with the NuttX buildroot package.
This tools may be arm-nuttx-eabi- or, if ARMV7R_OABI_TOOLCHAIN is set,
arm-nuttx-elf-.
config ARMV7R_TOOLCHAIN_CODESOURCERYW
bool "CodeSourcery GNU toolchain under Windows"
depends on HOST_WINDOWS
config ARMV7R_TOOLCHAIN_DEVKITARM
bool "devkitARM GNU toolchain"
depends on HOST_WINDOWS
config ARMV7R_TOOLCHAIN_GNU_EABIL
bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)"
---help---
This option should work for any modern GNU toolchain (GCC 4.5 or newer)
configured for arm-none-eabi-.
config ARMV7R_TOOLCHAIN_GNU_EABIW
bool "Generic GNU EABI toolchain under Windows"
depends on HOST_WINDOWS
---help---
This option should work for any modern GNU toolchain (GCC 4.5 or newer)
configured for arm-none-eabi-.
config ARMV7R_TOOLCHAIN_GNU_OABI
bool "Generic GNU OABI toolchain"
---help---
This option should work for any GNU toolchain configured for arm-elf-.
endchoice # ARMV7R_HAVE_L2CC
config ARMV7R_OABI_TOOLCHAIN
bool "OABI (vs EABI)"
default n
depends on ARMV7R_TOOLCHAIN_BUILDROOT
---help---
Most of the older buildroot toolchains are OABI and are named
arm-nuttx-elf- vs. arm-nuttx-eabi-
config ARMV7R_DECODEFIQ
bool "FIQ Handler"
default n
---help---
Select this option if your platform supports the function
arm_decodefiq().

View file

@ -0,0 +1,156 @@
############################################################################
# arch/arm/src/armv7-r/Toolchain.defs
#
# Copyright (C) 2015 Gregory Nutt. 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.
#
############################################################################
# Setup for the selected toolchain
#
# Select and allow the selected toolchain to be overridden by a command-line
#selection.
#
ifeq ($(filter y, \
$(CONFIG_ARMV7R_TOOLCHAIN_BUILDROOT) \
),y)
CONFIG_ARMV7R_TOOLCHAIN ?= BUILDROOT
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYL) \
),y)
CONFIG_ARMV7R_TOOLCHAIN ?= CODESOURCERYL
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYW) \
),y)
CONFIG_ARMV7R_TOOLCHAIN ?= CODESOURCERYW
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7R_TOOLCHAIN_DEVKITARM) \
),y)
CONFIG_ARMV7R_TOOLCHAIN ?= DEVKITARM
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIL) \
),y)
CONFIG_ARMV7R_TOOLCHAIN ?= GNU_EABIL
endif
ifeq ($(filter y, \
$(CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIW) \
),y)
CONFIG_ARMV7R_TOOLCHAIN ?= GNU_EABIW
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
# NuttX buildroot under Linux or Cygwin
ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),BUILDROOT)
ifeq ($(CONFIG_ARMV7R_OABI_TOOLCHAIN),y)
CROSSDEV ?= arm-nuttx-elf-
ARCROSSDEV ?= arm-nuttx-elf-
else
CROSSDEV ?= arm-nuttx-eabi-
ARCROSSDEV ?= arm-nuttx-eabi-
endif
MAXOPTIMIZATION ?= -Os
endif
# CodeSourcery under Linux
ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),CODESOURCERYL)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
MAXOPTIMIZATION ?= -O2
endif
# CodeSourcery under Windows
ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),CODESOURCERYW)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
MAXOPTIMIZATION ?= -O2
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
WINTOOL = y
endif
endif
# devkitARM under Windows
ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),DEVKITARM)
CROSSDEV ?= arm-eabi-
ARCROSSDEV ?= arm-eabi-
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
WINTOOL = y
endif
endif
# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system
ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),GNU_EABIL)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
MAXOPTIMIZATION ?= -Os
endif
# Generic GNU EABI toolchain under Windows
ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),GNU_EABIW)
CROSSDEV ?= arm-none-eabi-
ARCROSSDEV ?= arm-none-eabi-
MAXOPTIMIZATION ?= -Os
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
WINTOOL = y
endif
endif

139
arch/arm/src/armv7-r/arm.h Normal file
View file

@ -0,0 +1,139 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm.h
* Non-CP15 Registers
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright
* 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414)
*
* 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_ARMV7_R_CPSR_H
#define __ARCH_ARM_SRC_ARMV7_R_CPSR_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* ARMv7-R ******************************************************************/
/* PSR bits */
#define PSR_MODE_SHIFT (0) /* Bits 0-4: Mode fields */
#define PSR_MODE_MASK (31 << PSR_MODE_SHIFT)
# define PSR_MODE_USR (16 << PSR_MODE_SHIFT) /* User mode */
# define PSR_MODE_FIQ (17 << PSR_MODE_SHIFT) /* FIQ mode */
# define PSR_MODE_IRQ (18 << PSR_MODE_SHIFT) /* IRQ mode */
# define PSR_MODE_SVC (19 << PSR_MODE_SHIFT) /* Supervisor mode */
# define PSR_MODE_ABT (23 << PSR_MODE_SHIFT) /* Abort mode */
# define PSR_MODE_UND (27 << PSR_MODE_SHIFT) /* Undefined mode */
# define PSR_MODE_SYS (31 << PSR_MODE_SHIFT) /* System mode */
#define PSR_T_BIT (1 << 5) /* Bit 5: Thumb execution state bit */
#define PSR_MASK_SHIFT (6) /* Bits 6-8: Mask Bits */
#define PSR_MASK_MASK (7 << PSR_GE_SHIFT)
# define PSR_F_BIT (1 << 6) /* Bit 6: FIQ mask bit */
# define PSR_I_BIT (1 << 7) /* Bit 7: IRQ mask bit */
# define PSR_A_BIT (1 << 8) /* Bit 8: Asynchronous abort mask */
#define PSR_E_BIT (1 << 9) /* Bit 9: Endianness execution state bit */
#define PSR_IT27_SHIFT (10) /* Bits 10-15: If-Then execution state bits IT[2:7] */
#define PSR_IT27_MASK (0x3f << PSR_IT27_SHIFT)
#define PSR_GE_SHIFT (16) /* Bits 16-19: Greater than or Equal flags */
#define PSR_GE_MASK (15 << PSR_GE_SHIFT)
/* Bits 20-23: Reserved. RAZ/SBZP */
#define PSR_J_BIT (1 << 24) /* Bit 24: Jazelle state bit */
#define PSR_IT01_SHIFT (25) /* Bits 25-26: If-Then execution state bits IT[0:1] */
#define PSR_IT01_MASK (3 << PSR_IT01_SHIFT)
#define PSR_Q_BIT (1 << 27) /* Bit 27: Cumulative saturation bit */
#define PSR_V_BIT (1 << 28) /* Bit 28: Overflow condition flag */
#define PSR_C_BIT (1 << 29) /* Bit 29: Carry condition flag */
#define PSR_Z_BIT (1 << 30) /* Bit 30: Zero condition flag */
#define PSR_N_BIT (1 << 31) /* Bit 31: Negative condition flag */
/****************************************************************************
* Inline Functions
****************************************************************************/
#ifndef __ASSEMBLY__
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: arm_data_initialize
*
* Description:
* Clear all of .bss to zero; set .data to the correct initial values.
* This function is called automatically from ARMv7-R boot code *UNLESS*
* executing with data in some memory that requires platform-specific
* initialization (such as SDRAM). That latter case is indicated with
* CONFIG_ARMV7R_MEMINIT=y. In that case, early platform-specific logic
* must first initialize then memory then call this function.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void arm_data_initialize(void);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_ARMV7_R_CPSR_H */

View file

@ -0,0 +1,416 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_assert.c
*
* Copyright (C) 2015 Gregory Nutt. 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>
/* Output debug info if stack dump is selected -- even if debug is not
* selected.
*/
#ifdef CONFIG_ARCH_STACKDUMP
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
#endif
#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/usb/usbdev_trace.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* USB trace dumping */
#ifndef CONFIG_USBDEV_TRACE
# undef CONFIG_ARCH_USBDUMP
#endif
/* The following is just intended to keep some ugliness out of the mainline
* code. We are going to print the task name if:
*
* CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name
* (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used)
* defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used
*/
#undef CONFIG_PRINT_TASKNAME
#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP))
# define CONFIG_PRINT_TASKNAME 1
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* 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;
lldbg("%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 */
#ifdef CONFIG_PRINT_TASKNAME
lldbg("%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
lldbg("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)
{
/* Are user registers available from interrupt processing? */
if (current_regs)
{
int regs;
/* Yes.. dump the interrupt registers */
for (regs = REG_R0; regs <= REG_R15; regs += 8)
{
uint32_t *ptr = (uint32_t *)&current_regs[regs];
lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs, ptr[0], ptr[1], ptr[2], ptr[3],
ptr[4], ptr[5], ptr[6], ptr[7]);
}
lldbg("CPSR: %08x\n", current_regs[REG_CPSR]);
}
}
#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 vsyslog do the real work */
va_start(ap, fmt);
ret = lowvsyslog(LOG_INFO, 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 = (struct tcb_s *)g_readytorun.head;
uint32_t sp = up_getsp();
uint32_t ustackbase;
uint32_t ustacksize;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
uint32_t istackbase;
uint32_t istacksize;
#endif
#ifdef CONFIG_ARCH_KERNEL_STACK
uint32_t kstackbase = 0;
#endif
/* Get the limits on the user stack memory */
if (rtcb->pid == 0)
{
ustackbase = g_idle_topstack - 4;
ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
}
else
{
ustackbase = (uint32_t)rtcb->adj_stack_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
}
lldbg("Current sp: %08x\n", sp);
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
istackbase = (uint32_t)&g_intstackbase;
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
/* Show interrupt stack info */
lldbg("Interrupt stack:\n");
lldbg(" base: %08x\n", istackbase);
lldbg(" size: %08x\n", istacksize);
#ifdef CONFIG_STACK_COLORATION
lldbg(" used: %08x\n", up_check_intstack());
#endif
#endif
/* Show user stack info */
lldbg("User stack:\n");
lldbg(" base: %08x\n", ustackbase);
lldbg(" size: %08x\n", ustacksize);
#ifdef CONFIG_STACK_COLORATION
lldbg(" used: %08x\n", up_check_tcbstack(rtcb));
#endif
#ifdef CONFIG_ARCH_KERNEL_STACK
/* This this thread have a kernel stack allocated? */
if (rtcb->xcp.kstack)
{
kstackbase = (uint32_t)rtcb->xcp.kstack + CONFIG_ARCH_KERNEL_STACKSIZE - 4;
lldbg("Kernel stack:\n");
lldbg(" base: %08x\n", kstackbase);
lldbg(" size: %08x\n", CONFIG_ARCH_KERNEL_STACKSIZE);
}
#endif
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Does the current stack pointer lie within the interrupt stack? */
if (sp > istackbase - istacksize && sp < istackbase)
{
/* Yes.. dump the interrupt stack */
lldbg("Interrupt Stack\n", sp);
up_stackdump(sp, istackbase);
/* Extract the user stack pointer which should lie
* at the base of the interrupt stack.
*/
sp = g_intstackbase;
lldbg("User sp: %08x\n", sp);
}
#endif
/* Dump the user stack if the stack pointer lies within the allocated user
* stack memory.
*/
if (sp > ustackbase - ustacksize && sp < ustackbase)
{
lldbg("User Stack\n", sp);
up_stackdump(sp, ustackbase);
}
#ifdef CONFIG_ARCH_KERNEL_STACK
/* Dump the user stack if the stack pointer lies within the allocated
* kernel stack memory.
*/
if (sp >= (uint32_t)rtcb->xcp.kstack && sp < kstackbase)
{
lldbg("Kernel Stack\n", sp);
up_stackdump(sp, kstackbase);
}
#endif
/* Then dump the registers (if available) */
up_registerdump();
/* Dump the state of all tasks (if available) */
up_showtasks();
#ifdef CONFIG_ARCH_USBDUMP
/* Dump USB trace data */
(void)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)
{
/* Are we in an interrupt handler or the idle task? */
if (current_regs || ((struct tcb_s *)g_readytorun.head)->pid == 0)
{
(void)irqsave();
for (; ; )
{
#ifdef CONFIG_ARCH_LEDS
board_autoled_on(LED_PANIC);
up_mdelay(250);
board_autoled_off(LED_PANIC);
up_mdelay(250);
#endif
}
}
else
{
exit(errorcode);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_assert
****************************************************************************/
void up_assert(const uint8_t *filename, int lineno)
{
#ifdef CONFIG_PRINT_TASKNAME
struct tcb_s *rtcb = (struct tcb_s *)g_readytorun.head;
#endif
board_autoled_on(LED_ASSERTION);
#ifdef CONFIG_PRINT_TASKNAME
lldbg("Assertion failed at file:%s line: %d task: %s\n",
filename, lineno, rtcb->name);
#else
lldbg("Assertion failed at file:%s line: %d\n",
filename, lineno);
#endif
up_dumpstate();
#ifdef CONFIG_BOARD_CRASHDUMP
board_crashdump(up_getsp(), g_readytorun.head, filename, lineno);
#endif
_up_assert(EXIT_FAILURE);
}

View file

@ -0,0 +1,164 @@
/****************************************************************************
* arch/arm/src/armv7-r/up_blocktask.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdbool.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_block_task
*
* Description:
* The currently executing task at the head of
* the ready to run list must be stopped. Save its context
* and move it to the inactive list specified by task_state.
*
* Inputs:
* tcb: Refers to a task in the ready-to-run list (normally
* the task at the head of the list). It most be
* stopped, its context saved and moved into one of the
* waiting task lists. It it was the task at the head
* of the ready-to-run list, then a context to the new
* ready to run task must be performed.
* task_state: Specifies which waiting task list should be
* hold the blocked task TCB.
*
****************************************************************************/
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
{
struct tcb_s *rtcb = (struct tcb_s *)g_readytorun.head;
bool switch_needed;
/* Verify that the context switch can be performed */
ASSERT((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 g_readytorun
* 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 g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Reset scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. */
up_restorestate(rtcb->xcp.regs);
}
/* Copy the user C context into the TCB at the (old) head of the
* g_readytorun Task list. if up_saveusercontext returns a non-zero
* value, then this is really the previously running task restarting!
*/
else if (!up_saveusercontext(rtcb->xcp.regs))
{
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Reset scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
up_fullcontextrestore(rtcb->xcp.regs);
}
}
}

View file

@ -0,0 +1,97 @@
/****************************************************************************
* arch/arm/src/armv7-r/up_coherent_dcache.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <sys/types.h>
#include <stdint.h>
#include "cp15_cacheops.h"
#include <nuttx/arch.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
* by cleaning the D cache (i.e., flushing the D cache contents to memory
* and invalidating the I cache. This is typically used when code has been
* written to a memory region, and will be executed.
*
* Input Parameters:
* addr - virtual start address of region
* len - Size of the address region in bytes
*
* Returned Value:
* None
*
****************************************************************************/
void up_coherent_dcache(uintptr_t addr, size_t len)
{
if (len > 0)
{
/* Perform the operation on the L1 cache */
cp15_coherent_dcache(addr, addr + len - 1);
#ifdef CONFIG_ARCH_L2CACHE
/* If we have an L2 cache, then there more things that need to done */
# warning This is insufficient
#endif
}
}

View file

@ -0,0 +1,87 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_copyarmstate.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <arch/irq.h>
#include "up_internal.h"
#ifdef CONFIG_ARCH_FPU
/****************************************************************************
* 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-R 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 ARM_CONTEXT_REGS through (XCPTCONTEXT_REGS-1)
*/
up_savefpu(dest);
/* Then copy all of the ARM registers (omitting the floating point
* registers). Indices: 0 through (ARM_CONTEXT_REGS-1).
*/
for (i = 0; i < ARM_CONTEXT_REGS; i++)
{
*dest++ = *src++;
}
}
}
#endif /* CONFIG_ARCH_FPU */

View file

@ -0,0 +1,85 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_copyfullstate.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <arch/irq.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* 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 current ARM model, the state is always copied to and from the
* stack and TCB.
*/
for (i = 0; i < XCPTCONTEXT_REGS; i++)
{
*dest++ = *src++;
}
}

View file

@ -0,0 +1,199 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_dataabort.c
*
* Copyright (C) 2015 Gregory Nutt. 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>
/* Output debug info if stack dump is selected -- even if debug is not
* selected.
*/
#ifdef CONFIG_ARCH_STACKDUMP
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
#endif
#include <stdint.h>
#include <debug.h>
#include <nuttx/irq.h>
#include "sched/sched.h"
#include "up_internal.h"
#ifdef CONFIG_PAGING
# include <nuttx/page.h>
# include "arm.h"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_dataabort
*
* Input parameters:
* regs - The standard, ARM register save array.
*
* If CONFIG_PAGING is selected in the NuttX configuration file, then these
* additional input values are expected:
*
* dfar - Fault address register.
* dfsr - Fault status register.
*
* Description:
* This is the data abort exception handler. The ARM data abort exception
* occurs when a memory fault is detected during a data transfer.
*
****************************************************************************/
#ifdef CONFIG_PAGING
uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
{
DFAR struct tcb_s *tcb = (DFAR struct tcb_s *)g_readytorun.head;
uint32_t *savestate;
/* Save the saved processor context in current_regs where it can be accessed
* for register dumps and possibly context switching.
*/
savestate = (uint32_t *)current_regs;
current_regs = regs;
/* In the NuttX on-demand paging implementation, only the read-only, .text
* section is paged. However, the ARM compiler generated PC-relative data
* fetches from within the .text sections. Also, it is customary to locate
* read-only data (.rodata) within the same section as .text so that it
* does not require copying to RAM. Misses in either of these case should
* cause a data abort.
*
* We are only interested in data aborts due to page translations faults.
* Sections should already be in place and permissions should already be
* be set correctly (to read-only) so any other data abort reason is a
* fatal error.
*/
pglldbg("DFSR: %08x DFAR: %08x\n", dfsr, dfar);
if ((dfsr & FSR_MASK) != FSR_PAGE)
{
goto segfault;
}
/* Check the (virtual) address of data that caused the data abort. When
* the exception occurred, this address was provided in the DFAR register.
* (It has not yet been saved in the register context save area).
*/
pgllvdbg("VBASE: %08x VEND: %08x\n", PG_PAGED_VBASE, PG_PAGED_VEND);
if (dfar < PG_PAGED_VBASE || dfar >= PG_PAGED_VEND)
{
goto segfault;
}
/* Save the offending data address as the fault address in the TCB of
* the currently task. This fault address is also used by the prefetch
* abort handling; this will allow common paging logic for both
* prefetch and data aborts.
*/
tcb->xcp.dfar = regs[REG_R15];
/* Call pg_miss() to schedule the page fill. A consequences of this
* call are:
*
* (1) The currently executing task will be blocked and saved on
* on the g_waitingforfill task list.
* (2) An interrupt-level context switch will occur so that when
* this function returns, it will return to a different task,
* most likely the page fill worker thread.
* (3) The page fill worker task has been signalled and should
* execute immediately when we return from this exception.
*/
pg_miss();
/* 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;
return regs;
segfault:
lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n",
regs[REG_PC], dfar, dfsr);
PANIC();
return regs; /* To keep the compiler happy */
}
#else /* CONFIG_PAGING */
uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr)
{
/* Save the saved processor context in current_regs where it can be accessed
* for register dumps and possibly context switching.
*/
current_regs = regs;
/* Crash -- possibly showing diagnostic debug information. */
lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n",
regs[REG_PC], dfar, dfsr);
PANIC();
return regs; /* To keep the compiler happy */
}
#endif /* CONFIG_PAGING */

View file

@ -0,0 +1,122 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_doirq.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <assert.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "up_internal.h"
#include "group/group.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Nested interrupts are not supported */
DEBUGASSERT(current_regs == NULL);
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
current_regs = regs;
/* Deliver the IRQ */
irq_dispatch(irq, regs);
#ifdef CONFIG_ARCH_FPU
/* Check for a context switch. If a context switch occurred, then
* current_regs will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != current_regs)
{
/* Restore floating point registers */
up_restorefpu((uint32_t *)current_regs);
}
#endif
/* Set current_regs to NULL to indicate that we are no longer in an
* interrupt handler.
*/
regs = (uint32_t *)current_regs;
current_regs = NULL;
board_autoled_off(LED_INIRQ);
#endif
return regs;
}

View file

@ -0,0 +1,273 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_elf.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdlib.h>
#include <elf32.h>
#include <errno.h>
#include <debug.h>
#include <arch/elf.h>
#include <nuttx/arch.h>
#include <nuttx/binfmt/elf.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_checkarch
*
* Description:
* Given the ELF header in 'hdr', verify that the ELF file is appropriate
* for the current, configured architecture. Every architecture that uses
* the ELF loader must provide this function.
*
* Input Parameters:
* hdr - The ELF header read from the ELF file.
*
* Returned Value:
* True if the architecture supports this ELF file.
*
****************************************************************************/
bool up_checkarch(FAR const Elf32_Ehdr *ehdr)
{
/* Make sure it's an ARM executable */
if (ehdr->e_machine != EM_ARM)
{
bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine);
return -ENOEXEC;
}
/* Make sure that 32-bit objects are supported */
if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
{
bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]);
return -ENOEXEC;
}
/* Verify endian-ness */
#ifdef CONFIG_ENDIAN_BIG
if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
#else
if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
#endif
{
bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]);
return -ENOEXEC;
}
/* Make sure the entry point address is properly aligned */
if ((ehdr->e_entry & 3) != 0)
{
bdbg("Entry point is not properly aligned: %08x\n", ehdr->e_entry);
return -ENOEXEC;
}
/* TODO: Check ABI here. */
return OK;
}
/****************************************************************************
* Name: up_relocate and up_relocateadd
*
* Description:
* Perform on architecture-specific ELF relocation. Every architecture
* that uses the ELF loader must provide this function.
*
* Input Parameters:
* rel - The relocation type
* sym - The ELF symbol structure containing the fully resolved value.
* There are a few relocation types for a few architectures that do
* not require symbol information. For those, this value will be
* NULL. Implementations of these functions must be able to handle
* that case.
* addr - The address that requires the relocation.
*
* Returned Value:
* Zero (OK) if the relocation was successful. Otherwise, a negated errno
* value indicating the cause of the relocation failure.
*
****************************************************************************/
int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
uintptr_t addr)
{
int32_t offset;
unsigned int relotype;
/* All relocations except R_ARM_V4BX depend upon having valid symbol
* information.
*/
relotype = ELF32_R_TYPE(rel->r_info);
if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX)
{
return -EINVAL;
}
/* Handle the relocation by relocation type */
switch (relotype)
{
case R_ARM_NONE:
{
/* No relocation */
}
break;
case R_ARM_PC24:
case R_ARM_CALL:
case R_ARM_JUMP24:
{
bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000)
{
offset -= 0x04000000;
}
offset += sym->st_value - addr;
if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000)
{
bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n",
ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL;
}
offset >>= 2;
*(uint32_t *)addr &= 0xff000000;
*(uint32_t *)addr |= offset & 0x00ffffff;
}
break;
case R_ARM_ABS32:
case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
{
bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value);
*(uint32_t *)addr += sym->st_value;
}
break;
case R_ARM_V4BX:
{
bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n",
(long)addr, (long)(*(uint32_t *)addr));
/* Preserve only Rm and the condition code */
*(uint32_t *)addr &= 0xf000000f;
/* Change instruction to 'mov pc, Rm' */
*(uint32_t *)addr |= 0x01a0f000;
}
break;
case R_ARM_PREL31:
{
bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff;
}
break;
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
{
bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
offset = (offset ^ 0x8000) - 0x8000;
offset += sym->st_value;
if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
{
offset >>= 16;
}
*(uint32_t *)addr &= 0xfff0f000;
*(uint32_t *)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff);
}
break;
default:
bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info));
return -EINVAL;
}
return OK;
}
int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym,
uintptr_t addr)
{
bdbg("RELA relocation not supported\n");
return -ENOSYS;
}

View file

@ -0,0 +1,92 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_fpuconfig.S
*
* Copyright (C) 2015 Gregory Nutt. 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 "cp15.h"
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl arm_fpuconfig
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_fpuconfig.S"
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: sam_fpuconfig
*
* Description:
* Configure the FPU. Enables access to CP10 and CP11
*
****************************************************************************/
.globl arm_fpuconfig
.type arm_fpuconfig, %function
arm_fpuconfig:
/* Enable access to CP10 and CP11 in CP15.CACR */
mrc CP15_CPACR(r0)
orr r0, r0, #0xf00000
mcr CP15_CPACR(r0)
/* Enable access to CP10 and CP11 in CP15.NSACR */
/* REVISIT: Do we need to do this? */
/* Set FPEXC.EN (B30) */
fmrx r0, fpexc
orr r0, r0, #0x40000000
fmxr fpexc, r0
bx lr
.size arm_fpuconfig, . - arm_fpuconfig
.end

View file

@ -0,0 +1,176 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_fullcontextrestore.S
*
* Copyright (C) 2015 Gregory Nutt. 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 <nuttx/irq.h>
#include "up_internal.h"
#include "svcall.h"
.file "arm_fullcontextrestore.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl up_fullcontextrestore
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_fullcontextrestore.S"
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: up_fullcontextrestore
*
* Description:
* Restore the specified task context. Full prototype is:
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*
* Return:
* None
*
****************************************************************************/
.globl up_fullcontextrestore
.type up_fullcontextrestore, function
up_fullcontextrestore:
/* On entry, a1 (r0) holds address of the register save area. All other
* registers are available for use.
*/
#ifdef CONFIG_ARCH_FPU
/* First, restore the floating point registers. Lets do this before we
* restore the ARM registers so that we have plenty of registers to
* work with.
*/
add r1, r0, #(4*REG_S0) /* r1=Address of FP register storage */
/* 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 */
#endif
#ifdef CONFIG_BUILD_KERNEL
/* For the kernel build, we need to be able to transition gracefully
* between kernel- and user-mode tasks. Here we do that with a system
* call; the system call will execute in kernel mode and but can return
* to either user or kernel mode.
*/
/* Perform the System call with R0=SYS_context_restore, R1=restoreregs */
mov r1, r0 /* R1: restoreregs */
mov r0, #SYS_context_restore /* R0: SYS_context_restore syscall */
svc #0x900001 /* Perform the system call */
/* This call should not return */
bx lr /* Unnecessary ... will not return */
#else
/* For a flat build, we can do all of this here... Just think of this as
* a longjmp() all on steriods.
*/
/* Recover all registers except for r0, r1, R15, and CPSR */
add r1, r0, #(4*REG_R2) /* Offset to REG_R2 storage */
ldmia r1, {r2-r14} /* Recover registers */
/* Create a stack frame to hold the some registers */
sub sp, sp, #(3*4) /* Frame for three registers */
ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */
str r1, [sp] /* Save it at the top of the stack */
ldr r1, [r0, #(4*REG_R1)] /* Fetch the stored r1 value */
str r1, [sp, #4] /* Save it in the stack */
ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */
str r1, [sp, #8] /* Save it at the bottom of the frame */
/* Now we can restore the CPSR. We wait until we are completely
* finished with the context save data to do this. Restore the CPSR
* may re-enable and interrupts and we could be in a context
* where the save structure is only protected by interrupts being
* disabled.
*/
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
msr cpsr, r1 /* Set the CPSR */
/* Now recover r0 and r1 */
ldr r0, [sp]
ldr r1, [sp, #4]
add sp, sp, #(2*4)
/* Then return to the address at the stop of the stack,
* destroying the stack frame
*/
ldr pc, [sp], #4
#endif
.size up_fullcontextrestore, . - up_fullcontextrestore

View file

@ -0,0 +1,536 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_head.S
*
* Copyright (C) 2015 Gregory Nutt. 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 "arm.h"
#include "cp15.h"
#include "sctlr.h"
#include "up_internal.h"
#include "up_arch.h"
#include <arch/board/board.h>
/**********************************************************************************
* Configuration
**********************************************************************************/
/* Hard-coded options */
#undef CPU_ALIGNMENT_TRAP
#undef CPU_CACHE_ROUND_ROBIN
#undef CPU_DCACHE_DISABLE
#undef CPU_ICACHE_DISABLE
#define CPU_SCTLR_CCP15BEN 1
#define CPU_BACKGROUND_REGION 1
#undef CPU_DIV0_FAULT
#undef CPU_FAST_INTERRUPT
#undef CPU_IMPL_VECTORS
#undef CPU_NONMASKABLE_FIQ
/* There are three operational memory configurations:
*
* 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case
* the boot logic must:
*
* - Configure SDRAM (if present),
* - Initialize the .data section in RAM, and
* - Clear .bss section
*
* 2. We boot in FLASH but copy ourselves to SDRAM from better performance.
* (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case
* the boot logic must:
*
* - Configure SDRAM (if present),
* - Copy ourself to RAM, and
* - Clear .bss section (data should be fully initialized)
*
* In this case, we assume that the logic within this file executes from FLASH.
*
* 3. There is bootloader that copies us to SDRAM (CONFIG_BOOT_RUNFROMFLASH=n &&
* CONFIG_BOOT_COPYTORAM=n). In this case SDRAM was initialized by the boot
* loader, and this boot logic must:
*
* - Clear .bss section (data should be fully initialized)
*/
/* Beginning (BOTTOM) and End+1 (TOP) of the IDLE stack.
*
* REVISIT: There are issues here. The stack point is initialized very
* early in the boot sequence, but in some architectures the memory supporting
* the may not be initialized (SDRAM, for example). In that case, ideally
* the IDLE stack should be in some other memory that does not require
* initialization (such as internal SRAM)
*/
#define IDLE_STACK_BASE _ebss
#define IDLE_STACK_TOP _ebss+CONFIG_IDLETHREAD_STACKSIZE
/****************************************************************************
* Global Symbols
****************************************************************************/
/* Imported symbols */
.global arm_boot /* Called just before os_start */
.global os_start /* Start the operating system */
.global arm_data_initialize /* Perform C data initialization */
.global _sbss /* Start of .bss in RAM */
.global _ebss /* End+1 of .bss in RAM */
#ifdef CONFIG_BOOT_RUNFROMFLASH
.global _eronly /* Where .data defaults are stored in FLASH */
.global _sdata /* Where .data needs to reside in SDRAM */
.global _edata
#endif
#ifdef CONFIG_ARCH_RAMFUNCS
.global _framfuncs /* Where RAM functions are stored in FLASH */
.global _sramfuncs /* Where RAM functions needs to reside in RAM */
.global _eramfuncs
#endif
/* Exported symbols */
.global __start /* Power-up/Reset entry point */
.globl g_idle_topstack /* Top of the initial/IDLE stack */
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_head.S"
/***************************************************************************
* .text
***************************************************************************/
.text
/****************************************************************************
* OS Entry Point
****************************************************************************/
/* We assume the bootloader has already initialized most of the h/w for
* us and that only leaves us having to do some os specific things
* below.
*/
.type __start, #function
__start:
/* Make sure that we are in SVC mode with IRQs and FIQs disabled */
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
msr cpsr_c, r0
/* Set up the stack pointer and clear the frame pointer. */
ldr sp, .Lstackpointer
mov fp, #0
/* Invalidate caches and TLBs.
*
* NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not
* support a CP15 operation to invalidate the entire data cache. ...
* In normal usage the only time the entire data cache has to be
* invalidated is on reset."
*
* The instruction cache is virtually indexed and physically tagged but
* the data cache is physically indexed and physically tagged. So it
* should not be an issue if the system comes up with a dirty Dcache;
* the ICache, however, must be invalidated.
*/
mov r0, #0
mcr CP15_BPIALL(r0) /* Invalidate entire branch prediction array */
mcr CP15_ICIALLU(r0) /* Invalidate I-cache */
/* Configure the system control register (see sctrl.h) */
mrc CP15_SCTLR(r0) /* Get control register */
/* Clear bits to reset values. This is only necessary in situations like, for
* example, we get here via a bootloader and the control register is in some
* unknown state.
*
* SCTLR_M Bit 0: MPU enable bit
* SCTLR_A Bit 1: Strict alignment disabled
* SCTLR_C Bit 2: DCache disabled
* SCTLR_CCP15BEN Bit 5: CP15 barrier enable
* SCTLR_B Bit 7: Should be zero on ARMv7R
*
* SCTLR_SW Bit 10: SWP/SWPB not enabled
* SCTLR_I Bit 12: ICache disabled
* SCTLR_V Bit 13: Assume low vectors
* SCTLR_RR Bit 14: Round-robin replacement strategy.
*
* SCTLR_BR Bit 17: Background Region bit
* SCTLR_DZ Bit 19: Divide by Zero fault enable bit
* SCTLR_FI Bit 21: Fast interrupts configuration enable bit
* SCTLR_U Bit 22: Unaligned access model (always one)
*
* SCTLR_VE Bit 24: Interrupt Vectors Enable bit
* SCTLR_EE Bit 25: Little endian.
* SCTLR_NMFI Bit 27: Non-maskable FIQ (NMFI) support
* SCTLR_TE Bit 30: All exceptions handled in ARM state.
* SCTLR_IE Bit 31: Instruction endian-ness.
*/
/* Clear all configurable bits */
bic r0, r0, #(SCTLR_M | SCTLR_A | SCTLR_C | SCTLR_CCP15BEN | SCTLR_B)
bic r0, r0, #(SCTLR_SW | SCTLR_I | SCTLR_V | SCTLR_RR)
bic r0, r0, #(SCTLR_BR | SCTLR_DZ | SCTLR_FI | SCTLR_U)
bic r0, r0, #(SCTLR_VE | SCTLR_EE | SCTLR_NMFI | SCTLR_TE | SCTLR_IE)
/* Set configured bits */
#ifdef CPU_ALIGNMENT_TRAP
/* Alignment abort enable
*
* SCTLR_A Bit 1: Strict alignment enabled
*/
orr r0, r0, #(SCTLR_A)
#endif
#ifndef CPU_DCACHE_DISABLE
/* Dcache enable
*
* SCTLR_C Bit 2: DCache enable
*/
orr r0, r0, #(SCTLR_C)
#endif
#ifdef CPU_SCTLR_CCP15BEN
/* Enable memory barriers
*
* SCTLR_CCP15BEN Bit 5: CP15 barrier enable
*/
orr r0, r0, #(SCTLR_CCP15BEN)
#endif
#ifndef CPU_ICACHE_DISABLE
/* Icache enable
*
* SCTLR_I Bit 12: ICache enable
*/
orr r0, r0, #(SCTLR_I)
#endif
#ifndef CONFIG_ARCH_LOWVECTORS
/* Position vectors to 0xffff0000 if so configured.
*
* SCTLR_V Bit 13: High vectors
*/
orr r0, r0, #(SCTLR_V)
#endif
#ifdef CPU_CACHE_ROUND_ROBIN
/* Round Robin cache replacement
*
* SCTLR_RR Bit 14: Round-robin replacement strategy.
*/
orr r0, r0, #(SCTLR_RR)
#endif
#ifdef CPU_BACKGROUND_REGION
/* Allow PL1 access to back region when MPU is enabled
*
* SCTLR_BR Bit 17: Background Region bit
*/
orr r0, r0, #(SCTLR_BR)
#endif
#ifdef CPU_DIV0_FAULT
/* Enable divide by zero faults
*
* SCTLR_DZ Bit 19: Divide by Zero fault enable bit
*/
orr r0, r0, #(SCTLR_DZ)
#endif
#ifdef CPU_FAST_INTERRUPT
/* Fast interrupts configuration enable bit
*
* SCTLR_FI Bit 21: Fast interrupts configuration enable bit
*/
orr r0, r0, #(SCTLR_FI)
#endif
#ifdef CPU_IMPL_VECTORS
/* Implementation defined interrupt vectors
*
* SCTLR_VE Bit 24: Interrupt Vectors Enable bit
*/
orr r0, r0, #(SCTLR_VE)
#endif
#ifdef CPU_NONMASKABLE_FIQ
/* Non-maskable FIQ support
*
* SCTLR_NMFI Bit 27: Non-maskable FIQ (NMFI) support
*/
orr r0, r0, #(SCTLR_NMFI)
#endif
/* Then write the configured control register */
mcr CP15_SCTLR(r0) /* Write control reg */
.rept 12 /* Some CPUs want want lots of NOPs here */
nop
.endr
#if 0
/* Cortex-R/RF Errata Work-Around
*
* Errata 754269: Register corruption during a load-multiple instruction
* at an exception vector.
* Workaround: To workaround this erratum, set bit [7] of the
* Auxiliary Control Register to disable out-of-order
* completion for divide instructions. Code performance
* may be reduced depending on how often divide
* operations are used.
* NOTE: The ARMv7-A/R Architecture reference many lists the bits
* bits of the ACTLR as "implementation defined"
*
* REVISIT: I do not think this is needed because the NuttX vectors do not
* begin with an LDM instruction.
*/
mrc CP15_ACTLR(r0) /* Read Auxiliary Control register */
orr r0, r0, #(1 << 7) /* Disable out-of-order completion */
mcr CP15_ACTLR(r0) /* Write Auxiliary Control register */
#endif
#ifndef CONFIG_ARMV7R_MEMINIT
/* Initialize .bss and .data ONLY if .bss and .data lie in RAM that is
* ready to use. Other memory, such as SDRAM, must be initialized before
* it can be used. arm_boot() will perform that memory initialization and
* .bss and .data can be initialized after arm_boot() returns.
*/
bl arm_data_initialize
#endif
/* Perform early C-level, platform-specific initialization. Logic
* within arm_boot() must configure SDRAM and call arm_data_initialize()
* if CONFIG_ARMV7R_MEMINIT=y.
*/
bl arm_boot
#ifdef CONFIG_STACK_COLORATION
/* Write a known value to the IDLE thread stack to support stack
* monitoring logic
*/
adr r3, .Lstkinit
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
2: /* Top of the loop */
sub r1, r1, #1 /* R1 = Number of words remaining */
cmp r1, #0 /* Check (nwords == 0) */
str r2, [r0], #4 /* Save stack color word, increment stack address */
bne 2b /* Bottom of the loop */
#endif
/* Finally branch to the OS entry point */
mov lr, #0 /* LR = return address (none) */
b os_start /* Branch to os_start */
/* .text Data */
.Lstackpointer:
.long IDLE_STACK_TOP
#ifdef CONFIG_STACK_COLORATION
.type .Lstkinit, %object
.Lstkinit:
.long IDLE_STACK_BASE /* Beginning of the IDLE stack, then words of IDLE stack */
.long (CONFIG_IDLETHREAD_STACKSIZE >> 2)
.long STACK_COLOR /* Stack coloration word */
#endif
.size __start, .-__start
/***************************************************************************
* Name: arm_data_initialize
***************************************************************************/
.global arm_data_initialize
.type arm_data_initialize, #function
arm_data_initialize:
/* Zero BSS */
adr r0, .Linitparms
ldmia r0, {r0, r1}
mov r2, #0
1:
cmp r0, r1 /* Clear up to _bss_end_ */
strcc r2, [r0], #4
bcc 1b
#ifdef CONFIG_BOOT_RUNFROMFLASH
/* If the .data section is in a separate, uninitialized address space,
* then we will also need to copy the initial values of of the .data
* section from the .text region into that .data region. This would
* be the case if we are executing from FLASH and the .data section
* lies in a different physical address region OR if we are support
* on-demand paging and the .data section lies in a different virtual
* address region.
*/
adr r3, .Ldatainit
ldmia r3, {r0, r1, r2}
2:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
blt 2b
#endif
#ifdef CONFIG_ARCH_RAMFUNCS
/* Copy any necessary code sections from FLASH to RAM. The correct
* destination in SRAM is given by _sramfuncs and _eramfuncs. The
* temporary location is in flash after the data initialization code
* at _framfuncs
*/
adr r3, .Lfuncinit
ldmia r3, {r0, r1, r2}
3:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
blt 3b
#ifndef CPU_DCACHE_DISABLE
/* Flush the copied RAM functions into physical RAM so that will
* be available when fetched into the I-Cache.
*
* Note that this is a branch, not a call and so will return
* directly to the caller without returning here.
*/
adr r3, ..Lramfunc
ldmia r3, {r0, r1}
ldr r3, =arch_clean_dcache
b r3
#else
/* Otherwise return to the caller */
bx lr
#endif
#else
/* Return to the caller */
bx lr
#endif
/* .text Data:
*
* _sbss is the start of the BSS region (see linker script)
* _ebss is the end of the BSS regsion (see linker script)
*
* Typical Configuration:
* The idle task stack starts at the end of BSS and is of size
* CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there
* until the end of memory. See g_idle_topstack below.
*/
.type .Linitparms, %object
.Linitparms:
.long _sbss
.long _ebss
#ifdef CONFIG_BOOT_RUNFROMFLASH
.type .Ldatainit, %object
.Ldatainit:
.long _eronly /* Where .data defaults are stored in FLASH */
.long _sdata /* Where .data needs to reside in SDRAM */
.long _edata
#endif
#ifdef CONFIG_ARCH_RAMFUNCS
.type .Lfuncinit, %object
.Lfuncinit:
.long _framfuncs /* Where RAM functions are stored in FLASH */
.Lramfuncs:
.long _sramfuncs /* Where RAM functions needs to reside in RAM */
.long _eramfuncs
#endif
.size arm_data_initialize, . - arm_data_initialize
/***************************************************************************
* .rodata
***************************************************************************/
/* This global variable is unsigned long g_idle_topstack and is
* exported from here only because of its coupling to .Lstackpointer
* above.
*/
.section .rodata, "a"
.align 4
.type g_idle_topstack, object
g_idle_topstack:
.long IDLE_STACK_TOP
.size g_idle_topstack, .-g_idle_topstack
.end

View file

@ -0,0 +1,140 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_initialstate.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <string.h>
#include <nuttx/arch.h>
#include "arm.h"
#include "up_internal.h"
#include "up_arch.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* 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;
uint32_t cpsr;
/* 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;
/* Save the task entry point */
xcp->regs[REG_PC] = (uint32_t)tcb->start;
/* 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;
}
#endif
/* Set supervisor-mode and disable FIQs, regardless of how NuttX is
* configured and of what kind of thread is being started. That is
* because all threads, even user-mode threads will start in kernel
* trampoline at task_start() or pthread_start(). The thread's
* privileges will be dropped before transitioning to user code.
*/
cpsr = PSR_MODE_SVC;
/* Enable or disable interrupts, based on user configuration */
#ifdef CONFIG_SUPPRESS_INTERRUPTS
/* Disable interrupts (both IRQs and FIQs) */
cpsr |= (PSR_I_BIT | PSR_F_BIT);
#else /* CONFIG_SUPPRESS_INTERRUPTS */
/* Leave IRQs enabled (Also FIQs if CONFIG_ARMV7R_DECODEFIQ is selected) */
#ifndef CONFIG_ARMV7R_DECODEFIQ
cpsr |= PSR_F_BIT;
#endif /* !CONFIG_ARMV7R_DECODEFIQ */
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
xcp->regs[REG_CPSR] = cpsr;
}

View file

@ -0,0 +1,874 @@
/************************************************************************************
* arch/arm/src/armv7-r/chip/arm-l2cc_pl310.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Reference: "CoreLink™ Level 2 Cache Controller L2C-310", Revision r3p2,
* Technical Reference Manual, ARM DDI 0246F (ID011711), ARM
*
* NOTE: This logic is incompatible with older versions of the PL310!
*
* 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 <assert.h>
#include <debug.h>
#include <arch/irq.h>
#include "up_arch.h"
#include "l2cc.h"
#include "l2cc_pl310.h"
#ifdef CONFIG_ARMV7R_L2CC_PL310
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ***********************************************************/
/* Number of ways depends on ARM configuration */
#if defined(CONFIG_ARMV7R_ASSOCIATIVITY_8WAY)
# define PL310_NWAYS 8
# define PL310_WAY_MASK 0x000000ff
#elif defined(CONFIG_ARMV7R_ASSOCIATIVITY_8WAY)
# define PL310_NWAYS 16
# define PL310_WAY_MASK 0x0000ffff
#else
# error "Number of ways not selected"
#endif
/* The size of one depends on ARM configuration */
#if defined(CONFIG_ARMV7R_WAYSIZE_16KB)
# define PL310_WAYSIZE (16 * 1024)
#elif defined(CONFIG_ARMV7R_WAYSIZE_32KB)
# define PL310_WAYSIZE (32 * 1024)
#elif defined(CONFIG_ARMV7R_WAYSIZE_64KB)
# define PL310_WAYSIZE (64 * 1024)
#elif defined(CONFIG_ARMV7R_WAYSIZE_128KB)
# define PL310_WAYSIZE (128 * 1024)
#elif defined(CONFIG_ARMV7R_WAYSIZE_256KB)
# define PL310_WAYSIZE (256 * 1024)
#elif defined(CONFIG_ARMV7R_WAYSIZE_512KB)
# define PL310_WAYSIZE (512 * 1024)
#else
# error "Way size not selected"
#endif
/* The size of the cache is then the product of the number of ways times
* the size of each way.
*/
#define PL310_CACHE_SIZE (PL310_NWAYS * PL310_WAYSIZE)
/* Use for aligning addresses to a cache line boundary */
#define PL310_CACHE_LINE_MASK (PL310_CACHE_LINE_SIZE - 1)
/* Configurable options
*
* REVISIT: Currently there are not configuration options. All values
* are just set to the default.
*/
/* Bit 0: Full line zero enable
*
* Default: 0=Full line of write zero behavior disabled
*/
#define L2CC_ACR_FLZE_CONFIG (0) /* 0=Full line of write zero behavior disabled */
/* Bit 10: High Priority for SO and Dev Reads Enable
*
* Default: 0=Strongly Ordered and Device reads have lower priority than
* cacheable accesses
*/
#define L2CC_ACR_HPSO_CONFIG (0) /* 0=Have lower priority than cache */
/* Bit 11: Store Buffer Device Limitation Enable
*
* Default: 0=Store buffer device limitation disabled
*/
#define L2CC_ACR_SBDLE_CONFIG (0) /* 0=Store buffer device limitation disabled */
/* Bit 12: Exclusive Cache Configuration
*
* Default: 0=Disabled
*/
#define L2CC_ACR_EXCC_CONFIG (0) /* 0=Disabled */
/* Bit 13: Shared Attribute Invalidate Enable
*
* Default: 0=Shared invalidate behavior disabled
*/
#define L2CC_ACR_SAIE_CONFIG (0) /* 0=Shared invalidate behavior disabled */
/* Bit 20: Event Monitor Bus Enable
*
* Default: 0=Disabled
*/
#define L2CC_ACR_EMBEN_CONFIG (0) /* 0=Disabled */
/* Bit 21: Parity Enable
*
* Default: 0=Disabled
*/
#define L2CC_ACR_PEN_CONFIG (0) /* 0=Disabled */
/* Bit 22: Shared Attribute Override Enable
*
* Default: 0=Treats shared accesses as specified in the TRM
*/
#define L2CC_ACR_SAOEN_CONFIG (0) /* 0=As specified in the TRM */
/* Bits 23-24: Force Write Allocate
*
* Default: 0=Use AWCACHE attributes for WA
*/
#define L2CC_ACR_FWA_CONFIG L2CC_ACR_FWA_AWCACHE /* Use AWCACHE attributes for WA */
/* Bit 25: Cache Replacement Policy
*
* Default: 1=Round robin replacement policy
*/
#define L2CC_ACR_CRPOL_CONFIG L2CC_ACR_CRPOL /* 1=Round robin replacement policy */
/* Bit 26: Non-Secure Lockdown Enable
*
* Default: 0=Lockdown registers cannot be modified using non-secure acceses
*/
#define L2CC_ACR_NSLEN_CONFIG (0) /* 0=Secure access only */
/* Bit 27: Non-Secure Interrupt Access Control
*
* Default: 0=Interrupt Clear and Mask can only be modified or read with
* secure accesses
*/
#define L2CC_ACR_NSIAC_CONFIG (0) /* 0=Secure access only */
/* Bit 28: Data Prefetch Enable
*
* Default: 0=Data prefetching disabled
*/
#define L2CC_ACR_DPEN_CONFIG (0) /* 0=Data prefetching disabled */
/* Bit 29: Instruction Prefetch Enable
*
* Default: 0=Instruction prefetching disabled
*/
#define L2CC_ACR_IPEN_CONFIG (0) /* 0=Instruction prefetching disabled */
/* Bit 30: Early BRESP enable
*
* Default: 0=Early BRESP disabled
*/
#define L2CC_ACR_EBRESP_CONFIG (0) /* 0=Early BRESP disabled */
#define L2CC_ACR_CONFIG \
(L2CC_ACR_FLZE_CONFIG | L2CC_ACR_HPSO_CONFIG | L2CC_ACR_SBDLE_CONFIG | \
L2CC_ACR_EXCC_CONFIG | L2CC_ACR_SAIE_CONFIG | L2CC_ACR_EMBEN_CONFIG | \
L2CC_ACR_PEN_CONFIG | L2CC_ACR_SAOEN_CONFIG | L2CC_ACR_FWA_CONFIG | \
L2CC_ACR_CRPOL_CONFIG | L2CC_ACR_NSLEN_CONFIG | L2CC_ACR_NSIAC_CONFIG | \
L2CC_ACR_DPEN_CONFIG | L2CC_ACR_IPEN_CONFIG | L2CC_ACR_EBRESP_CONFIG)
#define L2CC_ACR_ALLCONFIGS (0x7f303c01)
#define L2CC_ACR_CONFIGMASK (L2CC_ACR_SBZ | L2CC_ACR_ALLCONFIGS)
/* Filter end address */
#define CONFIG_PL310_FLEND (CONFIG_PL310_FLSTRT + CONFIG_PL310_FLSIZE)
/* Block size. Used to break up long operations so that interrupts are not
* disabled for a long time.
*/
#define PL310_GULP_SIZE 4096
/* Misc commoly defined and re-defined things */
#ifndef MIN
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef OK
# define OK 0
#endif
/* Data synchronization barrier */
#define dsb(a) __asm__ __volatile__ ("dsb " #a : : : "memory")
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pl310_flush_all
*
* Description:
* Flush all ways using the Clean Invalidate Way Register (CIWR).
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void pl310_flush_all(void)
{
/* Flush all ways by writing the set of ways to be cleaned to the Clean
* Invalidate Way Register (CIWR).
*/
putreg32(PL310_WAY_MASK, L2CC_CIWR);
/* Wait for cache operation by way to complete */
while ((getreg32(L2CC_CIWR) & PL310_WAY_MASK) != 0);
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
putreg32(0, L2CC_CSR);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_l2ccinitialize
*
* Description:
* One time configuration of the L2 cache. The L2 cache will be enabled
* upon return.
*
* Input Parameters:
* None. The L2 cache configuration is controlled by configuration
* settings.
*
* Returned Value:
* None
*
****************************************************************************/
void up_l2ccinitialize(void)
{
uint32_t regval;
int i;
/* Make sure that this is a PL310 cache, version r3p2.
*
* REVISIT: The SAMA5D4 is supposed to report its ID as 0x410000C8 which is
* r3p2, but the chip that I have actually* reports 0x410000C9 which is some
* later revision.
*/
//DEBUGASSERT((getreg32(L2CC_IDR) & L2CC_IDR_REV_MASK) == L2CC_IDR_REV_R3P2);
/* Make sure that actual cache configuration agrees with the configured
* cache configuration.
*/
#if defined(CONFIG_ARMV7R_ASSOCIATIVITY_8WAY)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 0);
#elif defined(CONFIG_ARMV7R_ASSOCIATIVITY_16WAY)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 1);
#else
# error No associativity selected
#endif
#if defined(CONFIG_ARMV7R_WAYSIZE_16KB)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_16KB);
#elif defined(CONFIG_ARMV7R_WAYSIZE_32KB)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_32KB);
#elif defined(CONFIG_ARMV7R_WAYSIZE_64KB)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_64KB);
#elif defined(CONFIG_ARMV7R_WAYSIZE_128KB)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_128KB);
#elif defined(CONFIG_ARMV7R_WAYSIZE_256KB)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_256KB);
#elif defined(CONFIG_ARMV7R_WAYSIZE_512KB)
DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_512KB);
#else
# error No way size selected
#endif
/* L2 configuration can only be changed if the cache is disabled,
*
* NOTE: This register access will fail if we are not in secure more.
*/
if ((getreg32(L2CC_CR) & L2CC_CR_L2CEN) == 0)
{
#if defined(CONFIG_PL310_TRCR_TSETLAT) && defined(CONFIG_PL310_TRCR_TRDLAT) && \
defined(CONFIG_PL310_TRCR_TWRLAT)
/* Configure Tag RAM control */
regval = ((CONFIG_PL310_TRCR_TSETLAT - 1) << L2CC_TRCR_TSETLAT_SHIFT)
((CONFIG_PL310_TRCR_TRDLAT - 1) << L2CC_TRCR_TRDLAT_SHIFT) |
((CONFIG_PL310_TRCR_TWRLAT - 1) << L2CC_TRCR_TWRLAT_SHIFT);
putreg32(regval, L2CC_TRCR);
#endif
#if defined(CONFIG_PL310_DRCR_DSETLAT) && defined(CONFIG_PL310_DRCR_DRDLAT) && \
defined(CONFIG_PL310_DRCR_DWRLAT)
/* Configure Data RAM control */
regval = ((CONFIG_PL310_DRCR_DSETLAT - 1) << L2CC_DRCR_DSETLAT_SHIFT) |
((CONFIG_PL310_DRCR_DRDLAT - 1) << L2CC_DRCR_DRDLAT_SHIFT) |
((CONFIG_PL310_DRCR_DWRLAT - 1) << L2CC_DRCR_DWRLAT_SHIFT);
putreg32(regval, L2CC_DRCR);
#endif
#ifdef PL310_ADDRESS_FILTERING
#if defined(CONFIG_PL310_FLSTRT) && defined(CONFIG_PL310_FLSIZE)
/* Configure the address filter */
regval = (CONFIG_PL310_FLEND + ~L2CC_FLEND_MASK) & L2CC_FLEND_MASK;
putreg32(regval, L2CC_FLEND);
regval = (CONFIG_PL310_FLSTRT & L2CC_FLSTRT_MASK) | L2CC_FLSTRT_ENABLE;
putreg32(regval | L2X0_ADDR_FILTER_EN, L2CC_FLSTRT);
#endif
#endif
/* Make sure that the memory is not locked down */
for (i = 0; i < PL310_NLOCKREGS; i++)
{
putreg32(0, L2CC_DLKR(i));
putreg32(0, L2CC_ILKR(i));
}
/* Configure the cache properties */
regval = getreg32(L2CC_ACR);
regval &= ~L2CC_ACR_CONFIGMASK;
regval |= L2CC_ACR_CONFIG;
putreg32(regval, L2CC_ACR);
/* Invalidate and enable the cache */
l2cc_invalidate_all();
putreg32(L2CC_CR_L2CEN, L2CC_CR);
}
lldbg("(%d ways) * (%d bytes/way) = %d bytes\n",
PL310_NWAYS, PL310_WAYSIZE, PL310_CACHE_SIZE);
}
/****************************************************************************
* Name: l2cc_enable
*
* Description:
* Re-enable the L2CC-P310 L2 cache by setting the enable bit in the
* Control Register (CR)
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_enable(void)
{
irqstate_t flags;
/* Invalidate and enable the cache (must be disabled to do this!) */
flags = irqsave();
l2cc_invalidate_all();
putreg32(L2CC_CR_L2CEN, L2CC_CR);
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_disable
*
* Description:
* Disable the L2CC-P310 L2 cache by clearing the Control Register (CR)
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_disable(void)
{
irqstate_t flags;
/* Flush all ways using the Clean Invalidate Way Register (CIWR). */
flags = irqsave();
pl310_flush_all();
/* Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) */
putreg32(0, L2CC_CR);
dsb();
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_sync
*
* Description:
* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_sync(void)
{
irqstate_t flags;
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
flags = irqsave();
putreg32(0, L2CC_CSR);
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_invalidate_all
*
* Description:
* Invalidate all ways using the Invalidate Way Register (IWR).
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_invalidate_all(void)
{
irqstate_t flags;
uint32_t regval;
/* Invalidate all ways */
flags = irqsave();
/* Disable the L2 cache while we invalidate it */
regval = getreg32(L2CC_CR);
l2cc_disable();
/* Invalidate all ways by writing the bit mask of ways to be invalidated
* the Invalidate Way Register (IWR).
*/
putreg32(PL310_WAY_MASK, L2CC_IWR);
/* Wait for cache operation by way to complete */
while ((getreg32(L2CC_IWR) & PL310_WAY_MASK) != 0);
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
putreg32(0, L2CC_CSR);
/* Then re-enable the L2 cache if it was enabled before */
putreg32(regval, L2CC_CR);
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_invalidate
*
* Description:
* Invalidate a range of addresses by writing to the Invalidate Physical
* Address Line Register (IPALR) repeatedly.
*
* Input Parameters:
* startaddr - The first address to be invalidated
* endaddr - The last address to be invalidated
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_invalidate(uintptr_t startaddr, uintptr_t endaddr)
{
uintptr_t invalsize;
uintptr_t gulpend;
irqstate_t flags;
/* Check if the start address is aligned with a cacheline */
flags = irqsave();
if ((startaddr & PL310_CACHE_LINE_MASK) != 0)
{
/* No.. align down and flush the cache line by writing the address to
* the Clean Invalidate Physical Address Line Register (CIPALR).
*/
startaddr &= ~PL310_CACHE_LINE_MASK;
putreg32(startaddr, L2CC_CIPALR);
/* Then start invalidating at the next cache line */
startaddr += PL310_CACHE_LINE_SIZE;
}
/* Check if the end address is aligned with a cache line */
if ((endaddr & PL310_CACHE_LINE_MASK) != 0)
{
/* No.. align down and flush cache line by writing the address to
* the Clean Invalidate Physical Address Line Register (CIPALR).
*/
endaddr &= ~PL310_CACHE_LINE_MASK;
putreg32(endaddr, L2CC_CIPALR);
}
irqrestore(flags);
/* Loop, invalidated the address range by cache line. Interrupts are re-
* enabled momentarily every PL310_GULP_SIZE bytes.
*/
while (startaddr < endaddr)
{
/* Get the size of the next gulp of cache lines to invalidate. We do
* this in small chunks so that we do not have to keep interrupts
* disabled throughout the whole flush.
*/
invalsize = endaddr - startaddr;
gulpend = startaddr + MIN(invalsize, PL310_GULP_SIZE);
/* Disable interrupts and invalidate the gulp */
flags = irqsave();
while (startaddr < gulpend)
{
/* Invalidate the cache line by writing the address to the
* Invalidate Physical Address Line Register (IPALR).
*/
putreg32(startaddr, L2CC_IPALR);
/* Start of the next cache line */
startaddr += PL310_CACHE_LINE_SIZE;
}
/* Enable interrupts momentarily */
irqrestore(flags);
}
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
flags = irqsave();
putreg32(0, L2CC_CSR);
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_clean_all
*
* Description:
* Clean all ways by using the Clean Ways Register (CWR).
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_clean_all(void)
{
irqstate_t flags;
/* Clean all ways by writing the set of ways to be cleaned to the Clean
* Ways Register (CWR).
*/
flags = irqsave();
putreg32(PL310_WAY_MASK, L2CC_CWR);
/* Wait for cache operation by way to complete */
while ((getreg32(L2CC_CWR) & PL310_WAY_MASK) != 0);
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
putreg32(0, L2CC_CSR);
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_clean
*
* Description:
* Clean the cache line over a range of addresses uing the Clean Physical
* Address Line Register (CPALR) repeatedly.
*
* Input Parameters:
* startaddr - The first address to be cleaned
* endaddr - The last address to be cleaned
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_clean(uintptr_t startaddr, uintptr_t endaddr)
{
uintptr_t cleansize;
uintptr_t gulpend;
irqstate_t flags;
/* If the range of addresses to clean is as large or larger the L2 cache,
* then just clean the whole thing.
*/
cleansize = endaddr - startaddr;
if (cleansize >= PL310_CACHE_SIZE)
{
l2cc_clean_all();
return;
}
/* Align the starting address to a cache line boundary */
startaddr &= ~PL310_CACHE_LINE_MASK;
/* Clean the L2 cache by cache line, enabling interrupts momentarily
* every PL310_GULP_SIZE bytes.
*/
while (startaddr < endaddr)
{
/* Get the size of the next gulp of cache lines to flush. We do
* this in small chunks so that we do not have to keep interrupts
* disabled throughout the whole flush.
*/
cleansize = endaddr - startaddr;
gulpend = startaddr + MIN(cleansize, PL310_GULP_SIZE);
/* Disable interrupts and clean the gulp */
flags = irqsave();
while (startaddr < gulpend)
{
/* Clean the cache line by writing the address to the Clean
* Physical Address Line Register (CPALR).
*/
putreg32(startaddr, L2CC_CPALR);
/* Start of the next cache line */
startaddr += PL310_CACHE_LINE_SIZE;
}
/* Enable interrupts momentarily */
irqrestore(flags);
}
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
flags = irqsave();
putreg32(0, L2CC_CSR);
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_flush_all
*
* Description:
* Flush all ways using the Clean Invalidate Way Register (CIWR).
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_flush_all(void)
{
irqstate_t flags;
/* Flush all ways using the Clean Invalidate Way Register (CIWR). */
flags = irqsave();
pl310_flush_all();
irqrestore(flags);
}
/****************************************************************************
* Name: l2cc_flush
*
* Description:
* Flush a range of address by using the Clean Invalidate Physical Address
* Line Register (CIPALR) repeatedly.
*
* Input Parameters:
* startaddr - The first address to be flushed
* endaddr - The last address to be flushed
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_flush(uint32_t startaddr, uint32_t endaddr)
{
uintptr_t flushsize;
uintptr_t gulpend;
irqstate_t flags;
/* If the range of addresses to flush is as large or larger the L2 cache,
* then just flush the whole thing.
*/
flushsize = endaddr - startaddr;
if (flushsize >= PL310_CACHE_SIZE)
{
l2cc_flush_all();
return;
}
/* Align the starting address to a cache line boundary */
startaddr &= ~PL310_CACHE_LINE_MASK;
/* Flush the L2 cache by cache line, enabling interrupts momentarily
* every PL310_GULP_SIZE bytes.
*/
while (startaddr < endaddr)
{
/* Get the size of the next gulp of cache lines to flush. We do
* this in small chunks so that we do not have to keep interrupts
* disabled throughout the whole flush.
*/
flushsize = endaddr - startaddr;
gulpend = startaddr + MIN(flushsize, PL310_GULP_SIZE);
/* Disable interrupts and flush the gulp */
flags = irqsave();
while (startaddr < gulpend)
{
/* Flush the cache line by writing the address to the Clean
* Invalidate Physical Address Line Register (CIPALR).
*/
putreg32(startaddr, L2CC_CIPALR);
/* Start of the next cache line */
startaddr += PL310_CACHE_LINE_SIZE;
}
/* Enable interrupts momentarily */
irqrestore(flags);
}
/* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and
* EB, are empty.
*/
flags = irqsave();
putreg32(0, L2CC_CSR);
irqrestore(flags);
}
#endif /* CONFIG_ARMV7R_L2CC_PL310 */

View file

@ -0,0 +1,433 @@
/************************************************************************************
* nuttx/arch/arm/src/armv7-r/arm_memcpy.S
*
* ARMv7-R optimised memcpy, based on the ARMv7-M version contributed by Mike Smith.
* Apparently in the public domain and is re-released here under the modified BSD
* license:
*
* Obtained via a posting on the Stellaris forum:
* http://e2e.ti.com/support/microcontrollers/\
* stellaris_arm_cortex-m3_microcontroller/f/473/t/44360.aspx
*
* Posted by rocksoft on Jul 24, 2008 10:19 AM
*
* Hi,
*
* I recently finished a "memcpy" replacement and thought it might be useful for
* others...
*
* I've put some instructions and the code here:
*
* http://www.rock-software.net/downloads/memcpy/
*
* Hope it works for you as well as it did for me.
*
* Liam.
*
* 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.
*
************************************************************************************/
/************************************************************************************
* Public Symbols
************************************************************************************/
.global memcpy
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_memcpy.S"
/************************************************************************************
* .text
************************************************************************************/
.text
/************************************************************************************
* Private Constant Data
************************************************************************************/
/* We have 16 possible alignment combinations of src and dst, this jump table
* directs the copy operation
*
* Bits: Src=00, Dst=00 - Long to Long copy
* Bits: Src=00, Dst=01 - Long to Byte before half word
* Bits: Src=00, Dst=10 - Long to Half word
* Bits: Src=00, Dst=11 - Long to Byte before long word
* Bits: Src=01, Dst=00 - Byte before half word to long
* Bits: Src=01, Dst=01 - Byte before half word to byte before half word -
* Same alignment
* Bits: Src=01, Dst=10 - Byte before half word to half word
* Bits: Src=01, Dst=11 - Byte before half word to byte before long word
* Bits: Src=10, Dst=00 - Half word to long word
* Bits: Src=10, Dst=01 - Half word to byte before half word
* Bits: Src=10, Dst=10 - Half word to half word - Same Alignment
* Bits: Src=10, Dst=11 - Half word to byte before long word
* Bits: Src=11, Dst=00 - Byte before long word to long word
* Bits: Src=11, Dst=01 - Byte before long word to byte before half word
* Bits: Src=11, Dst=11 - Byte before long word to half word
* Bits: Src=11, Dst=11 - Byte before long word to Byte before long word -
* Same alignment
*/
MEM_DataCopyTable:
.byte (MEM_DataCopy0 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy1 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy2 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy3 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy4 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy5 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy6 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy7 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy8 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy9 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy10 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy11 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy12 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy13 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy14 - MEM_DataCopyJump) >> 1
.byte (MEM_DataCopy15 - MEM_DataCopyJump) >> 1
.align 2
MEM_LongCopyTable:
.byte (MEM_LongCopyEnd - MEM_LongCopyJump) >> 1 /* 0 bytes left */
.byte 0 /* 4 bytes left */
.byte (1 * 10) >> 1 /* 8 bytes left */
.byte (2 * 10) >> 1 /* 12 bytes left */
.byte (3 * 10) >> 1 /* 16 bytes left */
.byte (4 * 10) >> 1 /* 20 bytes left */
.byte (5 * 10) >> 1 /* 24 bytes left */
.byte (6 * 10) >> 1 /* 28 bytes left */
.byte (7 * 10) >> 1 /* 32 bytes left */
.byte (8 * 10) >> 1 /* 36 bytes left */
.align 2
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: memcpy
*
* Description:
* Optimised "general" copy routine
*
* Input Parameters:
* r0 = destination, r1 = source, r2 = length
*
* Returned Value:
* r0 = destination r1-r3 burned
*
************************************************************************************/
.align 4
memcpy:
push {r14}
push {r0}
bl _do_memcpy
pop {r0}
pop {pc}
.align 4
_do_memcpy:
push {r14}
/* This allows the inner workings to "assume" a minimum amount of bytes */
/* Quickly check for very short copies */
cmp r2, #4
blt.n MEM_DataCopyBytes
and r14, r0, #3 /* Get destination alignment bits */
bfi r14, r1, #2, #2 /* Get source alignment bits */
ldr r3, =MEM_DataCopyTable /* Jump table base */
tbb [r3, r14] /* Perform jump on src/dst alignment bits */
MEM_DataCopyJump:
.align 4
/* Bits: Src=01, Dst=01 - Byte before half word to byte before half word - Same alignment
* 3 bytes to read for long word aligning
*/
MEM_DataCopy5:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=10, Dst=10 - Half word to half word - Same Alignment
* 2 bytes to read for long word aligning
*/
MEM_DataCopy10:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - Same alignment
* 1 bytes to read for long word aligning
*/
MEM_DataCopy15:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=00, Dst=00 - Long to Long copy */
MEM_DataCopy0:
/* Save regs that may be used by memcpy */
push {r4-r12}
/* Check for short word-aligned copy */
cmp r2, #0x28
blt.n MEM_DataCopy0_2
/* Bulk copy loop */
MEM_DataCopy0_1:
ldmia r1!, {r3-r12}
stmia r0!, {r3-r12}
sub r2, r2, #0x28
cmp r2, #0x28
bge.n MEM_DataCopy0_1
/* Copy remaining long words */
MEM_DataCopy0_2:
/* Copy remaining long words */
ldr r14, =MEM_LongCopyTable
lsr r11, r2, #0x02
tbb [r14, r11]
/* longword copy branch table anchor */
MEM_LongCopyJump:
ldr.w r3, [r1], #0x04 /* 4 bytes remain */
str.w r3, [r0], #0x04
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r4} /* 8 bytes remain */
stmia.w r0!, {r3-r4}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r5} /* 12 bytes remain */
stmia.w r0!, {r3-r5}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r6} /* 16 bytes remain */
stmia.w r0!, {r3-r6}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r7} /* 20 bytes remain */
stmia.w r0!, {r3-r7}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r8} /* 24 bytes remain */
stmia.w r0!, {r3-r8}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r9} /* 28 bytes remain */
stmia.w r0!, {r3-r9}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r10} /* 32 bytes remain */
stmia.w r0!, {r3-r10}
b.n MEM_LongCopyEnd
ldmia.w r1!, {r3-r11} /* 36 bytes remain */
stmia.w r0!, {r3-r11}
MEM_LongCopyEnd:
pop {r4-r12}
and r2, r2, #0x03 /* All the longs have been copied */
/* Deal with up to 3 remaining bytes */
MEM_DataCopyBytes:
/* Deal with up to 3 remaining bytes */
cmp r2, #0x00
it eq
popeq {pc}
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
subs r2, r2, #0x01
it eq
popeq {pc}
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
subs r2, r2, #0x01
it eq
popeq {pc}
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
pop {pc}
.align 4
/* Bits: Src=01, Dst=11 - Byte before half word to byte before long word
* 3 bytes to read for long word aligning the source
*/
MEM_DataCopy7:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=10, Dst=00 - Half word to long word
* 2 bytes to read for long word aligning the source
*/
MEM_DataCopy8:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=11, Dst=01 - Byte before long word to byte before half word
* 1 byte to read for long word aligning the source
*/
MEM_DataCopy13:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=00, Dst=10 - Long to Half word */
MEM_DataCopy2:
cmp r2, #0x28
blt.n MEM_DataCopy2_1
/* Save regs */
push {r4-r12}
/* Bulk copy loop */
MEM_DataCopy2_2:
ldmia r1!, {r3-r12}
strh r3, [r0], #0x02
lsr r3, r3, #0x10
bfi r3, r4, #0x10, #0x10
lsr r4, r4, #0x10
bfi r4, r5, #0x10, #0x10
lsr r5, r5, #0x10
bfi r5, r6, #0x10, #0x10
lsr r6, r6, #0x10
bfi r6, r7, #0x10, #0x10
lsr r7, r7, #0x10
bfi r7, r8, #0x10, #0x10
lsr r8, r8, #0x10
bfi r8, r9, #0x10, #0x10
lsr r9, r9, #0x10
bfi r9, r10, #0x10, #0x10
lsr r10, r10, #0x10
bfi r10, r11, #0x10, #0x10
lsr r11, r11, #0x10
bfi r11, r12, #0x10, #0x10
stmia r0!, {r3-r11}
lsr r12, r12, #0x10
strh r12, [r0], #0x02
sub r2, r2, #0x28
cmp r2, #0x28
bge.n MEM_DataCopy2_2
pop {r4-r12}
MEM_DataCopy2_1: /* Read longs and write 2 x half words */
cmp r2, #4
blt.n MEM_DataCopyBytes
ldr r3, [r1], #0x04
strh r3, [r0], #0x02
lsr r3, r3, #0x10
strh r3, [r0], #0x02
sub r2, r2, #0x04
b.n MEM_DataCopy2
/* Bits: Src=01, Dst=00 - Byte before half word to long
* Bits: Src=01, Dst=10 - Byte before half word to half word
* 3 bytes to read for long word aligning the source
*/
MEM_DataCopy4:
MEM_DataCopy6:
/* Read B and write B */
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=10, Dst=01 - Half word to byte before half word
* Bits: Src=10, Dst=11 - Half word to byte before long word
* 2 bytes to read for long word aligning the source
*/
MEM_DataCopy9:
MEM_DataCopy11:
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=11, Dst=00 -chm Byte before long word to long word
* Bits: Src=11, Dst=11 - Byte before long word to half word
* 1 byte to read for long word aligning the source
*/
MEM_DataCopy12:
MEM_DataCopy14:
/* Read B and write B */
ldrb r3, [r1], #0x01
strb r3, [r0], #0x01
sub r2, r2, #0x01
/* Bits: Src=00, Dst=01 - Long to Byte before half word
* Bits: Src=00, Dst=11 - Long to Byte before long word
*/
MEM_DataCopy1: /* Read longs, write B->H->B */
MEM_DataCopy3:
cmp r2, #4
blt MEM_DataCopyBytes
ldr r3, [r1], #0x04
strb r3, [r0], #0x01
lsr r3, r3, #0x08
strh r3, [r0], #0x02
lsr r3, r3, #0x10
strb r3, [r0], #0x01
sub r2, r2, #0x04
b.n MEM_DataCopy3
.size memcpy, .-memcpy
.end

View file

@ -0,0 +1,316 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_mpu.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <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
* higher 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;
}

View file

@ -0,0 +1,175 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_prefetchabort.c
*
* Copyright (C) 2015 Gregory Nutt. 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>
/* Output debug info if stack dump is selected -- even if debug is not
* selected.
*/
#ifdef CONFIG_ARCH_STACKDUMP
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
#endif
#include <stdint.h>
#include <debug.h>
#include <nuttx/irq.h>
#ifdef CONFIG_PAGING
# include <nuttx/page.h>
#endif
#include "sched/sched.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_prefetchabort
*
* Description;
* This is the prefetch abort exception handler. The ARM prefetch abort
* exception occurs when a memory fault is detected during an an
* instruction fetch.
*
****************************************************************************/
#ifdef CONFIG_PAGING
uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
{
uint32_t *savestate;
/* Save the saved processor context in current_regs where it can be accessed
* for register dumps and possibly context switching.
*/
savestate = (uint32_t *)current_regs;
current_regs = regs;
/* Get the (virtual) address of instruction that caused the prefetch abort.
* When the exception occurred, this address was provided in the lr register
* and this value was saved in the context save area as the PC at the
* REG_R15 index.
*
* Check to see if this miss address is within the configured range of
* virtual addresses.
*/
pglldbg("VADDR: %08x VBASE: %08x VEND: %08x\n",
regs[REG_PC], PG_PAGED_VBASE, PG_PAGED_VEND);
if (regs[REG_R15] >= PG_PAGED_VBASE && regs[REG_R15] < PG_PAGED_VEND)
{
/* Save the offending PC as the fault address in the TCB of the currently
* executing task. This value is, of course, already known in regs[REG_R15],
* but saving it in this location will allow common paging logic for both
* prefetch and data aborts.
*/
FAR struct tcb_s *tcb = (FAR struct tcb_s *)g_readytorun.head;
tcb->xcp.far = regs[REG_R15];
/* Call pg_miss() to schedule the page fill. A consequences of this
* call are:
*
* (1) The currently executing task will be blocked and saved on
* on the g_waitingforfill task list.
* (2) An interrupt-level context switch will occur so that when
* this function returns, it will return to a different task,
* most likely the page fill worker thread.
* (3) The page fill worker task has been signalled and should
* execute immediately when we return from this exception.
*/
pg_miss();
/* 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;
}
else
{
lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n",
regs[REG_PC], ifar, ifsr);
PANIC();
}
return regs;
}
#else /* CONFIG_PAGING */
uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr)
{
/* Save the saved processor context in current_regs where it can be accessed
* for register dumps and possibly context switching.
*/
current_regs = regs;
/* Crash -- possibly showing diagnostic debug information. */
lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n",
regs[REG_PC], ifar, ifsr);
PANIC();
return regs; /* To keep the compiler happy */
}
#endif /* CONFIG_PAGING */

View file

@ -0,0 +1,135 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_releasepending.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.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 = (struct tcb_s *)g_readytorun.head;
slldbg("From TCB=%p\n", rtcb);
/* Merge the g_pendingtasks list into the g_readytorun task list */
/* sched_lock(); */
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 g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
up_restorestate(rtcb->xcp.regs);
}
/* Copy the exception context into the TCB of the task that
* was currently active. if up_saveusercontext returns a non-zero
* value, then this is really the previously running task
* restarting!
*/
else if (!up_saveusercontext(rtcb->xcp.regs))
{
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
up_fullcontextrestore(rtcb->xcp.regs);
}
}
}

View file

@ -0,0 +1,189 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_reprioritizertr.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <stdbool.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.h"
#include "up_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_reprioritize_rtr
*
* Description:
* Called when the priority of a running or
* ready-to-run task changes and the reprioritization will
* cause a context switch. Two cases:
*
* 1) The priority of the currently running task drops and the next
* task in the ready to run list has priority.
* 2) An idle, ready to run task's priority has been raised above the
* the priority of the current, running task and it now has the
* priority.
*
* Inputs:
* tcb: The TCB of the task that has been reprioritized
* priority: The new task priority
*
****************************************************************************/
void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
{
/* Verify that the caller is sane */
if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
tcb->task_state > LAST_READY_TO_RUN_STATE
#if SCHED_PRIORITY_MIN > 0
|| priority < SCHED_PRIORITY_MIN
#endif
#if SCHED_PRIORITY_MAX < UINT8_MAX
|| priority > SCHED_PRIORITY_MAX
#endif
)
{
PANIC();
}
else
{
struct tcb_s *rtcb = (struct tcb_s *)g_readytorun.head;
bool switch_needed;
slldbg("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
* remove 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 specified blocked task list.
* sched_addreadytorun will return true if the task was
* added to the new 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 */
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 g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
up_restorestate(rtcb->xcp.regs);
}
/* Copy the exception context into the TCB at the (old) head of the
* g_readytorun Task list. if up_saveusercontext returns a non-zero
* value, then this is really the previously running task restarting!
*/
else if (!up_saveusercontext(rtcb->xcp.regs))
{
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
up_fullcontextrestore(rtcb->xcp.regs);
}
}
}
}

View file

@ -0,0 +1,110 @@
/************************************************************************************
* arch/arm/src/armv7-r/arm_restorefpu.S
*
* Copyright (C) 2015 Gregory Nutt. 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>
#ifdef CONFIG_ARCH_FPU
/************************************************************************************
* Public Symbols
************************************************************************************/
.globl up_restorefpu
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_restorefpu.S"
/************************************************************************************
* Public Functions
************************************************************************************/
.text
/************************************************************************************
* 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.
*
************************************************************************************/
.globl up_restorefpu
.type up_restorefpu, function
up_restorefpu:
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
/* 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 */
bx lr
.size up_restorefpu, .-up_restorefpu
#endif /* CONFIG_ARCH_FPU */
.end

View file

@ -0,0 +1,106 @@
/************************************************************************************
* arch/arm/src/armv7-r/arm_savefpu.S
*
* Copyright (C) 2015 Gregory Nutt. 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>
#ifdef CONFIG_ARCH_FPU
.file "arm_savefpu.S"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/************************************************************************************
* Public Symbols
************************************************************************************/
.globl up_savefpu
/************************************************************************************
* Public Functions
************************************************************************************/
.text
/************************************************************************************
* 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
*
************************************************************************************/
.globl up_savefpu
.type up_savefpu, function
up_savefpu:
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
/* 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 */
bx lr
.size up_savefpu, .-up_savefpu
#endif /* CONFIG_ARCH_FPU */
.end

View file

@ -0,0 +1,132 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_saveusercontext.S
*
* Copyright (C) 2015 Gregory Nutt. 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/irq.h>
#include "up_internal.h"
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl up_saveusercontext
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_saveusercontext.S"
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: up_saveusercontext
****************************************************************************/
.globl up_saveusercontext
.type up_saveusercontext, function
up_saveusercontext:
/* On entry, a1 (r0) holds address of struct xcptcontext */
/* Make sure that the return value will be non-zero (the value of the
* other volatile registers don't matter -- r1-r3, ip). This function
* is called through the normal C calling conventions and the values of
* these registers cannot be assumed at the point of setjmp return.
*/
mov ip, #1
str ip, [r0, #(4*REG_R0)]
/* Save the volatile registers (plus r12 which really
* doesn't need to be saved)
*/
add r1, r0, #(4*REG_R4)
stmia r1, {r4-r14}
/* Save the current cpsr */
mrs r2, cpsr /* R3 = CPSR value */
add r1, r0, #(4*REG_CPSR)
str r2, [r1]
/* Save the return address as the PC so that we return to the exit from
* this function.
*/
add r1, r0, #(4*REG_PC)
str lr, [r1]
/* Save the floating point registers.
* REVISIT: Not all of the floating point registers need to be saved.
* Some are volatile and need not be preserved across functions calls.
* But right now, I can't find the definitive list of the volatile
* floating point registers.
*/
#ifdef CONFIG_ARCH_FPU
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
/* 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 */
#endif
/* Return 0 now indicating that this return is not a context switch */
mov r0, #0 /* Return value == 0 */
mov pc, lr /* Return */
.size up_saveusercontext, . - up_saveusercontext
.end

View file

@ -0,0 +1,203 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_schedulesigaction.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "arm.h"
#include "sched/sched.h"
#include "up_internal.h"
#include "up_arch.h"
#ifndef CONFIG_DISABLE_SIGNALS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_schedule_sigaction
*
* Description:
* This function is called by the OS when one or more
* signal handling actions have been queued for execution.
* The architecture specific code must configure things so
* that the 'sigdeliver' callback is executed on the thread
* specified by 'tcb' as soon as possible.
*
* This function may be called from interrupt handling logic.
*
* This operation should not cause the task to be unblocked
* nor should it cause any immediate execution of sigdeliver.
* Typically, a few cases need to be considered:
*
* (1) This function may be called from an interrupt handler
* During interrupt processing, all xcptcontext structures
* should be valid for all tasks. That structure should
* be modified to invoke sigdeliver() either on return
* from (this) interrupt or on some subsequent context
* switch to the recipient task.
* (2) If not in an interrupt handler and the tcb is NOT
* the currently executing task, then again just modify
* the saved xcptcontext structure for the recipient
* task so it will invoke sigdeliver when that task is
* later resumed.
* (3) If not in an interrupt handler and the tcb IS the
* currently executing task -- just call the signal
* handler now.
*
****************************************************************************/
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
irqstate_t flags;
sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
/* Make sure that interrupts are disabled */
flags = irqsave();
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
*/
sdbg("rtcb=0x%p current_regs=0x%p\n", g_readytorun.head, current_regs);
if (tcb == (struct tcb_s *)g_readytorun.head)
{
/* CASE 1: We are not in an interrupt handler and a task is
* signalling itself for some reason.
*/
if (!current_regs)
{
/* In this case just deliver the signal now. */
sigdeliver(tcb);
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state
* in the TCB.
*
* Hmmm... there looks like a latent bug here: The following logic
* would fail in the strange case where we are in an interrupt
* handler, the thread is signalling itself, but a context switch
* to another task has occurred so that current_regs does not
* refer to the thread at g_readytorun.head!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
tcb->xcp.sigdeliver = sigdeliver;
tcb->xcp.saved_pc = current_regs[REG_PC];
tcb->xcp.saved_cpsr = current_regs[REG_CPSR];
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
current_regs[REG_PC] = (uint32_t)up_sigdeliver;
current_regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT);
/* And make sure that the saved context in the TCB is the same
* as the interrupt return context.
*/
up_savestate(tcb->xcp.regs);
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signalling some non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
tcb->xcp.sigdeliver = sigdeliver;
tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR];
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT);
}
}
irqrestore(flags);
}
#endif /* !CONFIG_DISABLE_SIGNALS */

View file

@ -0,0 +1,139 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_sigdeliver.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <stdint.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "sched/sched.h"
#include "up_internal.h"
#include "up_arch.h"
#ifndef CONFIG_DISABLE_SIGNALS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_sigdeliver
*
* Description:
* This is the a signal handling trampoline. When a signal action was
* posted. The task context was mucked with and forced to branch to this
* location with interrupts disabled.
*
****************************************************************************/
void up_sigdeliver(void)
{
struct tcb_s *rtcb = (struct tcb_s *)g_readytorun.head;
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
* EINTR).
*/
int saved_errno = rtcb->pterrno;
board_autoled_on(LED_SIGNAL);
sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
ASSERT(rtcb->xcp.sigdeliver != NULL);
/* Save the real return state on the stack. */
up_copyfullstate(regs, rtcb->xcp.regs);
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
/* Get a local copy of the sigdeliver function pointer. we do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
/* Then restore the task interrupt state */
irqrestore(regs[REG_CPSR]);
/* Deliver the signals */
sigdeliver(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
* errno that is needed by the user logic (it is probably EINTR).
*/
sdbg("Resuming\n");
(void)irqsave();
rtcb->pterrno = saved_errno;
/* Then restore the correct state for this thread of execution. */
board_autoled_off(LED_SIGNAL);
up_fullcontextrestore(regs);
}
#endif /* !CONFIG_DISABLE_SIGNALS */

View file

@ -0,0 +1,119 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_signal_dispatch.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <nuttx/arch.h>
#include "svcall.h"
#include "pgalloc.h"
#include "up_internal.h"
#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_signal_dispatch
*
* Description:
* In this kernel mode build, this function will be called to execute a
* a signal handler in user-space. When the signal is delivered, a
* kernel-mode stub will first run to perform some housekeeping functions.
* This kernel-mode stub will then be called transfer control to the user
* mode signal handler by calling this function.
*
* Normally the a user-mode signalling handling stub will also execute
* before the ultimate signal handler is called. See
* arch/arm/src/armv[6\7]/up_signal_handler. This function is the
* user-space, signal handler trampoline function. It is called from
* up_signal_dispatch() in user-mode.
*
* Inputs:
* sighand - The address user-space signal handling function
* signo, info, and ucontext - Standard arguments to be passed to the
* signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via an architecture specific system call made by up_signal_handler().
* However, this will look like a normal return by the caller of
* up_signal_dispatch.
*
****************************************************************************/
void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
FAR siginfo_t *info, FAR void *ucontext)
{
/* We are signalling a user group, but does the signal handler lie in the
* user address space? Or the kernel address space? The OS does
* intercept some signals for its own purpose (such as the death-of-child
* signal.
*/
if (arm_uservaddr((uintptr_t)sighand))
{
/* Yes.. Let sys_call4() do all of the work to get us into user space */
(void)sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo,
(uintptr_t)info, (uintptr_t)ucontext);
}
else
{
/* No.. we are already in kernel mode so just call the handler */
sighand(signo, info, ucontext);
}
}
#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_SIGNALS */

View file

@ -0,0 +1,121 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_signal_handler.S
*
* Copyright (C) 2015 Gregory Nutt. 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/syscall.h>
#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
/****************************************************************************
* File info
****************************************************************************/
#ifdef CONFIG_ARCH_FPU
.cpu cortex-r4
#else
.cpu cortex-r4f
#endif
.syntax unified
.file "arm_signal_handler.S"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: up_signal_handler
*
* Description:
* This function is the user-space, signal handler trampoline function. It
* is called from up_signal_dispatch() in user-mode.
*
* R0-R3, R11 - volatile registers need not be preserved.
* R4-R10 - static registers must be preserved
* R12-R14 - LR and SP must be preserved
*
* Inputs:
* R0 = sighand
* The address user-space signal handling function
* R1-R3 = signo, info, and ucontext
* Standard arguments to be passed to the signal handling function.
*
* Return:
* None. This function does not return in the normal sense. It returns
* via the SYS_signal_handler_return (see svcall.h)
*
****************************************************************************/
.globl up_signal_handler
.type up_signal_handler, function
up_signal_handler:
/* Save some register */
push {lr} /* Save LR on the stack */
/* Call the signal handler */
mov ip, r0 /* IP=sighand */
mov r0, r1 /* R0=signo */
mov r1, r2 /* R1=info */
mov r2, r3 /* R2=ucontext */
blx ip /* Call the signal handler */
/* Restore the registers */
pop {r2} /* Recover LR in R2 */
mov lr, r2 /* Restore LR */
/* Execute the SYS_signal_handler_return SVCall (will not return) */
mov r0, #SYS_signal_handler_return
svc 0
nop
.size up_signal_handler, .-up_signal_handler
.end
#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */

View file

@ -0,0 +1,532 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_syscall.c
*
* Copyright (C) 2015 Gregory Nutt. 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>
/* Output debug info if stack dump is selected -- even if debug is not
* selected.
*/
#ifdef CONFIG_ARCH_STACKDUMP
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
#endif
#include <stdint.h>
#include <string.h>
#include <syscall.h>
#include <assert.h>
#include <debug.h>
#include <arch/irq.h>
#include <nuttx/sched.h>
#include "arm.h"
#include "svcall.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Debug ********************************************************************/
#if defined(CONFIG_DEBUG_SYSCALL)
# define svcdbg(format, ...) lldbg(format, ##__VA_ARGS__)
#else
# define svcdbg(x...)
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Name: dispatch_syscall
*
* Description:
* Call the stub function corresponding to the system call. NOTE the non-
* standard parameter passing:
*
* R0 = SYS_ call number
* R1 = parm0
* R2 = parm1
* R3 = parm2
* R4 = parm3
* R5 = parm4
* R6 = parm5
*
* The values of R4-R5 may be preserved in the proxy called by the user
* code if they are used (but otherwise will not be).
*
* WARNING: There are hard-coded values in this logic!
*
* Register usage:
*
* R0 - Need not be preserved.
* R1-R3 - Need to be preserved until the stub is called. The values of
* R0 and R1 returned by the stub must be preserved.
* R4-R11 must be preserved to support the expectations of the user-space
* callee. R4-R6 may have been preserved by the proxy, but don't know
* for sure.
* R12 - Need not be preserved
* R13 - (stack pointer)
* R14 - Need not be preserved
* R15 - (PC)
*
****************************************************************************/
#ifdef CONFIG_LIB_SYSCALL
static void dispatch_syscall(void) naked_function;
static void dispatch_syscall(void)
{
__asm__ __volatile__
(
" sub sp, sp, #16\n" /* Create a stack frame to hold 3 parms + lr */
" str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */
" str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */
" str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */
" str lr, [sp, #12]\n" /* Save lr in the stack frame */
" ldr ip, =g_stublookup\n" /* R12=The base of the stub lookup table */
" ldr ip, [ip, r0, lsl #2]\n" /* R12=The address of the stub for this SYSCALL */
" blx ip\n" /* Call the stub (modifies lr) */
" ldr lr, [sp, #12]\n" /* Restore lr */
" add sp, sp, #16\n" /* Destroy the stack frame */
" mov r2, r0\n" /* R2=Save return value in R2 */
" mov r0, #0\n" /* R0=SYS_syscall_return */
" svc #0x900001\n" /* Return from the SYSCALL */
);
}
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_syscall
*
* Description:
* SVC interrupts will vector here with insn=the SVC instruction and
* xcp=the interrupt context
*
* The handler may get the SVC number be de-referencing the return
* address saved in the xcp and decoding the SVC instruction
*
****************************************************************************/
#ifdef CONFIG_LIB_SYSCALL
uint32_t *arm_syscall(uint32_t *regs)
{
uint32_t cmd;
#ifdef CONFIG_BUILD_KERNEL
uint32_t cpsr;
#endif
/* Nested interrupts are not supported */
DEBUGASSERT(regs);
/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */
cmd = regs[REG_R0];
/* The SVCall software interrupt is called with R0 = system call command
* and R1..R7 = variable number of arguments depending on the system call.
*/
#if defined(CONFIG_DEBUG_SYSCALL)
svcdbg("SYSCALL Entry: regs: %p cmd: %d\n", regs, cmd);
svcdbg(" 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]);
svcdbg(" 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]);
svcdbg("CPSR: %08x\n", regs[REG_CPSR]);
#endif
/* Handle the SVCall according to the command in R0 */
switch (cmd)
{
/* R0=SYS_syscall_return: This a SYSCALL return command:
*
* void up_syscall_return(void);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_syscall_return
*
* We need to restore the saved return address and return in
* unprivileged thread mode.
*/
case SYS_syscall_return:
{
FAR struct tcb_s *rtcb = sched_self();
int index = (int)rtcb->xcp.nsyscalls - 1;
/* Make sure that there is a saved SYSCALL return address. */
DEBUGASSERT(index >= 0);
/* Setup to return to the saved SYSCALL return address in
* the original mode.
*/
regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn;
#ifdef CONFIG_BUILD_KERNEL
regs[REG_CPSR] = rtcb->xcp.syscall[index].cpsr;
#endif
/* The return value must be in R0-R1. dispatch_syscall() temporarily
* moved the value for R0 into R2.
*/
regs[REG_R0] = regs[REG_R2];
#ifdef CONFIG_ARCH_KERNEL_STACK
/* If this is the outermost SYSCALL and if there is a saved user stack
* pointer, then restore the user stack pointer on this final return to
* user code.
*/
if (index == 0 && rtcb->xcp.ustkptr != NULL)
{
regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr;
rtcb->xcp.ustkptr = NULL;
}
#endif
/* Save the new SYSCALL nesting level */
rtcb->xcp.nsyscalls = index;
}
break;
/* R0=SYS_context_restore: Restore task context
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_context_restore
* R1 = restoreregs
*/
#ifdef CONFIG_BUILD_KERNEL
case SYS_context_restore:
{
/* Replace 'regs' with the pointer to the register set in
* regs[REG_R1]. On return from the system call, that register
* set will determine the restored context.
*/
regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(regs);
}
break;
#endif
/* R0=SYS_task_start: This a user task start
*
* void up_task_start(main_t taskentry, int argc, FAR char *argv[]) noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_task_start
* R1 = taskentry
* R2 = argc
* R3 = argv
*/
#ifdef CONFIG_BUILD_KERNEL
case SYS_task_start:
{
/* Set up to return to the user-space _start function in
* unprivileged mode. We need:
*
* R0 = argc
* R1 = argv
* PC = taskentry
* CSPR = user mode
*/
regs[REG_PC] = regs[REG_R1];
regs[REG_R0] = regs[REG_R2];
regs[REG_R1] = regs[REG_R3];
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
}
break;
#endif
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
*/
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode. We need:
*
* R0 = arg
* PC = entrypt
* CSPR = user mode
*/
regs[REG_PC] = regs[REG_R1];
regs[REG_R0] = regs[REG_R2];
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
}
break;
#endif
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
/* R0=SYS_signal_handler: This a user signal handler callback
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
* FAR siginfo_t *info, FAR void *ucontext);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_signal_handler
* R1 = sighand
* R2 = signo
* R3 = info
* ucontext (on the stack)
*/
case SYS_signal_handler:
{
FAR struct tcb_s *rtcb = sched_self();
/* Remember the caller's return address */
DEBUGASSERT(rtcb->xcp.sigreturn == 0);
rtcb->xcp.sigreturn = regs[REG_PC];
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)ARCH_DATA_RESERVE->ar_sigtramp;
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
*/
regs[REG_R0] = regs[REG_R1]; /* sighand */
regs[REG_R1] = regs[REG_R2]; /* signal */
regs[REG_R2] = regs[REG_R3]; /* info */
/* The last parameter, ucontext, is trickier. The ucontext
* parameter will reside at an offset of 4 from the stack pointer.
*/
regs[REG_R3] = *(uint32_t *)(regs[REG_SP]+4);
#ifdef CONFIG_ARCH_KERNEL_STACK
/* If we are signalling a user process, then we must be operating
* on the kernel stack now. We need to switch back to the user
* stack before dispatching the signal handler to the user code.
* The existence of an allocated kernel stack is sufficient
* information to make this decision.
*/
if (rtcb->xcp.kstack != NULL)
{
DEBUGASSERT(rtcb->xcp.kstkptr == NULL && rtcb->xcp.ustkptr != NULL);
rtcb->xcp.kstkptr = (FAR uint32_t *)regs[REG_SP];
regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr;
}
#endif
}
break;
#endif
#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
/* R0=SYS_signal_handler_return: This a user signal handler callback
*
* void signal_handler_return(void);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_signal_handler_return
*/
case SYS_signal_handler_return:
{
FAR struct tcb_s *rtcb = sched_self();
/* Set up to return to the kernel-mode signal dispatching logic. */
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_PC] = rtcb->xcp.sigreturn;
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
rtcb->xcp.sigreturn = 0;
#ifdef CONFIG_ARCH_KERNEL_STACK
/* We must enter here be using the user stack. We need to switch
* to back to the kernel user stack before returning to the kernel
* mode signal trampoline.
*/
if (rtcb->xcp.kstack != NULL)
{
DEBUGASSERT(rtcb->xcp.kstkptr != NULL &&
(uint32_t)rtcb->xcp.ustkptr == regs[REG_SP]);
regs[REG_SP] = (uint32_t)rtcb->xcp.kstkptr;
rtcb->xcp.kstkptr = NULL;
}
#endif
}
break;
#endif
/* This is not an architecture-specific system call. If NuttX is built
* as a standalone kernel with a system call interface, then all of the
* additional system calls must be handled as in the default case.
*/
default:
{
#ifdef CONFIG_LIB_SYSCALL
FAR struct tcb_s *rtcb = sched_self();
int index = rtcb->xcp.nsyscalls;
/* Verify that the SYS call number is within range */
DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall);
/* Make sure that there is a no saved SYSCALL return address. We
* cannot yet handle nested system calls.
*/
DEBUGASSERT(index < CONFIG_SYS_NNEST);
/* Setup to return to dispatch_syscall in privileged mode. */
rtcb->xcp.syscall[index].sysreturn = regs[REG_PC];
#ifdef CONFIG_BUILD_KERNEL
rtcb->xcp.syscall[index].cpsr = regs[REG_CPSR];
#endif
regs[REG_PC] = (uint32_t)dispatch_syscall;
#ifdef CONFIG_BUILD_KERNEL
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
#endif
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
#else
svcdbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif
#ifdef CONFIG_ARCH_KERNEL_STACK
/* If this is the first SYSCALL and if there is an allocated
* kernel stack, then switch to the kernel stack.
*/
if (index == 0 && rtcb->xcp.kstack != NULL)
{
rtcb->xcp.ustkptr = (FAR uint32_t *)regs[REG_SP];
regs[REG_SP] = (uint32_t)rtcb->xcp.kstack + ARCH_KERNEL_STACKSIZE;
}
#endif
/* Save the new SYSCALL nesting level */
rtcb->xcp.nsyscalls = index + 1;
}
break;
}
#if defined(CONFIG_DEBUG_SYSCALL)
/* Report what happened */
svcdbg("SYSCALL Exit: regs: %p\n", regs);
svcdbg(" 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]);
svcdbg(" 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]);
svcdbg("CPSR: %08x\n", regs[REG_CPSR]);
#endif
/* Return the last value of curent_regs. This supports context switches
* on return from the exception. That capability is only used with the
* SYS_context_switch system call.
*/
return regs;
}
#else
uint32_t *arm_syscall(uint32_t *regs)
{
lldbg("SYSCALL from 0x%x\n", regs[REG_PC]);
current_regs = regs;
PANIC();
}
#endif

View file

@ -0,0 +1,162 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_unblocktask.c
*
* Copyright (C) 2015 Gregory Nutt. 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 <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.h"
#include "clock/clock.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_unblock_task
*
* Description:
* A task is currently in an inactive task list
* but has been prepped to execute. Move the TCB to the
* ready-to-run list, restore its context, and start execution.
*
* Inputs:
* tcb: Refers to the tcb to be unblocked. This tcb is
* in one of the waiting tasks lists. It must be moved to
* the ready-to-run list and, if it is the highest priority
* ready to run task, executed.
*
****************************************************************************/
void up_unblock_task(struct tcb_s *tcb)
{
struct tcb_s *rtcb = (struct tcb_s *)g_readytorun.head;
/* Verify that the context switch can be performed */
ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) &&
(tcb->task_state <= LAST_BLOCKED_STATE));
/* Remove the task from the blocked task list */
sched_removeblocked(tcb);
/* Add the task in the correct location in the prioritized
* g_readytorun task list
*/
if (sched_addreadytorun(tcb))
{
/* The currently active task has changed! We need to do
* a context switch to the new task.
*/
/* Update scheduler parameters */
sched_suspend_scheduler(rtcb);
/* Are we in an interrupt handler? */
if (current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
up_restorestate(rtcb->xcp.regs);
}
/* We are not in an interrupt handler. Copy the user C context
* into the TCB of the task that was previously active. if
* up_saveusercontext returns a non-zero value, then this is really the
* previously running task restarting!
*/
else if (!up_saveusercontext(rtcb->xcp.regs))
{
/* Restore the exception context of the new task that is ready to
* run (probably tcb). This is the new rtcb at the head of the
* g_readytorun task list.
*/
rtcb = (struct tcb_s *)g_readytorun.head;
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts */
up_fullcontextrestore(rtcb->xcp.regs);
}
}
}

View file

@ -0,0 +1,87 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_undefinedinsn.c
*
* Copyright (C) 2015 Gregory Nutt. 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>
/* Output debug info if stack dump is selected -- even if debug is not
* selected.
*/
#ifdef CONFIG_ARCH_STACKDUMP
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
#endif
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <arch/irq.h>
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_undefinedinsn
****************************************************************************/
uint32_t *arm_undefinedinsn(uint32_t *regs)
{
lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]);
current_regs = regs;
PANIC();
return regs; /* To keep the compiler happy */
}

View file

@ -0,0 +1,87 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_vectoraddrexceptn.S
*
* Copyright (C) 2015 Gregory Nutt. 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 <nuttx/irq.h>
#include "up_arch.h"
.file "arm_vectoraddrexcptn.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl arm_vectoraddrexcption
/****************************************************************************
* Assembly Macros
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
.text
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: arm_vectoraddrexcption
*
* Description:
* Shouldn't happen. This exception handler is in a separate file from
* other vector handlers because some processors do not support the
* Address Exception vector.
*
****************************************************************************/
.globl arm_vectoraddrexcptn
.type arm_vectoraddrexcptn, %function
arm_vectoraddrexcptn:
b arm_vectoraddrexcptn
.size arm_vectoraddrexcptn, . - arm_vectoraddrexcptn
.end

View file

@ -0,0 +1,977 @@
/************************************************************************************
* arch/arm/src/armv7-r/arm_vectors.S
*
* Copyright (C) 2015 Gregory Nutt. 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 <nuttx/irq.h>
#include "arm.h"
#include "cp15.h"
.file "arm_vectors.S"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/************************************************************************************
* Private Data
************************************************************************************/
.data
g_irqtmp:
.word 0 /* Saved lr */
.word 0 /* Saved spsr */
g_undeftmp:
.word 0 /* Saved lr */
.word 0 /* Saved spsr */
g_aborttmp:
.word 0 /* Saved lr */
.word 0 /* Saved spsr */
#ifdef CONFIG_ARMV7R_DECODEFIQ
g_fiqtmp:
.word 0 /* Saved lr */
.word 0 /* Saved spsr */
#endif
/************************************************************************************
* Assembly Macros
************************************************************************************/
/************************************************************************************
* Private Functions
************************************************************************************/
.text
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: arm_vectorirq
*
* Description:
* Interrupt exception. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC
*
************************************************************************************/
.globl arm_decodeirq
.globl arm_vectorirq
.type arm_vectorirq, %function
arm_vectorirq:
/* On entry, we are in IRQ mode. We are free to use the IRQ mode r13
* and r14.
*/
ldr r13, .Lirqtmp
sub lr, lr, #4
str lr, [r13] /* Save lr_IRQ */
mrs lr, spsr
str lr, [r13, #4] /* Save spsr_IRQ */
/* Then switch back to SVC mode */
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
#ifdef CONFIG_ARMV7R_DECODEFIQ
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
#else
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT)
#endif
msr cpsr_c, lr /* Switch to SVC mode */
/* Create a context structure. First set aside a stack frame
* and store r0-r12 into the frame.
*/
sub sp, sp, #XCPTCONTEXT_SIZE
stmia sp, {r0-r12} /* Save the SVC mode regs */
/* Get the values for r15(pc) and CPSR in r3 and r4 */
ldr r0, .Lirqtmp /* Points to temp storage */
ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */
#ifdef CONFIG_BUILD_KERNEL
/* Did we enter from user mode? If so then we need get the values of
* USER mode r13(sp) and r14(lr).
*/
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
cmp r1, #PSR_MODE_USR /* User mode? */
bne .Lirqentersvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
b .Lirqcontinue
.Lirqentersvc:
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
* and r2.
*/
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
.Lirqcontinue:
#else
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
#endif
/* Then call the IRQ handler with interrupts disabled. */
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
#if CONFIG_ARCH_INTERRUPTSTACK > 3
ldr sp, .Lirqstackbase /* SP = interrupt stack base */
str r0, [sp] /* Save the user stack pointer */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_decodeirq /* Call the handler */
ldr sp, [r4] /* Restore the user stack pointer */
#else
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_decodeirq /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
#endif
/* Upon return from arm_decodeirq, r0 holds the pointer to the register
* state save area to use to restore the registers. This may or may not
* be the same value that was passed to arm_decodeirq: It will differ if a
* context switch is required.
*/
/* Restore the CPSR, SVC mode registers and return */
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr, r1 /* Set the return mode SPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
cmp r2, #PSR_MODE_USR /* User mode? */
bne .Lirqleavesvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
mov r13, r0 /* (SVC) R13=Register storage area */
ldmia r13, {r0-R12} /* Restore common R0-R12 */
add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */
ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */
add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */
ldmia r14, {r15}^ /* Return */
.Lirqleavesvc:
#endif
/* Life is simple when everything is SVC mode */
ldmia r0, {r0-r15}^ /* Return */
.Lirqtmp:
.word g_irqtmp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
.Lirqstackbase:
.word g_intstackbase
#endif
.size arm_vectorirq, . - arm_vectorirq
.align 5
/************************************************************************************
* Function: arm_vectorsvc
*
* Description:
* SVC interrupt. We enter the SVC in SVC mode.
*
************************************************************************************/
.globl arm_syscall
.globl arm_vectorsvc
.type arm_vectorsvc, %function
arm_vectorsvc:
/* Create a context structure. First set aside a stack frame
* and store r0-r12 into the frame.
*/
sub sp, sp, #XCPTCONTEXT_SIZE
stmia sp, {r0-r12} /* Save the SVC mode regs */
/* Get the values for r15(pc) and CPSR in r3 and r4 */
mov r3, r14 /* Save r14 as the PC as well */
mrs r4, spsr /* Get the saved CPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Did we enter from user mode? If so then we need get the values of
* USER mode r13(sp) and r14(lr).
*/
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
cmp r1, #PSR_MODE_USR /* User mode? */
bne .Lsvcentersvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
b .Lsvccontinue
.Lsvcentersvc:
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
* and r2.
*/
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
.Lsvccontinue:
#else
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
#endif
/* Then call the SVC handler with interrupts disabled.
* void arm_syscall(struct xcptcontext *xcp)
*/
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_syscall /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Upon return from arm_syscall, r0 holds the pointer to the register
* state save area to use to restore the registers. This may or may not
* be the same value that was passed to arm_syscall: It will differ if a
* context switch is required.
*/
/* Restore the CPSR, SVC mode registers and return */
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr, r1 /* Set the return mode SPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
cmp r2, #PSR_MODE_USR /* User mode? */
bne .Lleavesvcsvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
mov r13, r0 /* (SVC) R13=Register storage area */
ldmia r13, {r0-R12} /* Restore common R0-R12 */
add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */
ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */
add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */
ldmia r14, {r15}^ /* Return */
.Lleavesvcsvc:
#endif
/* Life is simple when everything is SVC mode */
ldmia r0, {r0-r15}^ /* Return */
.size arm_vectorsvc, . - arm_vectorsvc
.align 5
/************************************************************************************
* Name: arm_vectordata
*
* Description:
* This is the data abort exception dispatcher. The ARM data abort exception occurs
* when a memory fault is detected during a data transfer. This handler saves the
* current processor state and gives control to data abort handler. This function
* is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC
*
************************************************************************************/
.globl arm_dataabort
.globl arm_vectordata
.type arm_vectordata, %function
arm_vectordata:
/* On entry we are free to use the ABORT mode registers
* r13 and r14
*/
ldr r13, .Ldaborttmp /* Points to temp storage */
sub lr, lr, #8 /* Fixup return */
str lr, [r13] /* Save in temp storage */
mrs lr, spsr /* Get SPSR */
str lr, [r13, #4] /* Save in temp storage */
/* Then switch back to SVC mode */
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
msr cpsr_c, lr /* Switch to SVC mode */
/* Create a context structure. First set aside a stack frame
* and store r0-r12 into the frame.
*/
sub sp, sp, #XCPTCONTEXT_SIZE
stmia sp, {r0-r12} /* Save the SVC mode regs */
/* Get the values for r15(pc) and CPSR in r3 and r4 */
ldr r0, .Ldaborttmp /* Points to temp storage */
ldmia r0, {r3, r4} /* Recover r3=lr_ABT, r4=spsr_ABT */
#ifdef CONFIG_BUILD_KERNEL
/* Did we enter from user mode? If so then we need get the values of
* USER mode r13(sp) and r14(lr).
*/
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
cmp r1, #PSR_MODE_USR /* User mode? */
bne .Ldabtentersvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
b .Ldabtcontinue
.Ldabtentersvc:
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
* and r2.
*/
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
.Ldabtcontinue:
#else
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
#endif
/* Then call the data abort handler with interrupts disabled.
* void arm_dataabort(struct xcptcontext *xcp)
*/
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mrc CP15_DFAR(r1) /* Get R1=DFAR */
mrc CP15_DFSR(r2) /* Get r2=DFSR */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_dataabort /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Upon return from arm_dataabort, r0 holds the pointer to the register
* state save area to use to restore the registers. This may or may not
* be the same value that was passed to arm_dataabort: It will differ if a
* context switch is required.
*/
/* Restore the CPSR, SVC mode registers and return */
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr_cxsf, r1 /* Set the return mode SPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
cmp r2, #PSR_MODE_USR /* User mode? */
bne .Ldabtleavesvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
mov r13, r0 /* (SVC) R13=Register storage area */
ldmia r13, {r0-R12} /* Restore common R0-R12 */
add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */
ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */
add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */
ldmia r14, {r15}^ /* Return */
.Ldabtleavesvc:
#endif
/* Life is simple when everything is SVC mode */
ldmia r0, {r1-r15}^ /* Return */
.Ldaborttmp:
.word g_aborttmp
.size arm_vectordata, . - arm_vectordata
.align 5
/************************************************************************************
* Name: arm_vectorprefetch
*
* Description:
* This is the prefetch abort exception dispatcher. The ARM prefetch abort exception
* occurs when a memory fault is detected during an an instruction fetch. This
* handler saves the current processor state and gives control to prefetch abort
* handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC.
*
************************************************************************************/
.globl arm_prefetchabort
.globl arm_vectorprefetch
.type arm_vectorprefetch, %function
arm_vectorprefetch:
/* On entry we are free to use the ABORT mode registers
* r13 and r14
*/
ldr r13, .Lpaborttmp /* Points to temp storage */
sub lr, lr, #4 /* Fixup return */
str lr, [r13] /* Save in temp storage */
mrs lr, spsr /* Get SPSR */
str lr, [r13, #4] /* Save in temp storage */
/* Then switch back to SVC mode */
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
msr cpsr_c, lr /* Switch to SVC mode */
/* Create a context structure. First set aside a stack frame
* and store r0-r12 into the frame.
*/
sub sp, sp, #XCPTCONTEXT_SIZE
stmia sp, {r0-r12} /* Save the SVC mode regs */
/* Get the values for r15(pc) and CPSR in r3 and r4 */
ldr r0, .Lpaborttmp /* Points to temp storage */
ldmia r0, {r3, r4} /* Recover r3=lr_ABT, r4=spsr_ABT */
#ifdef CONFIG_BUILD_KERNEL
/* Did we enter from user mode? If so then we need get the values of
* USER mode r13(sp) and r14(lr).
*/
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
cmp r1, #PSR_MODE_USR /* User mode? */
bne .Lpabtentersvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
b .Lpabtcontinue
.Lpabtentersvc:
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
* and r2.
*/
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
.Lpabtcontinue:
#else
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
#endif
/* Then call the prefetch abort handler with interrupts disabled.
* void arm_prefetchabort(struct xcptcontext *xcp)
*/
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mrc CP15_IFAR(r1) /* Get R1=IFAR */
mrc CP15_IFSR(r2) /* Get r2=IFSR */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_prefetchabort /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Upon return from arm_prefetchabort, r0 holds the pointer to the register
* state save area to use to restore the registers. This may or may not
* be the same value that was passed to arm_prefetchabort: It will differ if a
* context switch is required.
*/
/* Restore the CPSR, SVC mode registers and return */
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr_cxsf, r1 /* Set the return mode SPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
cmp r2, #PSR_MODE_USR /* User mode? */
bne .Lpabtleavesvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
mov r13, r0 /* (SVC) R13=Register storage area */
ldmia r13, {r0-R12} /* Restore common R0-R12 */
add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */
ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */
add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */
ldmia r14, {r15}^ /* Return */
.Lpabtleavesvc:
#endif
/* Life is simple when everything is SVC mode */
ldmia r0, {r0-r15}^ /* Return */
.Lpaborttmp:
.word g_aborttmp
.size arm_vectorprefetch, . - arm_vectorprefetch
.align 5
/************************************************************************************
* Name: arm_vectorundefinsn
*
* Description:
* Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR,
* lr = SVC PC
*
************************************************************************************/
.globl arm_undefinedinsn
.globl arm_vectorundefinsn
.type arm_vectorundefinsn, %function
arm_vectorundefinsn:
/* On entry we are free to use the UND mode registers
* r13 and r14
*/
ldr r13, .Lundeftmp /* Points to temp storage */
str lr, [r13] /* Save in temp storage */
mrs lr, spsr /* Get SPSR */
str lr, [r13, #4] /* Save in temp storage */
/* Then switch back to SVC mode */
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
msr cpsr_c, lr /* Switch to SVC mode */
/* Create a context structure. First set aside a stack frame
* and store r0-r12 into the frame.
*/
sub sp, sp, #XCPTCONTEXT_SIZE
stmia sp, {r0-r12} /* Save the SVC mode regs */
/* Get the values for r15(pc) and CPSR in r3 and r4 */
ldr r0, .Lundeftmp /* Points to temp storage */
ldmia r0, {r3, r4} /* Recover r3=lr_UND, r4=spsr_UND */
#ifdef CONFIG_BUILD_KERNEL
/* Did we enter from user mode? If so then we need get the values of
* USER mode r13(sp) and r14(lr).
*/
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
cmp r1, #PSR_MODE_USR /* User mode? */
bne .Lundefentersvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
b .Lundefcontinue
.Lundefentersvc:
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
* and r2.
*/
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
.Lundefcontinue:
#else
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
#endif
/* Then call the undef insn handler with interrupts disabled.
* void arm_undefinedinsn(struct xcptcontext *xcp)
*/
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_undefinedinsn /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Upon return from arm_undefinedinsn, r0 holds the pointer to the register
* state save area to use to restore the registers. This may or may not
* be the same value that was passed to arm_undefinedinsn: It will differ if a
* context switch is required.
*/
/* Restore the CPSR, SVC mode registers and return */
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr_cxsf, r1 /* Set the return mode SPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
cmp r2, #PSR_MODE_USR /* User mode? */
bne .Lundefleavesvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
mov r13, r0 /* (SVC) R13=Register storage area */
ldmia r13, {r0-R12} /* Restore common R0-R12 */
add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */
ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */
add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */
ldmia r14, {r15}^ /* Return */
.Lundefleavesvc:
#endif
/* Life is simple when everything is SVC mode */
ldmia r0, {r0-r15}^ /* Return */
.Lundeftmp:
.word g_undeftmp
.size arm_vectorundefinsn, . - arm_vectorundefinsn
.align 5
/************************************************************************************
* Name: arm_vectorfiq
*
* Description:
* Shouldn't happen unless a arm_decodefiq() is provided. FIQ is primarily used
* with the TrustZone feature in order to handle secure interrupts.
*
************************************************************************************/
#ifdef CONFIG_ARMV7R_DECODEFIQ
.globl arm_decodefiq
#endif
.globl arm_vectorfiq
.type arm_vectorfiq, %function
arm_vectorfiq:
#ifdef CONFIG_ARMV7R_DECODEFIQ
/* On entry we are free to use the FIQ mode registers r8 through r14 */
ldr r13, .Lfiqtmp /* Points to temp storage */
sub lr, lr, #4 /* Fixup return */
str lr, [r13] /* Save in temp storage */
mrs lr, spsr /* Get SPSR_fiq */
str lr, [r13, #4] /* Save in temp storage */
/* Then switch back to SVC mode */
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
msr cpsr_c, lr /* Switch to SVC mode */
/* Create a context structure. First set aside a stack frame
* and store r0-r12 into the frame.
*/
sub sp, sp, #XCPTCONTEXT_SIZE
stmia sp, {r0-r12} /* Save the SVC mode regs */
/* Get the values for r15(pc) and CPSR in r3 and r4 */
ldr r0, .Lfiqtmp /* Points to temp storage */
ldmia r0, {r3, r4} /* Recover r3=lr_SVC, r4=spsr_SVC */
#ifdef CONFIG_BUILD_KERNEL
/* Did we enter from user mode? If so then we need get the values of
* USER mode rr13(sp) and r14(lr).
*/
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
cmp r1, #PSR_MODE_USR /* User mode? */
bne .Lfiqentersvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
b .Lfiqcontinue
.Lfiqentersvc:
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
* and r2.
*/
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
.Lfiqcontinue:
#else
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
add r1, sp, #XCPTCONTEXT_SIZE
mov r2, r14
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
stmia r0, {r1-r4}
#endif
/* Then call the IRQ handler with interrupts disabled. */
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
#if CONFIG_ARCH_INTERRUPTSTACK > 3
ldr sp, .Lfiqstackbase /* SP = interrupt stack base */
str r0, [sp] /* Save the user stack pointer */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_decodefiq /* Call the handler */
ldr sp, [r4] /* Restore the user stack pointer */
#else
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignment */
bl arm_decodefiq /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
#endif
/* Upon return from arm_decodefiq, r0 holds the pointer to the register
* state save area to use to restore the registers. This may or may not
* be the same value that was passed to arm_decodefiq: It will differ if a
* context switch is required.
*/
/* Restore the CPSR, SVC mode registers and return */
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr, r1 /* Set the return mode SPSR */
#ifdef CONFIG_BUILD_KERNEL
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
cmp r2, #PSR_MODE_USR /* User mode? */
bne .Lfiqleavesvc /* Branch if not user mode */
/* ldmia with ^ will return the user mode registers (provided that r15
* is not in the register list).
*/
mov r13, r0 /* (SVC) R13=Register storage area */
ldmia r13, {r0-R12} /* Restore common R0-R12 */
add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */
ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */
add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */
ldmia r14, {r15}^ /* Return */
.Lfiqleavesvc:
#endif
/* Life is simple when everything is SVC mode */
ldmia r0, {r0-r15}^ /* Return */
.Lfiqtmp:
.word g_fiqtmp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
.Lfiqstackbase:
.word g_intstackbase
#endif
#else
subs pc, lr, #4
#endif
.size arm_vectorfiq, . - arm_vectorfiq
/************************************************************************************
* Name: g_intstackalloc/g_intstackbase
************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
.bss
.align 4
.globl g_intstackalloc
.type g_intstackalloc, object
.globl g_intstackbase
.type g_intstackbase, object
g_intstackalloc:
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
g_intstackbase:
.skip 4
.size g_intstackbase, 4
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 3 */
.end

View file

@ -0,0 +1,110 @@
/****************************************************************************
* arch/arm/src/arm7-r/arm_vectortab.S
*
* Copyright (C) 2015 Gregory Nutt. 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>
.file "arm_vectortab.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl _vector_start
.globl _vector_end
/****************************************************************************
* Assembly Macros
****************************************************************************/
/****************************************************************************
* Name: _vector_start
*
* Description:
* Vector initialization block
****************************************************************************/
.section .vectors, "ax"
.globl _vector_start
/* These will be relocated to VECTOR_BASE. */
_vector_start:
ldr pc, .Lresethandler /* 0x00: Reset */
ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */
ldr pc, .Lsvchandler /* 0x08: Software interrupt */
ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */
ldr pc, .Ldataaborthandler /* 0x10: Data abort */
ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */
ldr pc, .Lirqhandler /* 0x18: IRQ */
ldr pc, .Lfiqhandler /* 0x1c: FIQ */
.globl __start
.globl arm_vectorundefinsn
.globl arm_vectorsvc
.globl arm_vectorprefetch
.globl arm_vectordata
.globl arm_vectoraddrexcptn
.globl arm_vectorirq
.globl arm_vectorfiq
.Lresethandler:
.long __start
.Lundefinedhandler:
.long arm_vectorundefinsn
.Lsvchandler:
.long arm_vectorsvc
.Lprefetchaborthandler:
.long arm_vectorprefetch
.Ldataaborthandler:
.long arm_vectordata
.Laddrexcptnhandler:
.long arm_vectoraddrexcptn
.Lirqhandler:
.long arm_vectorirq
.Lfiqhandler:
.long arm_vectorfiq
.globl _vector_end
_vector_end:
.size _vector_start, . - _vector_start
.end

View file

@ -0,0 +1,140 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_vfork.S
*
* Copyright (C) 2015 Gregory Nutt. 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 "up_vfork.h"
.file "vfork.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl up_vfork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* any data other than a variable of type pid_t used to store the return
* value from vfork(), or returns from the function in which vfork() was
* called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls task_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls task_vforkstart()
* 6) task_vforkstart() then executes the child thread.
*
* Input Paremeters:
* None
*
* Return:
* Upon successful completion, vfork() returns 0 to the child process and
* returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
.globl vfork
.type vfork, function
vfork:
/* Create a stack frame */
mov r0, sp /* Save the value of the stack on entry */
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
/* CPU registers */
/* Save the volatile registers */
str r4, [sp, #VFORK_R4_OFFSET]
str r5, [sp, #VFORK_R5_OFFSET]
str r6, [sp, #VFORK_R6_OFFSET]
str r7, [sp, #VFORK_R7_OFFSET]
str r8, [sp, #VFORK_R8_OFFSET]
str r9, [sp, #VFORK_R9_OFFSET]
str r10, [sp, #VFORK_R10_OFFSET]
/* Save the frame pointer, stack pointer, and return address */
str fp, [sp, #VFORK_FP_OFFSET]
str r0, [sp, #VFORK_SP_OFFSET]
str lr, [sp, #VFORK_LR_OFFSET]
/* Floating point registers (not yet) */
/* Then, call up_vfork(), passing it a pointer to the stack structure */
mov r0, sp
bl up_vfork
/* Release the stack data and return the value returned by up_vfork */
ldr lr, [sp, #VFORK_LR_OFFSET]
add sp, sp, #VFORK_SIZEOF
mov pc, lr
.size vfork, .-vfork
.end

View file

@ -0,0 +1,207 @@
/************************************************************************************
* arch/arm/src/armv7-r/cache.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_ARMV7_R_CACHE_H
#define __ARCH_ARM_SRC_ARMV7_R_CACHE_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include "cp15_cacheops.h"
#include "l2cc.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/************************************************************************************
* Inline Functions
************************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Name: arch_invalidate_dcache
*
* Description:
* Invalidate the data cache within the specified region; we will be
* performing a DMA operation in this region and we want to purge old data
* in the cache.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
* Assumptions:
* This operation is not atomic. This function assumes that the caller
* has exclusive access to the address range so that no harm is done if
* the operation is pre-empted.
*
****************************************************************************/
static inline void arch_invalidate_dcache(uintptr_t start, uintptr_t end)
{
cp15_invalidate_dcache(start, end);
l2cc_invalidate(start, end);
}
/****************************************************************************
* Name: arch_invalidate_dcache_all
*
* Description:
* Invalidate the entire contents of D cache.
*
* NOTE: This function forces L1 and L2 cache operations to be atomic
* by disabling interrupts.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static inline void arch_invalidate_dcache_all(void)
{
#ifdef CONFIG_ARCH_L2CACHE
irqstate_t flags = irqsave();
cp15_invalidate_dcache_all();
l2cc_invalidate_all();
irqrestore(flags);
#else
cp15_invalidate_dcache_all();
#endif
}
/************************************************************************************
* Name: arch_invalidate_icache
*
* Description:
* Invalidate all instruction caches to PoU, also flushes branch target cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
#define arch_invalidate_icache() cp15_invalidate_icache()
/****************************************************************************
* Name: arch_clean_dcache
*
* Description:
* Clean the data cache within the specified region by flushing the
* contents of the data cache to memory.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
* Assumptions:
* This operation is not atomic. This function assumes that the caller
* has exclusive access to the address range so that no harm is done if
* the operation is pre-empted.
*
****************************************************************************/
static inline void arch_clean_dcache(uintptr_t start, uintptr_t end)
{
cp15_clean_dcache(start, end);
l2cc_clean(start, end);
}
/****************************************************************************
* Name: arch_flush_dcache
*
* Description:
* Flush the data cache within the specified region by cleaning and
* invalidating the D cache.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
* Assumptions:
* This operation is not atomic. This function assumes that the caller
* has exclusive access to the address range so that no harm is done if
* the operation is pre-empted.
*
****************************************************************************/
static inline void arch_flush_dcache(uintptr_t start, uintptr_t end)
{
cp15_flush_dcache(start, end);
l2cc_flush(start, end);
}
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_ARMV7_R_CACHE_H */

169
arch/arm/src/armv7-r/cp15.h Normal file
View file

@ -0,0 +1,169 @@
/************************************************************************************
* arch/arm/src/armv7-r/cp15.h
* CP15 register access
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright
* 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414)
*
* 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_ARMV7_R_CP15_H
#define __ARCH_ARM_SRC_ARMV7_R_CP15_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* System control register descriptions.
*
* CP15 registers are accessed with MRC and MCR instructions as follows:
*
* MRC p15, <Op1>, <Rd>, <CRn>, <CRm>, <Op2> ; Read CP15 Register
* MCR p15, <Op1>, <Rd>, <CRn>, <CRm>, <Op2> ; Write CP15 Register
*
* Where
*
* <Op1> is the Opcode_1 value for the register
* <Rd> is a general purpose register
* <CRn> is the register number within CP15
* <CRm> is the operational register
* <Op2> is the Opcode_2 value for the register.
*
* Reference: Cortex-A5 MPCore, Technical Reference Manual, Paragraph 4.2.
*/
#define _CP15(op1,rd,crn,crm,op2) p15, op1, rd, crn, crm, op2
#define CP15_MIDR(r) _CP15(0, r, c0, c0, 0) /* Main ID Register */
#define CP15_CTR(r) _CP15(0, r, c0, c0, 1) /* Cache Type Register */
#define CP15_TCMTR(r) _CP15(0, r, c0, c0, 2) /* TCM Type Register */
#define CP15_MPUIR(r) _CP15(0, r, c0, c0, 4) /* MPU Type Register */
#define CP15_MPIDR(r) _CP15(0, r, c0, c0, 5) /* Multiprocessor Affinity Register */
#define CP15_REVIDR(r) _CP15(0, r, c0, c0, 6) /* Revision ID register (Cortex-A9) */
#define CP15_MID_PFR0(r) _CP15(0, r, c0, c1, 0) /* Processor Feature Register 0 */
#define CP15_MID_PFR1(r) _CP15(0, r, c0, c1, 1) /* Processor Feature Register 1 */
#define CP15_MID_DFR0(r) _CP15(0, r, c0, c1, 2) /* Debug Feature Register 0 */
#define CP15_MID_AFR0(r) _CP15(0, r, c0, c1, 3) /* Auxiliary Feature Register 0 (Cortex-A9) */
#define CP15_MID_MMFR0(r) _CP15(0, r, c0, c1, 4) /* Memory Model Features Register 0 */
#define CP15_MID_MMFR1(r) _CP15(0, r, c0, c1, 5) /* Memory Model Features Register 1 */
#define CP15_MID_MMFR2(r) _CP15(0, r, c0, c1, 6) /* Memory Model Features Register 2 */
#define CP15_MID_MMFR3(r) _CP15(0, r, c0, c1, 7) /* Memory Model Features Register 3 */
#define CP15_ID_ISAR0(r) _CP15(0, r, c0, c2, 0) /* Instruction Set Attributes Register 0 */
#define CP15_ID_ISAR1(r) _CP15(0, r, c0, c2, 1) /* Instruction Set Attributes Register 1 */
#define CP15_ID_ISAR2(r) _CP15(0, r, c0, c2, 2) /* Instruction Set Attributes Register 2 */
#define CP15_ID_ISAR3(r) _CP15(0, r, c0, c2, 3) /* Instruction Set Attributes Register 3 */
#define CP15_ID_ISAR4(r) _CP15(0, r, c0, c2, 4) /* Instruction Set Attributes Register 4 */
#define CP15_ID_ISAR5(r) _CP15(0, r, c0, c2, 5) /* Instruction Set Attributes Register 5 (Cortex-A5) */
#define CP15_CCSIDR(r) _CP15(1, r, c0, c0, 0) /* Cache Size Identification Register */
#define CP15_CLIDR(r) _CP15(1, r, c0, c0, 1) /* Cache Level ID Register */
#define CP15_AIDR(r) _CP15(1, r, c0, c0, 7) /* Auxiliary ID Register */
#define CP15_CSSELR(r) _CP15(2, r, c0, c0, 0) /* Cache Size Selection Register */
#define CP15_SCTLR(r) _CP15(0, r, c1, c0, 0) /* System Control Register */
#define CP15_ACTLR(r) _CP15(0, r, c1, c0, 1) /* Auxiliary Control Register */
#define CP15_CPACR(r) _CP15(0, r, c1, c0, 2) /* Coprocessor Access Control Register */
#define CP15_DFSR(r) _CP15(0, r, c5, c0, 0) /* Data Fault Status Register */
#define CP15_IFSR(r) _CP15(0, r, c5, c0, 1) /* Instruction Fault Status Register */
#define CP15_ADFSR(r) _CP15(0, r, c5, c1, 0) /* Auxiliary Data Fault Status Register */
#define CP15_AIFSR(r) _CP15(0, r, c5, c1, 1) /* Auxiliary Instruction Fault Status Register */
#define CP15_DFAR(r) _CP15(0, r, c6, c0, 0) /* Data Fault Address Register */
#define CP15_IFAR(r) _CP15(0, r, c6, c0, 2) /* Instruction Fault Address Register */
#define CP15_DRBAR(r) _CP15(0, r, c6, c1, 0) /* Data Region Base Address Register */
#define CP15_DRSR(r) _CP15(0, r, c6, c1, 2) /* Data Region Size and Enable Register */
#define CP15_DRACR(r) _CP15(0, r, c6, c1, 4) /* Data Region Access Control Register */
#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED
# define CP15_IRBAR(r) _CP15(0, r, c6, c1, 1) /* Instruction Region Base Address Register */
# define CP15_IRSR(r) _CP15(0, r, c6, c1, 3) /* Instruction Region Size and Enable Register */
# define CP15_IRACR(r) _CP15(0, r, c6, c1, 5) /* Instruction Region Access Control Register */
#endif
#define CP15_RGNR(r) _CP15(0, r, c6, c2, 0) /* MPU Region Number Register */
#define CP15_ICIALLUIS(r) _CP15(0, r, c7, c1, 0) /* Cache Operations Registers */
#define CP15_BPIALLIS(r) _CP15(0, r, c7, c1, 6)
#define CP15_ICIALLU(r) _CP15(0, r, c7, c5, 0) /* Cache Operations Registers */
#define CP15_ICIMVAU(r) _CP15(0, r, c7, c5, 1)
#define CP15_CP15ISB(r) _CP15(0, r, c7, c5, 4) /* CP15 Instruction Synchronization Barrier operation */
#define CP15_BPIALL(r) _CP15(0, r, c7, c5, 6) /* Cache Operations Registers */
#define CP15_BPIMVA(r) _CP15(0, r, c7, c5, 7) /* Cortex-A5 */
#define CP15_DCIMVAC(r) _CP15(0, r, c7, c6, 1)
#define CP15_DCISW(r) _CP15(0, r, c7, c6, 2)
#define CP15_DCCMVAC(r) _CP15(0, r, c7, c10, 1) /* Data Cache Clean by MVA to PoC */
#define CP15_DCCSW(r) _CP15(0, r, c7, c10, 2) /* Data Cache Clean by Set/Way */
#define CP15_CP15DSB(r) _CP15(0, r, c7, c10, 4) /* CP15 Data Synchronization Barrier operation */
#define CP15_CP15DMB(r) _CP15(0, r, c7, c10, 5) /* CP15 Instruction Synchronization Barrier operation */
#define CP15_DCCMVAU(r) _CP15(0, r, c7, c11, 1) /* Cache Operations Registers */
#define CP15_DCCIMVAC(r) _CP15(0, r, c7, c14, 1)
#define CP15_DCCISW(r) _CP15(0, r, c7, c14, 2)
#define CP15_PMCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */
#define CP15_PMCNTENSET(r) _CP15(0, r, c9, c12, 1) /* Count Enable Set Register */
#define CP15_PMCNTENCLR(r) _CP15(0, r, c9, c12, 2) /* Count Enable Clear Register */
#define CP15_PMOVSR(r) _CP15(0, r, c9, c12, 3) /* Overflow Flag Status Register */
#define CP15_PMSWINC(r) _CP15(0, r, c9, c12, 4) /* Software Increment Register */
#define CP15_PMSELR(r) _CP15(0, r, c9, c12, 5) /* Event Counter Selection Register */
#define CP15_PMCEID0(r) _CP15(0, r, c9, c12, 6) /* Common Event Identification Registers (Cortex-A5) */
#define CP15_PMCEID1(r) _CP15(0, r, c9, c12, 7)
#define CP15_PMCCNTR(r) _CP15(0, r, c9, c13, 0) /* Cycle Count Register */
#define CP15_PMXEVTYPER(r) _CP15(0, r, c9, c13, 1) /* Event Type Select Register */
#define CP15_PMXEVCNTR(r) _CP15(0, r, c9, c13, 2) /* Event Count Registers (Cortex-A5) */
#define CP15_PMUSERENR(r) _CP15(0, r, c9, c14, 0) /* User Enable Register */
#define CP15_PMINTENSET(r) _CP15(0, r, c9, c14, 1) /* Interrupt Enable Set Register */
#define CP15_PMINTENCLR(r) _CP15(0, r, c9, c14, 2) /* Interrupt Enable Clear Register */
#define CP15_CONTEXTIDR(r) _CP15(0, r, c13, c0, 1) /* Context ID Register */
#define CP15_TPIDRURW(r) _CP15(0, r, c13, c0, 2) /* Software Thread ID Registers */
#define CP15_TPIDRURO(r) _CP15(0, r, c13, c0, 3)
#define CP15_TPIDRPRW(r) _CP15(0, r, c13, c0, 4)
#define CP15_CNTFRQ(r) _CP15(0, r, c14, c0, 0) /* Counter Frequency register */
#define CP15_CNTKCTL(r) _CP15(0, r, c14, c1, 0) /* Timer PL1 Control register */
#define CP15_CNTP_TVAL(r) _CP15(0, r, c14, c2, 0) /* PL1 Physical TimerValue register */
#define CP15_CNTP_CTL(r) _CP15(0, r, c14, c2, 0) /* PL1 Physical Timer Control register */
#define CP15_CNTV_TVAL(r) _CP15(0, r, c14, c3, 0) /* Virtual TimerValue register */
#define CP15_CNTV_CTL(r) _CP15(0, r, c14, c3, 0) /* Virtual Timer Control register */
#define CP15_CNTPCT(r,n) _CP15(0, r, c14, c14, n) /* 64-bit Physical Count register */
#define CP15_CNTVCT(r,n) _CP15(1, r, c14, c14, n) /* Virtual Count register */
#define CP15_CNTP_CVAL(r,n) _CP15(2, r, c14, c14, n) /* PL1 Physical Timer CompareValue register */
#define CP15_CNTV_CVAL(r,n) _CP15(3, r, c14, c14, n) /* Virtual Timer CompareValue register */
#endif /* __ARCH_ARM_SRC_ARMV7_R_CP15_H */

View file

@ -0,0 +1,999 @@
/************************************************************************************
* arch/arm/src/armv7-r/cp15_cacheops.h
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright ©
* 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414)
*
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
* which also has a modified BSD-style license:
*
* Copyright (c) 2012, Atmel Corporation
* All rights reserved.
*
* 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 Atmel nor the names of the 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_ARMV7_R_CP15_CACHEOPS_H
#define __ARCH_ARM_SRC_ARMV7_R_CP15_CACHEOPS_H
/************************************************************************************
* Included Files
************************************************************************************/
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Cache definitions ****************************************************************/
/* L1 Memory */
#define CP15_L1_LINESIZE 32
/* CP15 Registers *******************************************************************/
/* Terms:
* 1) Point of coherency (PoC)
* The PoC is the point at which all agents that can access memory are guaranteed
* to see the same copy of a memory location
* 2) Point of unification (PoU)
* The PoU is the point by which the instruction and data caches and the
* translation table walks of the processor are guaranteed to see the same copy
* of a memory location.
*
* Cache Operations:
*
* CP15 Register: ICIALLUIS
* Description: Invalidate entire instruction cache Inner Shareable.
* Register Format: Should be zero (SBZ)
* Instruction: MCR p15, 0, <Rd>, c7, c1, 0
* CP15 Register: BPIALLIS
* Description: Invalidate entire branch predictor array Inner Shareable.
* Register Format: Should be zero (SBZ)
* Instruction: MCR p15, 0, <Rd>, c7, c1, 6
* CP15 Register: ICIALLU
* Description: Invalidate all instruction caches to PoU. Also flushes branch
* target cache.
* Register Format: Should be zero (SBZ)
* Instruction: MCR p15, 0, <Rd>, c7, c5, 0
* CP15 Register: ICIMVAU
* Description: Invalidate instruction cache by VA to PoU.
* Register Format: VA
* Instruction: MCR p15, 0, <Rd>, c7, c5, 1
* CP15 Register: CP15ISB
* Description: Instruction Synchronization Barrier operation
* NOTE: Deprecated and no longer documented
* Instruction: MCR p15, 0, <Rd>, c7, c5, 4
* CP15 Register: BPIALL
* Description: Invalidate entire branch predictor array.
* Register Format: Should be zero (SBZ)
* Instruction: MCR p15, 0, <Rd>, c7, c5, 6
* CP15 Register: BPIMVA
* Description: Invalidate VA from branch predictor array.
* Register Format: Should be zero (SBZ)
* Instruction: MCR p15, 0, <Rd>, c7, c5, 7
* CP15 Register: DCIMVAC
* Description: Invalidate data cache line by VA to PoC.
* Register Format: VA
* Instruction: MCR p15, 0, <Rd>, c7, c6, 1
* CP15 Register: DCISW
* Description: Invalidate data cache line by Set/Way.
* Register Format: Set/Way
* Instruction: MCR p15, 0, <Rd>, c7, c6, 2
* CP15 Register: DCCMVAC
* Description: Clean data cache line to PoC by VA.
* Register Format: VA
* Instruction: MCR p15, 0, <Rd>, c7, c10, 1
* CP15 Register: DCCSW
* Description: Clean data cache line by Set/Way.
* Register Format: Set/Way
* Instruction: MCR p15, 0, <Rd>, c7, c10, 2
* CP15 Register: CP15DSB
* Description: Data Synchronization Barrier operation
* NOTE: Deprecated and no longer documented
* Instruction: MCR p15, 0, <Rd>, c7, c10, 4
* CP15 Register: CP15DMB
* Description: Data Memory Barrier operation
* NOTE: Deprecated and no longer documented
* Instruction: MCR p15, 0, <Rd>, c7, c10, 5
* CP15 Register: DCCMVAU
* Description: Clean data or unified cache line by VA to PoU.
* Register Format: VA
* Instruction: MCR p15, 0, <Rd>, c7, c11, 1
* CP15 Register: DCCIMVAC
* Description: Clean and invalidate data cache line by VA to PoC.
* Register Format: VA
* Instruction: MCR p15, 0, <Rd>, c7, c14, 1
* CP15 Register: DCCISW
* Description: Clean and invalidate data cache line by Set/Way.
* Register Format: Set/Way
* Instruction: MCR p15, 0, <Rd>, c7, c14, 2
*/
/* Set/way format */
#define CACHE_WAY_SHIFT (3) /* Bits 30-31: Way in set being accessed */
#define CACHE_WAY_MASK (3 << CACHE_WAY_SHIFT)
#define CACHE_SET_SHIFT (5) /* Bits 5-(S+4): Way in set being accessed */
/* For 4KB cache size: S=5 */
#define CACHE_SET4KB_MASK (0x1f << CACHE_SET_SHIFT)
/* Bits 10-29: Reserved */
/* For 8KB cache size: S=6 */
#define CACHE_SET8KB_MASK (0x3f << CACHE_SET_SHIFT)
/* Bits 11-29: Reserved */
/* For 16KB cache size: S=7 */
#define CACHE_SET16KB_MASK (0x7f << CACHE_SET_SHIFT)
/* Bits 12-29: Reserved */
/* For 32KB cache size: S=8 */
#define CACHE_SET32KB_MASK (0xff << CACHE_SET_SHIFT)
/* Bits 13-29: Reserved */
/* For 64KB cache size: S=9 */
#define CACHE_SET64KB_MASK (0x1fff << CACHE_SET_SHIFT)
/* Bits 14-29: Reserved */
/* VA and SBZ format */
#define CACHE_SBZ_SHIFT (4) /* Bits 0-4: Should be zero (SBZ) */
#define CACHE_SBZ_MASK (31 << TLB_SBZ_SHIFT)
#define CACHE_VA_MASK (0xfffffffe0) /* Bits 5-31: Virtual address */
/************************************************************************************
* Assemby Macros
************************************************************************************/
/* cp15_cache Cache Operations
*
* Usage
*
* They are performed as MCR instructions and only operate on a level 1 cache
* associated with ARM v7 processor.
*
* The supported operations are:
*
* 1. Any of these operations can be applied to any data cache or any
* unified cache.
* 2. Invalidate by MVA. Performs an invalidate of a data or unified cache
* line
* based on the address it contains.
* 3. Invalidate by set/way. Performs an invalidate of a data or unified
* cache line based on its location in the cache hierarchy.
* 4. Clean by MVA. Performs a clean of a data or unified cache line based
* on the address it contains.
* 5. Clean by set/way. Performs a clean of a data or unified cache line
* based on its location in the cache hierarchy.
* 6. Clean and Invalidate by MVA. Performs a clean and invalidate of a
* data or unified cache line based on the address it contains.
* 7. Clean and Invalidate by set/way. Performs a clean and invalidate of
* a data or unified cache line based on its location in the cache
* hierarchy.
*
* NOTE: Many of these operations are implemented as assembly language
* macros or as C inline functions in the file cache.h. The larger functions
* are implemented here as C-callable functions.
*/
#ifdef __ASSEMBLY__
/************************************************************************************
* Name: cp15_disable_dcache
*
* Description:
* Disable L1 D Cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_disable_dcache, tmp
mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */
bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */
mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */
.endm
/************************************************************************************
* Name: cp15_disable_caches
*
* Description:
* Disable L1 Caches
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_disable_caches, tmp
mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */
bic \tmp, \tmp, #(0x1 << 12) /* Disable I cache */
bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */
mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */
.endm
/************************************************************************************
* Name: cp15_invalidate_icache_inner_sharable
*
* Description:
* Invalidate I cache predictor array inner sharable
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_invalidate_icache_inner_sharable, tmp
mov \tmp, #0
mrc p15, 0, \tmp, c7, c1, 0 /* ICIALLUIS */
.endm
/************************************************************************************
* Name: cp15_invalidate_btb_inner_sharable
*
* Description:
* Invalidate entire branch predictor array inner sharable
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_invalidate_btb_inner_sharable, tmp
mov \tmp, #0
mrc p15, 0, \tmp, c7, c1, 6 /* BPIALLIS */
.endm
/************************************************************************************
* Name: cp15_invalidate_icache
*
* Description:
* Invalidate all instruction caches to PoU, also flushes branch target cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_invalidate_icache, tmp
mov \tmp, #0
mrc p15, 0, \tmp, c7, c5, 0 /* ICIALLU */
.endm
/************************************************************************************
* Name: cp15_invalidate_icache_bymva
*
* Description:
* Invalidate instruction caches by VA to PoU
*
* Input Parameters:
* va - Register with VA format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_invalidate_icache_bymva, va
mrc p15, 0, \va, c7, c5, 1 /* ICIMVAU */
.endm
/************************************************************************************
* Name: cp15_flush_btb
*
* Description:
* Invalidate entire branch predictor array
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_flush_btb, tmp
mov \tmp, #0
mrc p15, 0, \tmp, c7, c5, 6 /* BPIALL */
.endm
/************************************************************************************
* Name: cp15_flush_btb_bymva
*
* Description:
* Invalidate branch predictor array entry by MVA
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_flush_btb_bymva, tmp
mov \tmp, #0
mrc p15, 0, \tmp, c7, c5, 7 /* BPIMVA */
.endm
/************************************************************************************
* Name: cp15_invalidate_dcacheline_bymva
*
* Description:
* Invalidate data cache line by VA to PoC
*
* Input Parameters:
* va - Register with VA format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_invalidate_dcacheline_bymva, va
mrc p15, 0, \va, c7, c6, 1 /* DCIMVAC */
.endm
/************************************************************************************
* Name: cp15_invalidate_dcacheline_bysetway
*
* Description:
* Invalidate data cache line by set/way
*
* Input Parameters:
* setway - Register with Set/Way format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_invalidate_dcacheline_bysetway, setway
mrc p15, 0, \setway, c7, c6, 2 /* DCISW */
.endm
/************************************************************************************
* Name: cp15_clean_dcache_bymva
*
* Description:
* Clean data cache line by MVA
*
* Input Parameters:
* va - Register with VA format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_clean_dcache_bymva, va
mrc p15, 0, \va, c7, c10, 1 /* DCCMVAC */
.endm
/************************************************************************************
* Name: cp15_clean_dcache_bysetway
*
* Description:
* Clean data cache line by Set/way
*
* Input Parameters:
* setway - Register with Set/Way format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_clean_dcache_bysetway, setway
mrc p15, 0, \setway, c7, c10, 2 /* DCCSW */
.endm
/************************************************************************************
* Name: cp15_clean_ucache_bymva
*
* Description:
* Clean unified cache line by MVA
*
* Input Parameters:
* setway - Register with VA format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_clean_ucache_bymva, setway
mrc p15, 0, \setway, c7, c11, 1 /* DCCMVAU */
.endm
/************************************************************************************
* Name: cp15_cleaninvalidate_dcacheline_bymva
*
* Description:
* Clean and invalidate data cache line by VA to PoC
*
* Input Parameters:
* va - Register with VA format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_cleaninvalidate_dcacheline_bymva, va
mrc p15, 0, \va, c7, c14, 1 /* DCCIMVAC */
.endm
/************************************************************************************
* Name: cp15_cleaninvalidate_dcacheline
*
* Description:
* Clean and Incalidate data cache line by Set/Way
*
* Input Parameters:
* setway - Register with Set/Way format
*
* Returned Value:
* None
*
************************************************************************************/
.macro cp15_cleaninvalidate_dcacheline, setway
mrc p15, 0, \setway, c7, c14, 2 /* DCCISW */
.endm
#endif /* __ASSEMBLY__ */
/************************************************************************************
* Inline Functions
************************************************************************************/
#ifndef __ASSEMBLY__
/************************************************************************************
* Name: cp15_disable_dcache
*
* Description:
* Disable L1 Caches
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_disable_dcache(void)
{
__asm__ __volatile__
(
"\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */
"\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */
"\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_disable_caches
*
* Description:
* Disable L1 Caches
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_disable_caches(void)
{
__asm__ __volatile__
(
"\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */
"\tbic r0, r0, #(1 << 12)\n" /* Disable I cache */
"\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */
"\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_invalidate_icache_inner_sharable
*
* Description:
* Invalidate I cache predictor array inner sharable
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_invalidate_icache_inner_sharable(void)
{
__asm__ __volatile__
(
"\tmov r0, #0\n"
"\tmcr p15, 0, r0, c7, c1, 0\n" /* ICIALLUIS */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_invalidate_btb_inner_sharable
*
* Description:
* Invalidate entire branch predictor array inner sharable
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_invalidate_btb_inner_sharable(void)
{
__asm__ __volatile__
(
"\tmov r0, #0\n"
"\tmcr p15, 0, r0, c7, c1, 6\n" /* BPIALLIS */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_invalidate_icache
*
* Description:
* Invalidate all instruction caches to PoU, also flushes branch target cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_invalidate_icache(void)
{
__asm__ __volatile__
(
"\tmov r0, #0\n"
"\tmcr p15, 0, r0, c7, c5, 0\n" /* ICIALLU */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_invalidate_icache_bymva
*
* Description:
* Invalidate instruction caches by VA to PoU
*
* Input Parameters:
* va - 32-bit value with VA format
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_invalidate_icache_bymva(unsigned int va)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c5, 1\n" /* ICIMVAU */
:
: "r" (va)
: "memory"
);
}
/************************************************************************************
* Name: cp15_flush_btb
*
* Description:
* Invalidate entire branch predictor array
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_flush_btb(void)
{
__asm__ __volatile__
(
"\tmov r0, #0\n"
"\tmcr p15, 0, r0, c7, c5, 6\n" /* BPIALL */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_flush_btb_bymva
*
* Description:
* Invalidate branch predictor array entry by MVA
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_flush_btb_bymva(void)
{
__asm__ __volatile__
(
"\tmov r0, #0\n"
"\tmcr p15, 0, r0, c7, c5, 7\n" /* BPIMVA */
:
:
: "r0", "memory"
);
}
/************************************************************************************
* Name: cp15_invalidate_dcacheline_bymva
*
* Description:
* Invalidate data cache line by VA to PoC
*
* Input Parameters:
* va - 32-bit value with VA format
*
* Returned Value:
* None
*
************************************************************************************/
/* Invalidate data cache line by VA to PoC */
static inline void cp15_invalidate_dcacheline_bymva(unsigned int va)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c6, 1\n" /* DCIMVAC */
:
: "r" (va)
: "memory"
);
}
/************************************************************************************
* Name: cp15_invalidate_dcacheline_bysetway
*
* Description:
* Invalidate data cache line by set/way
*
* Input Parameters:
* setway - 32-bit value with Set/Way format
*
* Returned Value:
* None
*
************************************************************************************/
/* Invalidate data cache line by set/way */
static inline void cp15_invalidate_dcacheline_bysetway(unsigned int setway)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c6, 2\n" /* DCISW */
:
: "r" (setway)
: "memory"
);
}
/************************************************************************************
* Name: cp15_clean_dcache_bymva
*
* Description:
* Clean data cache line by MVA
*
* Input Parameters:
* va - 32-bit value with VA format
*
* Returned Value:
* None
*
************************************************************************************/
/* Clean data cache line by MVA */
static inline void cp15_clean_dcache_bymva(unsigned int va)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c10, 1\n" /* DCCMVAC */
:
: "r" (va)
: "memory"
);
}
/************************************************************************************
* Name: cp15_clean_dcache_bysetway
*
* Description:
* Clean data cache line by Set/way
*
* Input Parameters:
* setway - 32-bit value with Set/Way format
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_clean_dcache_bysetway(unsigned int setway)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c10, 2\n" /* DCCSW */
:
: "r" (setway)
: "memory"
);
}
/************************************************************************************
* Name: cp15_clean_ucache_bymva
*
* Description:
* Clean unified cache line by MVA
*
* Input Parameters:
* setway - 32-bit value with VA format
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_clean_ucache_bymva(unsigned int setway)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c11, 1\n" /* DCCMVAU */
:
: "r" (setway)
: "memory"
);
}
/************************************************************************************
* Name: cp15_cleaninvalidate_dcacheline_bymva
*
* Description:
* Clean and invalidate data cache line by VA to PoC
*
* Input Parameters:
* va - 32-bit value with VA format
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_cleaninvalidate_dcacheline_bymva(unsigned int va)
{
__asm__ __volatile__
(
"\tmcr p15, 0, r0, c7, c14, 1\n" /* DCCIMVAC */
:
: "r" (va)
: "memory"
);
}
/************************************************************************************
* Name: cp15_cleaninvalidate_dcacheline
*
* Description:
* Clean and Incalidate data cache line by Set/Way
*
* Input Parameters:
* setway - 32-bit value with Set/Way format
*
* Returned Value:
* None
*
************************************************************************************/
static inline void cp15_cleaninvalidate_dcacheline(unsigned int setway)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c7, c14, 2\n" /* DCCISW */
:
: "r" (setway)
: "memory"
);
}
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: cp15_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
* by cleaning the D cache (i.e., flushing the D cache contents to memory
* and invalidating the I cache). This is typically used when code has been
* written to a memory region, and will be executed.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_coherent_dcache(uintptr_t start, uintptr_t end);
/****************************************************************************
* Name: cp15_invalidate_dcache
*
* Description:
* Invalidate the data cache within the specified region; we will be
* performing a DMA operation in this region and we want to purge old data
* in the cache.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_invalidate_dcache(uintptr_t start, uintptr_t end);
/****************************************************************************
* Name: cp15_invalidate_dcache_all
*
* Description:
* Invalidate the entire contents of D cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_invalidate_dcache_all(void);
/****************************************************************************
* Name: cp15_clean_dcache
*
* Description:
* Clean the data cache within the specified region by flushing the
* contents of the data cache to memory.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_clean_dcache(uintptr_t start, uintptr_t end);
/****************************************************************************
* Name: cp15_flush_dcache
*
* Description:
* Flush the data cache within the specified region by cleaning and
* invalidating the D cache.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_flush_dcache(uintptr_t start, uintptr_t end);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_ARMV7_R_CP15_CACHEOPS_H */

View file

@ -0,0 +1,115 @@
/****************************************************************************
* arch/arm/src/armv7-r/cp15_clean_dcache.S
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
* Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
* "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
* Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
* DDI 0406C.b (ID072512)
*
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
* which also has a modified BSD-style license:
*
* Copyright (c) 2012, Atmel Corporation
* All rights reserved.
*
* 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 Atmel nor the names of the 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 "cp15.h"
.file "cp15_clean_dcache.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl cp15_clean_dcache
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: cp15_clean_dcache
*
* Description:
* Clean the data cache within the specified region by flushing the
* contents of the data cache to memory.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
.globl cp15_clean_dcache
.type cp15_clean_dcache, function
cp15_clean_dcache:
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
sub r3, r2, #1 /* R3=Cache line size mask */
bic r0, r0, r3 /* R0=aligned start address */
/* Loop, cleaning each cache line by writing its contents to memory */
1:
mcr CP15_DCCMVAC(r0) /* Clean data cache line to PoC by VA */
add r0, r0, r2 /* R12=Next cache line */
cmp r0, r1 /* Loop until all cache lines have been cleaned */
blo 1b
dsb
bx lr
.size cp15_clean_dcache, . - cp15_clean_dcache
.end

View file

@ -0,0 +1,137 @@
/****************************************************************************
* arch/arm/src/armv7-r/cp15_coherent_dcache.S
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
* Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
* "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
* Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
* DDI 0406C.b (ID072512)
*
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
* which also has a modified BSD-style license:
*
* Copyright (c) 2012, Atmel Corporation
* All rights reserved.
*
* 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 Atmel nor the names of the 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 "cp15.h"
.file "cp15_coherent_dcache.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl cp15_coherent_dcache
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: cp15_coherent_dcache
*
* Description:
* Ensure that the I and D caches are coherent within specified region
* by cleaning the D cache (i.e., flushing the D cache contents to memory
* and invalidating the I cache. This is typically used when code has been
* written to a memory region, and will be executed.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
.globl cp15_coherent_dcache
.type cp15_coherent_dcache, function
cp15_coherent_dcache:
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
sub r3, r2, #1 /* R3=Cache line size mask */
bic r12, r0, r3 /* R12=aligned start address */
/* Loop, flushing each D cache line to memory */
1:
mcr CP15_DCCMVAU(r12) /* Clean data or unified cache line by VA to PoU */
add r12, r12, r2 /* R12=Next cache line */
cmp r12, r1 /* Loop until all cache lines have been cleaned */
blo 1b
dsb
mrc CP15_CTR(r3) /* Read the Cache Type Register */
and r3, r3, #0xf /* Isolate the IminLine field */
mov r2, #4
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
sub r3, r2, #1 /* R3=Cache line size mask */
bic r12, r0, r3 /* R12=aligned start address */
/* Loop, invalidating each I cache line to memory */
1:
mcr CP15_ICIMVAU(r12) /* Invalidate instruction cache by VA to PoU */
add r12, r12, r2 /* R12=Next cache line */
cmp r12, r1 /* Loop until all cache lines have been invalidated */
blo 1b
mov r0, #0
mcr CP15_BPIALLIS(r0) /* Invalidate entire branch predictor array Inner Shareable */
mcr CP15_BPIALL(r0) /* Invalidate entire branch predictor array Inner Shareable */
dsb
isb
bx lr
.size cp15_coherent_dcache, . - cp15_coherent_dcache
.end

View file

@ -0,0 +1,115 @@
/****************************************************************************
* arch/arm/src/armv7-r/cp15_flush_dcache.S
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
* Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
* "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
* Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
* DDI 0406C.b (ID072512)
*
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
* which also has a modified BSD-style license:
*
* Copyright (c) 2012, Atmel Corporation
* All rights reserved.
*
* 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 Atmel nor the names of the 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 "cp15.h"
.file "cp15_flush_dcache.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl cp15_flush_dcache
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: cp15_flush_dcache
*
* Description:
* Flush the data cache within the specified region by cleaning and
* invalidating the D cache.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
.globl cp15_flush_dcache
.type cp15_flush_dcache, function
cp15_flush_dcache:
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
sub r3, r2, #1 /* R3=Cache line size mask */
bic r0, r0, r3 /* R0=aligned start address */
/* Loop, cleaning and invaliding each D cache line in the address range */
1:
mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */
add r0, r0, r2 /* R12=Next cache line */
cmp r0, r1 /* Loop until all cache lines have been cleaned */
blo 1b
dsb
bx lr
.size cp15_flush_dcache, . - cp15_flush_dcache
.end

View file

@ -0,0 +1,122 @@
/****************************************************************************
* arch/arm/src/armv7-r/cp15_invalidate_dcache.S
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
* Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
* "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
* Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
* DDI 0406C.b (ID072512)
*
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
* which also has a modified BSD-style license:
*
* Copyright (c) 2012, Atmel Corporation
* All rights reserved.
*
* 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 Atmel nor the names of the 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 "cp15.h"
.file "cp15_invalidate_dcache.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl cp15_invalidate_dcache
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: cp15_invalidate_dcache
*
* Description:
* Invalidate the data cache within the specified region; we will be
* performing a DMA operation in this region and we want to purge old data
* in the cache.
*
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
*
* Returned Value:
* None
*
****************************************************************************/
.globl cp15_invalidate_dcache
.type cp15_invalidate_dcache, function
cp15_invalidate_dcache:
mrc CP15_CTR(r3) /* Read the Cache Type Register */
lsr r3, r3, #16 /* Isolate the DMinLine field */
and r3, r3, #0xf
mov r2, #4
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
sub r3, r2, #1 /* R3=Cache line size mask */
tst r0, r3
bic r0, r0, r3 /* R0=aligned start address */
mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */
tst r1, r3
bic r1, r1, r3 /* R0=aligned end address */
mcrne CP15_DCCIMVAC(r1) /* Clean and invalidate data cache line by VA to PoC */
/* Loop, invalidating each D cache line */
1:
mcr CP15_DCIMVAC(r0) /* Invalidate data cache line by VA to PoC */
add r0, r0, r2 /* R12=Next cache line */
cmp r0, r1 /* Loop until all cache lines have been invalidate */
blo 1b
dsb
bx lr
.size cp15_invalidate_dcache, . - cp15_invalidate_dcache
.end

View file

@ -0,0 +1,116 @@
/****************************************************************************
* arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
* Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
* "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
* Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
* DDI 0406C.b (ID072512)
*
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
* which also has a modified BSD-style license:
*
* Copyright (c) 2012, Atmel Corporation
* All rights reserved.
*
* 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 Atmel nor the names of the 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 "cp15.h"
.file "cp15_invalidate_dcache_all.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl cp15_invalidate_dcache_all
/****************************************************************************
* Public Functions
****************************************************************************/
.text
/****************************************************************************
* Name: cp15_invalidate_dcache_all
*
* Description:
* Invalidate the entire contents of D cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
.globl cp15_invalidate_dcache_all
.type cp15_invalidate_dcache_all, function
cp15_invalidate_dcache_all:
mrc CP15_CCSIDR(r0) /* Read the Cache Size Identification Register */
ldr r3, =0xffff /* Isolate the NumSets field (bits 13-27) */
and r0, r3, r0, lsr #13 /* r0=NumSets (number of sets - 1) */
mov r1, #0 /* r1 = way loop counter */
way_loop:
mov r3, #0 /* r3 = set loop counter */
set_loop:
mov r2, r1, lsl #30 /* r2 = way loop counter << 30 */
orr r2, r3, lsl #5 /* r2 = set/way cache operation format */
mcr CP15_DCISW(r2) /* Data Cache Invalidate by Set/Way */
add r3, r3, #1 /* Increment set counter */
cmp r0, r3 /* Last set? */
bne set_loop /* Keep looping if not */
add r1, r1, #1 /* Increment the way counter */
cmp r1, #4 /* Last way? (four ways assumed) */
bne way_loop /* Keep looping if not */
dsb
bx lr
.size cp15_invalidate_dcache_all, . - cp15_invalidate_dcache_all
.end

View file

@ -0,0 +1,93 @@
/****************************************************************************
* arch/arm/src/armv7-r/fpu.h
* Non-CP15 Registers
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_ARMV7_R_FPU_H
#define __ARCH_ARM_SRC_ARMV7_R_FPU_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Inline Functions
****************************************************************************/
#ifndef __ASSEMBLY__
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: arm_fpuconfig
*
* Description:
* Configure the FPU. Enables access to CP10 and CP11
*
****************************************************************************/
#ifdef CONFIG_ARCH_FPU
void arm_fpuconfig(void);
#endif
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_ARMV7_R_FPU_H */

258
arch/arm/src/armv7-r/l2cc.h Normal file
View file

@ -0,0 +1,258 @@
/****************************************************************************
* arch/arm/src/armv7-r/l2cc.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_ARMV7_R_L2CC_H
#define __ARCH_ARM_SRC_ARMV7_R_L2CC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_ARCH_L2CACHE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: up_l2ccinitialize
*
* Description:
* One time configuration of the L2 cache. The L2 cache will be enabled
* upon return.
*
* Input Parameters:
* None. The L2 cache configuration is controlled by configuration
* settings.
*
* Returned Value:
* None
*
****************************************************************************/
#if 0 /* Prototyped in up_internal.h */
void up_l2ccinitialize(void);
#endif
/****************************************************************************
* Name: l2cc_enable
*
* Description:
* Re-enable the L2CC-P310 L2 cache by setting the enable bit in the
* Control Register (CR)
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_enable(void);
/****************************************************************************
* Name: l2cc_disable
*
* Description:
* Disable the L2 cache
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_disable(void);
/****************************************************************************
* Name: l2cc_sync
*
* Description:
* Drain the L2 cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_sync(void);
/****************************************************************************
* Name: l2cc_invalidate_all
*
* Description:
* Invalidate the entire L2 cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_invalidate_all(void);
/****************************************************************************
* Name: l2cc_invalidate
*
* Description:
* Invalidate a range of addresses in the L2 cache
*
* Input Parameters:
* startaddr - The first address to be invalidated
* endaddr - The last address to be invalidated
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_invalidate(uintptr_t startaddr, uintptr_t endaddr);
/****************************************************************************
* Name: l2cc_clean_all
*
* Description:
* Clean the entire L2 cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_clean_all(void);
/****************************************************************************
* Name: l2cc_clean
*
* Description:
* Clean a range of address within the L2 cache.
*
* Input Parameters:
* startaddr - The first address to be cleaned
* endaddr - The last address to be cleaned
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_clean(uintptr_t startaddr, uintptr_t endaddr);
/****************************************************************************
* Name: l2cc_flush_all
*
* Description:
* Flush the entire L2 cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_flush_all(void);
/****************************************************************************
* Name: l2cc_flush
*
* Description:
* Flush a range of address within the L2 cache.
*
* Input Parameters:
* startaddr - The first address to be flushed
* endaddr - The last address to be flushed
*
* Returned Value:
* None
*
****************************************************************************/
void l2cc_flush(uint32_t startaddr, uint32_t endaddr);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#else /* CONFIG_ARCH_L2CACHE */
/* Provide simple definitions to concentrate the inline conditional
* compilation in one place.
*/
# define l2cc_enable()
# define l2cc_disable()
# define l2cc_sync()
# define l2cc_invalidate_all()
# define l2cc_invalidate(s,e)
# define l2cc_clean_all()
# define l2cc_clean(s,e)
# define l2cc_flush_all()
# define l2cc_flush(s,e)
#endif /* CONFIG_ARCH_L2CACHE */
#endif /* __ARCH_ARM_SRC_ARMV7_R_L2CC_H */

View file

@ -0,0 +1,497 @@
/************************************************************************************
* arch/arm/src/armv7-r/chip/l2cc_pl310.h
*
* Register definitions for the L2 Cache Controller (L2CC) is based on the
* L2CC-PL310 ARM multi-way cache macrocell, version r3p2.
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Reference: "CoreLink™ Level 2 Cache Controller L2C-310", Revision r3p2,
* Technical Reference Manual, ARM DDI 0246F (ID011711), ARM
*
* 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_ARMV7_R_L2CC_PL310_H
#define __ARCH_ARM_SRC_ARMV7_R_L2CC_PL310_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
/* The base address of the L2CC implementation must be provided in the chip.h
* header file as L2CC_VBASE.
*/
#include "chip/chip.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* General Definitions **************************************************************/
#define PL310_CACHE_LINE_SIZE 32
#ifdef CONFIG_PL310_LOCKDOWN_BY_MASTER
# define PL310_NLOCKREGS 8
#else
# define PL310_NLOCKREGS 1
#endif
/* L2CC Register Offsets ************************************************************/
#define L2CC_IDR_OFFSET 0x0000 /* Cache ID Register */
#define L2CC_TYPR_OFFSET 0x0004 /* Cache Type Register */
#define L2CC_CR_OFFSET 0x0100 /* Control Register */
#define L2CC_ACR_OFFSET 0x0104 /* Auxiliary Control Register */
#define L2CC_TRCR_OFFSET 0x0108 /* Tag RAM Control Register */
#define L2CC_DRCR_OFFSET 0x010c /* Data RAM Control Register */
/* 0x0110-0x01fc Reserved */
#define L2CC_ECR_OFFSET 0x0200 /* Event Counter Control Register */
#define L2CC_ECFGR1_OFFSET 0x0204 /* Event Counter 1 Configuration Register */
#define L2CC_ECFGR0_OFFSET 0x0208 /* Event Counter 0 Configuration Register */
#define L2CC_EVR1_OFFSET 0x020c /* Event Counter 1 Value Register */
#define L2CC_EVR0_OFFSET 0x0210 /* Event Counter 0 Value Register */
#define L2CC_IMR_OFFSET 0x0214 /* Interrupt Mask Register */
#define L2CC_MISR_OFFSET 0x0218 /* Masked Interrupt Status Register */
#define L2CC_RISR_OFFSET 0x021c /* Raw Interrupt Status Register */
#define L2CC_ICR_OFFSET 0x0220 /* Interrupt Clear Register */
/* 0x0224-0x072c Reserved */
#define L2CC_CSR_OFFSET 0x0730 /* Cache Synchronization Register */
/* 0x0734-0x076c Reserved */
#define L2CC_IPALR_OFFSET 0x0770 /* Invalidate Physical Address Line Register */
/* 0x0774-0x0778 Reserved */
#define L2CC_IWR_OFFSET 0x077c /* Invalidate Way Register */
/* 0x0780-0x07af Reserved */
#define L2CC_CPALR_OFFSET 0x07b0 /* Clean Physical Address Line Register */
/* 0x07b4 Reserved */
#define L2CC_CIR_OFFSET 0x07b8 /* Clean Index Register */
#define L2CC_CWR_OFFSET 0x07bc /* Clean Way Register */
/* 0x07c0-0x07ec Reserved */
#define L2CC_CIPALR_OFFSET 0x07f0 /* Clean Invalidate Physical Address Line Register */
/* 0x07f4 Reserved */
#define L2CC_CIIR_OFFSET 0x07f8 /* Clean Invalidate Index Register */
#define L2CC_CIWR_OFFSET 0x07fc /* Clean Invalidate Way Register */
/* 0x0800-0x08fc Reserved */
/* Data and Instruction Lockdown registers where n=0-7. The registers for n > 0 are
* implemented if the option pl310_LOCKDOWN_BY_MASTER is enabled. Otherwise, they are
* unused
*/
#define L2CC_DLKR_OFFSET(n) (0x0900 + ((n) << 3)) /* Data Lockdown Register */
#define L2CC_ILKR_OFFSET(n) (0x0904 + ((n) << 3)) /* Instruction Lockdown Register */
/* 0x0940-0x0f4c Reserved */
#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE
# define L2CC_LKLN_OFFSET 0x0950 /* Lock Line Enable Register */
# define L2CC_UNLKW_OFFSET 0x0954 /* Unlock Way Register */
#endif
/* 0x0958-0x0bfc Reserved */
#define L2CC_FLSTRT_OFFSET 0x0c00 /* Address filter start */
#define L2CC_FLEND_OFFSET 0x0c04 /* Address filter end */
/* 0x0c08-0x0f3c Reserved */
#define L2CC_DCR_OFFSET 0x0f40 /* Debug Control Register */
/* 0x0f44-0x0f5c Reserved */
#define L2CC_PCR_OFFSET 0x0f60 /* Prefetch Control Register */
/* 0x0f64-0x0f7c Reserved */
#define L2CC_POWCR_OFFSET 0x0f80 /* Power Control Register */
/* L2CC Register Addresses **********************************************************/
#define L2CC_IDR (L2CC_VBASE+L2CC_IDR_OFFSET)
#define L2CC_TYPR (L2CC_VBASE+L2CC_TYPR_OFFSET)
#define L2CC_CR (L2CC_VBASE+L2CC_CR_OFFSET)
#define L2CC_ACR (L2CC_VBASE+L2CC_ACR_OFFSET)
#define L2CC_TRCR (L2CC_VBASE+L2CC_TRCR_OFFSET)
#define L2CC_DRCR (L2CC_VBASE+L2CC_DRCR_OFFSET)
#define L2CC_ECR (L2CC_VBASE+L2CC_ECR_OFFSET)
#define L2CC_ECFGR1 (L2CC_VBASE+L2CC_ECFGR1_OFFSET)
#define L2CC_ECFGR0 (L2CC_VBASE+L2CC_ECFGR0_OFFSET)
#define L2CC_EVR1 (L2CC_VBASE+L2CC_EVR1_OFFSET)
#define L2CC_EVR0 (L2CC_VBASE+L2CC_EVR0_OFFSET)
#define L2CC_IMR (L2CC_VBASE+L2CC_IMR_OFFSET)
#define L2CC_MISR (L2CC_VBASE+L2CC_MISR_OFFSET)
#define L2CC_RISR (L2CC_VBASE+L2CC_RISR_OFFSET)
#define L2CC_ICR (L2CC_VBASE+L2CC_ICR_OFFSET)
#define L2CC_CSR (L2CC_VBASE+L2CC_CSR_OFFSET)
#define L2CC_IPALR (L2CC_VBASE+L2CC_IPALR_OFFSET)
#define L2CC_IWR (L2CC_VBASE+L2CC_IWR_OFFSET)
#define L2CC_CPALR (L2CC_VBASE+L2CC_CPALR_OFFSET)
#define L2CC_CIR (L2CC_VBASE+L2CC_CIR_OFFSET)
#define L2CC_CWR (L2CC_VBASE+L2CC_CWR_OFFSET)
#define L2CC_CIPALR (L2CC_VBASE+L2CC_CIPALR_OFFSET)
#define L2CC_CIIR (L2CC_VBASE+L2CC_CIIR_OFFSET)
#define L2CC_CIWR (L2CC_VBASE+L2CC_CIWR_OFFSET)
#define L2CC_DLKR(n) (L2CC_VBASE+L2CC_DLKR_OFFSET(n))
#define L2CC_ILKR(n) (L2CC_VBASE+L2CC_ILKR_OFFSET(n))
#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE
# define L2CC_LKLN (L2CC_VBASE+L2CC_LKLN_OFFSET)
# define L2CC_UNLKW (L2CC_VBASE+L2CC_UNLKW_OFFSET)
#endif
#define L2CC_FLSTRT (L2CC_VBASE+L2CC_FLSTRT_OFFSET)
#define L2CC_FLEND (L2CC_VBASE+L2CC_FLEND_OFFSET)
#define L2CC_DCR (L2CC_VBASE+L2CC_DCR_OFFSET)
#define L2CC_PCR (L2CC_VBASE+L2CC_PCR_OFFSET)
#define L2CC_POWCR (L2CC_VBASE+L2CC_POWCR_OFFSET)
/* L2CC Register Bit Definitions ****************************************************/
/* Cache ID Register (32-bit ID) */
#define L2CC_IDR_REV_MASK 0x0000003f
# define L2CC_IDR_REV_R0P0 0x00000000
# define L2CC_IDR_REV_R1P0 0x00000002
# define L2CC_IDR_REV_R2P0 0x00000004
# define L2CC_IDR_REV_R3P0 0x00000005
# define L2CC_IDR_REV_R3P1 0x00000006
# define L2CC_IDR_REV_R3P2 0x00000008
/* Cache Type Register */
#define L2CC_TYPR_IL2ASS (1 << 6) /* Bit 6: Instruction L2 Cache Associativity */
#define L2CC_TYPR_IL2WSIZE_SHIFT (8) /* Bits 8-10: Instruction L2 Cache Way Size */
#define L2CC_TYPR_IL2WSIZE_MASK (7 << L2CC_TYPR_IL2WSIZE_SHIFT)
# define L2CC_TYPR_IL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_IL2WSIZE_SHIFT)
#define L2CC_TYPR_DL2ASS (1 << 18) /* Bit 18: Data L2 Cache Associativity */
#define L2CC_TYPR_DL2WSIZE_SHIFT (20) /* Bits 20-22: Data L2 Cache Way Size */
#define L2CC_TYPR_DL2WSIZE_MASK (7 << L2CC_TYPR_DL2WSIZE_SHIFT)
# define L2CC_TYPR_DL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_DL2WSIZE_SHIFT)
/* Control Register */
#define L2CC_CR_L2CEN (1 << 0) /* Bit 0: L2 Cache Enable */
/* Auxiliary Control Register */
#define L2CC_ACR_FLZE (1 << 0) /* Bit 0: Full line zero enable */
#define L2CC_ACR_HPSO (1 << 10) /* Bit 10: High Priority for SO and Dev Reads Enable */
#define L2CC_ACR_SBDLE (1 << 11) /* Bit 11: Store Buffer Device Limitation Enable */
#define L2CC_ACR_EXCC (1 << 12) /* Bit 12: Exclusive Cache Configuration */
#define L2CC_ACR_SAIE (1 << 13) /* Bit 13: Shared Attribute Invalidate Enable */
#define L2CC_ACR_ASS (1 << 16) /* Bit 16: Associativity */
#define L2CC_ACR_WAYSIZE_SHIFT (17) /* Bits 17-19: Way Size */
#define L2CC_ACR_WAYSIZE_MASK (7 << L2CC_ACR_WAYSIZE_SHIFT)
# define L2CC_ACR_WAYSIZE_16KB (1 << L2CC_ACR_WAYSIZE_SHIFT)
# define L2CC_ACR_WAYSIZE_32KB (2 << L2CC_ACR_WAYSIZE_SHIFT)
# define L2CC_ACR_WAYSIZE_64KB (3 << L2CC_ACR_WAYSIZE_SHIFT)
# define L2CC_ACR_WAYSIZE_128KB (4 << L2CC_ACR_WAYSIZE_SHIFT)
# define L2CC_ACR_WAYSIZE_256KB (5 << L2CC_ACR_WAYSIZE_SHIFT)
# define L2CC_ACR_WAYSIZE_512KB (6 << L2CC_ACR_WAYSIZE_SHIFT)
#define L2CC_ACR_EMBEN (1 << 20) /* Bit 20: Event Monitor Bus Enable */
#define L2CC_ACR_PEN (1 << 21) /* Bit 21: Parity Enable */
#define L2CC_ACR_SAOEN (1 << 22) /* Bit 22: Shared Attribute Override Enable */
#define L2CC_ACR_FWA_SHIFT (23) /* Bits 23-24: Force Write Allocate */
#define L2CC_ACR_FWA_MASK (3 << L2CC_ACR_FWA_SHIFT)
# define L2CC_ACR_FWA_AWCACHE (0 << L2CC_ACR_FWA_SHIFT) /* Use AWCACHE attributes for WA */
# define L2CC_ACR_FWA_NOALLOC (1 << L2CC_ACR_FWA_SHIFT) /* No allocate */
# define L2CC_ACR_FWA_OVERRIDE (2 << L2CC_ACR_FWA_SHIFT) /* Override AWCACHE attributes */
# define L2CC_ACR_FWA_MAPPED (3 << L2CC_ACR_FWA_SHIFT) /* Internally mapped to 00 */
#define L2CC_ACR_CRPOL (1 << 25) /* Bit 25: Cache Replacement Policy */
#define L2CC_ACR_NSLEN (1 << 26) /* Bit 26: Non-Secure Lockdown Enable */
#define L2CC_ACR_NSIAC (1 << 27) /* Bit 27: Non-Secure Interrupt Access Control */
#define L2CC_ACR_DPEN (1 << 28) /* Bit 28: Data Prefetch Enable */
#define L2CC_ACR_IPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */
#define L2CC_ACR_EBRESP (1 << 30) /* Bit 30: Early BRESP enable */
#define L2CC_ACR_SBZ (0x8000c1fe)
/* Tag RAM Control Register */
#define L2CC_TRCR_TSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */
#define L2CC_TRCR_TSETLAT_MASK (7 << L2CC_TRCR_TSETLAT_SHIFT)
# define L2CC_TRCR_TSETLAT(n) ((uint32_t)(n) << L2CC_TRCR_TSETLAT_SHIFT)
#define L2CC_TRCR_TRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */
#define L2CC_TRCR_TRDLAT_MASK (7 << L2CC_TRCR_TRDLAT_SHIFT)
# define L2CC_TRCR_TRDLAT(n) ((uint32_t)(n) << L2CC_TRCR_TRDLAT_SHIFT)
#define L2CC_TRCR_TWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */
#define L2CC_TRCR_TWRLAT_MASK (7 << L2CC_TRCR_TWRLAT_SHIFT)
# define L2CC_TRCR_TWRLAT(n) ((uint32_t)(n) << L2CC_TRCR_TWRLAT_SHIFT)
/* Data RAM Control Register */
#define L2CC_DRCR_DSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */
#define L2CC_DRCR_DSETLAT_MASK (7 << L2CC_DRCR_DSETLAT_SHIFT)
# define L2CC_DRCR_DSETLAT(n) ((uint32_t)(n) << L2CC_DRCR_DSETLAT_SHIFT)
#define L2CC_DRCR_DRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */
#define L2CC_DRCR_DRDLAT_MASK (7 << L2CC_DRCR_DRDLAT_SHIFT)
# define L2CC_DRCR_DRDLAT(n) ((uint32_t)(n) << L2CC_DRCR_DRDLAT_SHIFT)
#define L2CC_DRCR_DWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */
#define L2CC_DRCR_DWRLAT_MASK (7 << L2CC_DRCR_DWRLAT_SHIFT)
# define L2CC_DRCR_DWRLAT(n) ((uint32_t)(n) << L2CC_DRCR_DWRLAT_SHIFT)
/* Event Counter Control Register */
#define L2CC_ECR_EVCEN (1 << 0) /* Bit 0: Event Counter Enable */
#define L2CC_ECR_EVC0RST (1 << 1) /* Bit 1: Event Counter 0 Reset */
#define L2CC_ECR_EVC1RST (1 << 2) /* Bit 2: Event Counter 1 Reset */
/* Event Counter 1 Configuration Register */
#define L2CC_ECFGR1_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */
#define L2CC_ECFGR1_EIGEN_MASK (3 << L2CC_ECFGR1_EIGEN_SHIFT)
# define L2CC_ECFGR1_EIGEN_INTDIS (0 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables (default) */
# define L2CC_ECFGR1_EIGEN_INTENINCR (1 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Increment condition */
# define L2CC_ECFGR1_EIGEN_INTENOVER (2 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Overflow condition */
# define L2CC_ECFGR1_EIGEN_INTGENDIS (3 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables Interrupt generation */
#define L2CC_ECFGR1_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */
#define L2CC_ECFGR1_ESRC_MASK (15 << L2CC_ECFGR1_ESRC_SHIFT)
# define L2CC_ECFGR1_ESRC_CNTDIS (0 << L2CC_ECFGR1_ESRC_SHIFT) /* Counter Disabled */
# define L2CC_ECFGR1_ESRC_CO (1 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is CO */
# define L2CC_ECFGR1_ESRC_DRHIT (2 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRHIT */
# define L2CC_ECFGR1_ESRC_DRREQ (3 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRREQ */
# define L2CC_ECFGR1_ESRC_DWHIT (4 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWHIT */
# define L2CC_ECFGR1_ESRC_DWREQ (5 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWREQ */
# define L2CC_ECFGR1_ESRC_DWTREQ (6 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWTREQ */
# define L2CC_ECFGR1_ESRC_IRHIT (7 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRHIT */
# define L2CC_ECFGR1_ESRC_IRREQ (8 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRREQ */
# define L2CC_ECFGR1_ESRC_WA (9 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is WA */
# define L2CC_ECFGR1_ESRC_IPFALLOC (10 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IPFALLOC */
# define L2CC_ECFGR1_ESRC_EPFHIT (11 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFHIT */
# define L2CC_ECFGR1_ESRC_EPFALLOC (12 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFALLOC */
# define L2CC_ECFGR1_ESRC_SRRCVD (13 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRRCVD */
# define L2CC_ECFGR1_ESRC_SRCONF (14 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRCONF */
# define L2CC_ECFGR1_ESRC_EPFRCVD (15 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFRCVD */
/* Event Counter 0 Configuration Register */
#define L2CC_ECFGR0_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */
#define L2CC_ECFGR0_EIGEN_MASK (3 << L2CC_ECFGR0_EIGEN_SHIFT)
# define L2CC_ECFGR0_EIGEN_INTDIS (0 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables (default) */
# define L2CC_ECFGR0_EIGEN_INTENINCR (1 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Increment condition */
# define L2CC_ECFGR0_EIGEN_INTENOVER (2 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Overflow condition */
# define L2CC_ECFGR0_EIGEN_INTGENDIS (3 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables Interrupt generation */
#define L2CC_ECFGR0_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */
#define L2CC_ECFGR0_ESRC_MASK (15 << L2CC_ECFGR0_ESRC_SHIFT)
# define L2CC_ECFGR0_ESRC_CNTDIS (0 << L2CC_ECFGR0_ESRC_SHIFT) /* Counter Disabled */
# define L2CC_ECFGR0_ESRC_CO (1 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is CO */
# define L2CC_ECFGR0_ESRC_DRHIT (2 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRHIT */
# define L2CC_ECFGR0_ESRC_DRREQ (3 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRREQ */
# define L2CC_ECFGR0_ESRC_DWHIT (4 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWHIT */
# define L2CC_ECFGR0_ESRC_DWREQ (5 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWREQ */
# define L2CC_ECFGR0_ESRC_DWTREQ (6 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWTREQ */
# define L2CC_ECFGR0_ESRC_IRHIT (7 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRHIT */
# define L2CC_ECFGR0_ESRC_IRREQ (8 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRREQ */
# define L2CC_ECFGR0_ESRC_WA (9 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is WA */
# define L2CC_ECFGR0_ESRC_IPFALLOC (10 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IPFALLOC */
# define L2CC_ECFGR0_ESRC_EPFHIT (11 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFHIT */
# define L2CC_ECFGR0_ESRC_EPFALLOC (12 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFALLOC */
# define L2CC_ECFGR0_ESRC_SRRCVD (13 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRRCVD */
# define L2CC_ECFGR0_ESRC_SRCONF (14 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRCONF */
# define L2CC_ECFGR0_ESRC_EPFRCVD (15 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFRCVD */
/* Event Counter 1 Value Register (32-bit value) */
/* Event Counter 0 Value Register (32-bit value) */
/* Interrupt Mask Register, Masked Interrupt Status Register, Raw Interrupt Status
* Register, and Interrupt Clear Register.
*/
#define L2CC_INT_ECNTR (1 << 0) /* Bit 0: Event Counter 1/0 Overflow Increment */
#define L2CC_INT_PARRT (1 << 1) /* Bit 1: Parity Error on L2 Tag RAM, Read */
#define L2CC_INT_PARRD (1 << 2) /* Bit 2: Parity Error on L2 Data RAM, Read */
#define L2CC_INT_ERRWT (1 << 3) /* Bit 3: Error on L2 Tag RAM, Write */
#define L2CC_INT_ERRWD (1 << 4) /* Bit 4: Error on L2 Data RAM, Write */
#define L2CC_INT_ERRRT (1 << 5) /* Bit 5: Error on L2 Tag RAM, Read */
#define L2CC_INT_ERRRD (1 << 6) /* Bit 6: Error on L2 Data RAM, Read */
#define L2CC_INT_SLVERR (1 << 7) /* Bit 7: SLVERR from L3 Memory */
#define L2CC_INT_DECERR (1 << 8) /* Bit 8: DECERR from L3 Memory */
/* Cache Synchronization Register */
#define L2CC_CSR_C (1 << 0) /* Bit 0: Cache Synchronization Status */
/* Invalidate Physical Address Line Register */
#define L2CC_IPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */
#define L2CC_IPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */
#define L2CC_IPALR_IDX_MASK (0x1ff << L2CC_IPALR_IDX_SHIFT)
# define L2CC_IPALR_IDX(n) ((uint32_t)(n) << L2CC_IPALR_IDX_SHIFT)
#define L2CC_IPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */
#define L2CC_IPALR_TAG_MASK (0x3ffff << L2CC_IPALR_TAG_SHIFT)
# define L2CC_IPALR_TAG(n) ((uint32_t)(n) << L2CC_IPALR_TAG_SHIFT)
/* Invalidate Way Register */
#define L2CC_IWR_WAY(n) (1 << (n)) /* Bist 0-7: Invalidate Way Number n, n=0..7 */
# define L2CC_IWR_WAY0 (1 << 0) /* Bit 0: Invalidate Way Number 0 */
# define L2CC_IWR_WAY1 (1 << 1) /* Bit 1: Invalidate Way Number 1 */
# define L2CC_IWR_WAY2 (1 << 2) /* Bit 2: Invalidate Way Number 2 */
# define L2CC_IWR_WAY3 (1 << 3) /* Bit 3: Invalidate Way Number 3 */
# define L2CC_IWR_WAY4 (1 << 4) /* Bit 4: Invalidate Way Number 4 */
# define L2CC_IWR_WAY5 (1 << 5) /* Bit 5: Invalidate Way Number 5 */
# define L2CC_IWR_WAY6 (1 << 6) /* Bit 6: Invalidate Way Number 6 */
# define L2CC_IWR_WAY7 (1 << 7) /* Bit 7: Invalidate Way Number 7 */
/* Clean Physical Address Line Register */
#define L2CC_CPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */
#define L2CC_CPALR_IDX_SHIFT (5) /* Bits 5-13: Index number */
#define L2CC_CPALR_IDX_MASK (0x1ff << L2CC_CPALR_IDX_SHIFT)
# define L2CC_CPALR_IDX(n) ((uint32_t)(n) << L2CC_CPALR_IDX_SHIFT)
#define L2CC_CPALR_TAG_SHIFT (14) /* Bits 14-31: Tag number */
#define L2CC_CPALR_TAG_MASK (0x3ffff << L2CC_CPALR_TAG_SHIFT)
# define L2CC_CPALR_TAG(n) ((uint32_t)(n) << L2CC_CPALR_TAG_SHIFT)
/* Clean Index Register */
#define L2CC_CIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */
#define L2CC_CIR_IDX_SHIFT (5) /* Bits 5-13: Index number */
#define L2CC_CIR_IDX_MASK (0x1ff << L2CC_CIR_IDX_SHIFT)
# define L2CC_CIR_IDX(n) ((uint32_t)(n) << L2CC_CIR_IDX_SHIFT)
#define L2CC_CIR_WAY_SHIFT (28) /* Bits 28-30: Way number */
#define L2CC_CIR_WAY_MASK (7 << L2CC_CIR_WAY_SHIFT)
# define L2CC_CIR_WAY(n) ((uint32_t)(n) << L2CC_CIR_WAY_SHIFT)
/* Clean Way Register */
#define L2CC_CWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Way Number n, n=0..7 */
# define L2CC_CWR_WAY0 (1 << 0) /* Bit 0: Clean Way Number 0 */
# define L2CC_CWR_WAY1 (1 << 1) /* Bit 1: Clean Way Number 1 */
# define L2CC_CWR_WAY2 (1 << 2) /* Bit 2: Clean Way Number 2 */
# define L2CC_CWR_WAY3 (1 << 3) /* Bit 3: Clean Way Number 3 */
# define L2CC_CWR_WAY4 (1 << 4) /* Bit 4: Clean Way Number 4 */
# define L2CC_CWR_WAY5 (1 << 5) /* Bit 5: Clean Way Number 5 */
# define L2CC_CWR_WAY6 (1 << 6) /* Bit 6: Clean Way Number 6 */
# define L2CC_CWR_WAY7 (1 << 7) /* Bit 7: Clean Way Number 7 */
/* Clean Invalidate Physical Address Line Register */
#define L2CC_CIPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */
#define L2CC_CIPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */
#define L2CC_CIPALR_IDX_MASK (0x1ff << L2CC_CIPALR_IDX_SHIFT)
# define L2CC_CIPALR_IDX(n) ((uint32_t)(n) << L2CC_CIPALR_IDX_SHIFT)
#define L2CC_CIPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */
#define L2CC_CIPALR_TAG_MASK (0x3ffff << L2CC_CIPALR_TAG_SHIFT)
# define L2CC_CIPALR_TAG(n) ((uint32_t)(n) << L2CC_CIPALR_TAG_SHIFT)
/* Clean Invalidate Index Register */
#define L2CC_CIIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */
#define L2CC_CIIR_IDX_SHIFT (5) /* Bits 5-13: Index Number */
#define L2CC_CIIR_IDX_MASK (0x1ff << L2CC_CIIR_IDX_SHIFT)
# define L2CC_CIIR_IDX(n) ((uint32_t)(n) << L2CC_CIIR_IDX_SHIFT)
#define L2CC_CIIR_WAY_SHIFT (28) /* Bits 28-30: Way Number */
#define L2CC_CIIR_WAY_MASK (7 << L2CC_CIIR_WAY_SHIFT)
# define L2CC_CIIR_WAY(n) ((uint32_t)(n) << L2CC_CIIR_WAY_SHIFT)
/* Clean Invalidate Way Register */
#define L2CC_CIWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Invalidate Way Number n, n=1..7 */
# define L2CC_CIWR_WAY0 (1 << 0) /* Bit 0: Clean Invalidate Way Number 0 */
# define L2CC_CIWR_WAY1 (1 << 1) /* Bit 1: Clean Invalidate Way Number 1 */
# define L2CC_CIWR_WAY2 (1 << 2) /* Bit 2: Clean Invalidate Way Number 2 */
# define L2CC_CIWR_WAY3 (1 << 3) /* Bit 3: Clean Invalidate Way Number 3 */
# define L2CC_CIWR_WAY4 (1 << 4) /* Bit 4: Clean Invalidate Way Number 4 */
# define L2CC_CIWR_WAY5 (1 << 5) /* Bit 5: Clean Invalidate Way Number 5 */
# define L2CC_CIWR_WAY6 (1 << 6) /* Bit 6: Clean Invalidate Way Number 6 */
# define L2CC_CIWR_WAY7 (1 << 7) /* Bit 7: Clean Invalidate Way Number 7 */
/* Data Lockdown Register */
#define L2CC_DLKR_DLK(n) (1 << (n)) /* Bits 0-7: Data Lockdown in Way Number n, n=0..7 */
# define L2CC_DLKR_DLK0 (1 << 0) /* Bit 0: Data Lockdown in Way Number 0 */
# define L2CC_DLKR_DLK1 (1 << 1) /* Bit 1: Data Lockdown in Way Number 1 */
# define L2CC_DLKR_DLK2 (1 << 2) /* Bit 2: Data Lockdown in Way Number 2 */
# define L2CC_DLKR_DLK3 (1 << 3) /* Bit 3: Data Lockdown in Way Number 3 */
# define L2CC_DLKR_DLK4 (1 << 4) /* Bit 4: Data Lockdown in Way Number 4 */
# define L2CC_DLKR_DLK5 (1 << 5) /* Bit 5: Data Lockdown in Way Number 5 */
# define L2CC_DLKR_DLK6 (1 << 6) /* Bit 6: Data Lockdown in Way Number 6 */
# define L2CC_DLKR_DLK7 (1 << 7) /* Bit 7: Data Lockdown in Way Number 7 */
/* Instruction Lockdown Register */
#define L2CC_ILKR_ILK(n) (1 << (n)) /* Bits 0-7: Instruction Lockdown in Way Number n, n=0..7 */
# define L2CC_ILKR_ILK0 (1 << 0) /* Bit 0: Instruction Lockdown in Way Number 0 */
# define L2CC_ILKR_ILK1 (1 << 1) /* Bit 1: Instruction Lockdown in Way Number 1 */
# define L2CC_ILKR_ILK2 (1 << 2) /* Bit 2: Instruction Lockdown in Way Number 2 */
# define L2CC_ILKR_ILK3 (1 << 3) /* Bit 3: Instruction Lockdown in Way Number 3 */
# define L2CC_ILKR_ILK4 (1 << 4) /* Bit 4: Instruction Lockdown in Way Number 4 */
# define L2CC_ILKR_ILK5 (1 << 5) /* Bit 5: Instruction Lockdown in Way Number 5 */
# define L2CC_ILKR_ILK6 (1 << 6) /* Bit 6: Instruction Lockdown in Way Number 6 */
# define L2CC_ILKR_ILK7 (1 << 7) /* Bit 7: Instruction Lockdown in Way Number 7 */
/* Lock Line Enable Register */
#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE
# define L2CC_LKLN_ENABLE (1 << 0) /* Bit 0: Lockdown by line enable */
#endif
/* Unlock Way Register */
#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE
# define L2CC_UNLKW_WAY_SHIFT (0) /* Bits 0-15: Unlock line for corresponding way */
# define L2CC_UNLKW_WAY_MASK (0xffff << L2CC_UNLKW_WAY_SHIFT)
# define L2CC_UNLKW_WAY_SET(n) ((uint32_t)(n) << L2CC_UNLKW_WAY_SHIFT)
# define L2CC_UNLKW_WAY_BIT(n) ((1 << (n)) << L2CC_UNLKW_WAY_SHIFT)
#endif
/* Address filter start */
#ifdef PL310_ADDRESS_FILTERING
# define L2CC_FLSTRT_ENABLE (1 << 0) /* Bit 0: Address filter enable */
# define L2CC_FLSTRT_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */
#endif
/* Address filter end */
#ifdef PL310_ADDRESS_FILTERING
# define L2CC_FLEND_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */
#endif
/* Debug Control Register */
#define L2CC_DCR_DCL (1 << 0) /* Bit 0: Disable Cache Linefill */
#define L2CC_DCR_DWB (1 << 1) /* Bit 1: Disable Write-back, Force Write-through */
#define L2CC_DCR_SPNIDEN (1 << 2) /* Bit 2: SPNIDEN Value */
/* Prefetch Control Register */
#define L2CC_PCR_SHIFT (0) /* Bits 0-4: Prefetch Offset */
#define L2CC_PCR_MASK (31 << L2CC_PCR_SHIFT)
# define L2CC_PCR_PREFETCH(n) ((uint32_t)(n) << L2CC_PCR_SHIFT)
#define L2CC_PCR_NSIDEN (1 << 21) /* Bit 21: Not Same ID on Exclusive Sequence Enable */
#define L2CC_PCR_IDLEN (1 << 23) /* Bit 23: INCR Double Linefill Enable */
#define L2CC_PCR_PDEN (1 << 24) /* Bit 24: Prefetch Drop Enable */
#define L2CC_PCR_DLFWRDIS (1 << 27) /* Bit 27: Double Linefill on WRAP Read Disable */
#define L2CC_PCR_DATPEN (1 << 28) /* Bit 28: Data Prefetch Enable */
#define L2CC_PCR_INSPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */
#define L2CC_PCR_DLEN (1 << 30) /* Bit 30: Double Linefill Enable */
/* Power Control Register */
#define L2CC_POWCR_STBYEN (1 << 0) /* Bit 0: Standby Mode Enable */
#define L2CC_POWCR_DCKGATEN (1 << 1) /* Bit 1: Dynamic Clock Gating Enable */
#endif /* __ARCH_ARM_SRC_ARMV7_R_L2CC_PL310_H */

740
arch/arm/src/armv7-r/mpu.h Normal file
View file

@ -0,0 +1,740 @@
/************************************************************************************
* arch/arm/src/armv7-r/mpu.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_ARMV7R_MPU_H
#define __ARCH_ARM_SRC_ARMV7R_MPU_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <sys/types.h>
# include <stdint.h>
# include <stdbool.h>
# include <debug.h>
# include "up_arch.h"
# include "cp15.h"
#endif
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* MPU Type Register Bit Definitions */
#define MPUIR_SEPARATE (1 << 0) /* Bit 0: 0:unified or 1:separate memory maps */
#define MPUIR_DREGION_SHIFT (8) /* Bits 8-15: Number MPU data regions */
#define MPUIR_DREGION_MASK (0xff << MPUIR_DREGION_SHIFT)
#define MPUIR_IREGION_SHIFT (16) /* Bits 16-23: Number MPU instruction regions */
#define MPUIR_IREGION_MASK (0xff << MPUIR_IREGION_SHIFT)
/* Region Base Address Register Definitions */
#define MPU_RBAR_MASK 0xfffffffc
/* Region Size and Enable Register */
#define MPU_RASR_ENABLE (1 << 0) /* Bit 0: Region enable */
#define MPU_RASR_RSIZE_SHIFT (1) /* Bits 1-5: Size of the MPU protection region */
#define MPU_RASR_RSIZE_MASK (31 << MPU_RASR_RSIZE_SHIFT)
# define MPU_RASR_RSIZE_LOG2(n) ((n-1) << MPU_RASR_RSIZE_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)
/* Region Access Control Register */
#define MPU_RACR_B (1 << 0) /* Bit 0: Bufferable */
#define MPU_RACR_C (1 << 1) /* Bit 1: Cacheable */
#define MPU_RACR_S (1 << 2) /* Bit 2: Shareable */
#define MPU_RACR_TEX_SHIFT (8) /* Bits 0-2: Memory attributes (with C and B) */
#define MPU_RACR_TEX_MASK (7 << MPU_RACR_TEX_SHIFT)
# define MPU_RACR_TEX(n) ((uint32_t)(n) << MPU_RACR_TEX_SHIFT)
#define MPU_RACR_AP_SHIFT (8) /* Bits 8-10: Access permission */
#define MPU_RACR_AP_MASK (7 << MPU_RACR_AP_SHIFT)
# define MPU_RACR_AP_NONO (0 << MPU_RACR_AP_SHIFT) /* PL0:None PL1:None */
# define MPU_RACR_AP_RWNO (1 << MPU_RACR_AP_SHIFT) /* PL0:RW PL1:None */
# define MPU_RACR_AP_RWRO (2 << MPU_RACR_AP_SHIFT) /* PL0:RW PL1:RO */
# define MPU_RACR_AP_RWRW (3 << MPU_RACR_AP_SHIFT) /* PL0:RW PL1:RW */
# define MPU_RACR_AP_RONO (5 << MPU_RACR_AP_SHIFT) /* PL0:RO PL1:None */
# define MPU_RACR_AP_RORO (6 << MPU_RACR_AP_SHIFT) /* PL0:RO PL1:RO */
#define MPU_RACR_XN (1 << 12) /* Bit 12: Instruction access disable */
/* MPU Region Number Register */
#ifdef CONFIG_ARM_MPU_NREGIONS <= 8
# define MPU_RGNR_MASK (0x00000007)
#elif CONFIG_ARM_MPU_NREGIONS <= 16
# define MPU_RGNR_MASK (0x0000000f)
#elif CONFIG_ARM_MPU_NREGIONS <= 32
# define MPU_RGNR_MASK (0x0000001f)
#else
# error "FIXME: Unsupported number of MPU regions"
#endif
/************************************************************************************
* 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);
/************************************************************************************
* Inline Functions
************************************************************************************/
/****************************************************************************
* Name: mpu_get_mpuir
*
* Description:
* Read the MPUIR register the characteristics of the MPU
*
****************************************************************************/
static inline unsigned int mpu_get_mpuir(void)
{
unsigned int mpuir;
__asm__ __volatile__
(
"\tmrc " CP15_MPUIR(%0)
: "=r" (mpuir)
:
: "memory"
);
return mpuir;
}
/****************************************************************************
* Name: mpu_set_drbar
*
* Description:
* Wrtie to the DRBAR register
*
****************************************************************************/
static inline void mpu_set_drbar(unsigned int drbar)
{
__asm__ __volatile__
(
"\tmcr " CP15_DRBAR(%0)
:
: "r" (drbar)
: "memory"
);
}
/****************************************************************************
* Name: mpu_set_drsr
*
* Description:
* Wrtie to the DRSR register
*
****************************************************************************/
static inline void mpu_set_drsr(unsigned int drsr)
{
__asm__ __volatile__
(
"\tmcr " CP15_DRSR(%0)
:
: "r" (drsr)
: "memory"
);
}
/****************************************************************************
* Name: mpu_set_dracr
*
* Description:
* Wrtie to the DRACR register
*
****************************************************************************/
static inline void mpu_set_dracr(unsigned int dracr)
{
__asm__ __volatile__
(
"\tmcr " CP15_DRACR(%0)
:
: "r" (dracr)
: "memory"
);
}
/****************************************************************************
* Name: mpu_set_irbar
*
* Description:
* Wrtie to the IRBAR register
*
****************************************************************************/
#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED
static inline void mpu_set_irbar(unsigned int irbar)
{
__asm__ __volatile__
(
"\tmcr " CP15_IRBAR(%0)
:
: "r" (irbar)
: "memory"
);
}
#endif
/****************************************************************************
* Name: mpu_set_irsr
*
* Description:
* Wrtie to the IRSR register
*
****************************************************************************/
#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED
static inline void mpu_set_irsr(unsigned int irsr)
{
__asm__ __volatile__
(
"\tmcr " CP15_IRSR(%0)
:
: "r" (irsr)
: "memory"
);
}
#endif
/****************************************************************************
* Name: mpu_set_iracr
*
* Description:
* Wrtie to the IRCR register
*
****************************************************************************/
#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED
static inline void mpu_set_iracr(unsigned int iracr)
{
__asm__ __volatile__
(
"\tmcr " CP15_IRACR(%0)
:
: "r" (iracr)
: "memory"
);
}
#endif
/****************************************************************************
* Name: mpu_set_rgnr
*
* Description:
* Wrtie to the IRCR register
*
****************************************************************************/
static inline void mpu_set_rgnr(unsigned int rgnr)
{
__asm__ __volatile__
(
"\tmcr " CP15_RGNR(%0)
:
: "r" (rgnr)
: "memory"
);
}
/****************************************************************************
* Name: mpu_showtype
*
* Description:
* Show the characteristics of the MPU
*
****************************************************************************/
static inline void mpu_showtype(void)
{
#ifdef CONFIG_DEBUG
uint32_t regval = mpu_get_mpuir();
dbg("%s MPU Regions: data=%d instr=%d\n",
(regval & MPUIR_SEPARATE) != 0 ? "Separate" : "Unified",
(regval & MPUIR_DREGION_MASK) >> MPUIR_DREGION_SHIFT,
(regval & MPUIR_IREGION_MASK) >> MPUIR_IREGION_SHIFT);
#endif
}
/****************************************************************************
* Name: mpu_control
*
* Description:
* Enable (or disable) the MPU
*
****************************************************************************/
static inline void mpu_control(bool enable)
{
uint32_t regval;
/* Set/clear the following bits in the SCTLR:
*
* SCTLR_M Bit 0: MPU enable bit
* SCTLR_BR Bit 17: Background Region bit (not cleared)
*/
regval = cp15_rdsctlr();
if (enable)
{
regval |= (SCTLR_M | SCTLR_BR);
cp15_wrsctlr(regval);
}
else
{
regval &= ~SCTLR_M;
}
cp15_wrsctlr(regval);
}
/****************************************************************************
* Name: mpu_priv_stronglyordered
*
* Description:
* Configure a region for privileged, strongly ordered memory
*
****************************************************************************/
#if defined(CONFIG_ARMV7M_HAVE_ICACHE) || defined(CONFIG_ARMV7M_DCACHE)
static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = /* Not Cacheable */
/* Not Bufferable */
MPU_RACR_S | /* Shareable */
MPU_RACR_AP_RWNO; /* P:RW U:None */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
#endif
/****************************************************************************
* Name: mpu_user_flash
*
* Description:
* Configure a region for user program flash
*
****************************************************************************/
static inline void mpu_user_flash(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = /* Not Cacheable */
MPU_RACR_C | /* Cacheable */
MPU_RACR_AP_RORO; /* P:RO U:RO */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
/****************************************************************************
* Name: mpu_priv_flash
*
* Description:
* Configure a region for privileged program flash
*
****************************************************************************/
static inline void mpu_priv_flash(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = MPU_RACR_C | /* Cacheable */
MPU_RACR_AP_RONO; /* P:RO U:None */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
/****************************************************************************
* Name: mpu_user_intsram
*
* Description:
* Configure a region as user internal SRAM
*
****************************************************************************/
static inline void mpu_user_intsram(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = MPU_RACR_S | /* Shareable */
MPU_RACR_C | /* Cacheable */
MPU_RACR_AP_RWRW; /* P:RW U:RW */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
/****************************************************************************
* Name: mpu_priv_intsram
*
* Description:
* Configure a region as privileged internal SRAM
*
****************************************************************************/
static inline void mpu_priv_intsram(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = MPU_RACR_S | /* Shareable */
MPU_RACR_C | /* Cacheable */
MPU_RACR_AP_RWNO; /* P:RW U:None */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
/****************************************************************************
* Name: mpu_user_extsram
*
* Description:
* Configure a region as user external SRAM
*
****************************************************************************/
static inline void mpu_user_extsram(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = MPU_RACR_S | /* Shareable */
MPU_RACR_C | /* Cacheable */
MPU_RACR_B | /* Bufferable */
MPU_RACR_AP_RWRW; /* P:RW U:RW */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
/****************************************************************************
* Name: mpu_priv_extsram
*
* Description:
* Configure a region as privileged external SRAM
*
****************************************************************************/
static inline void mpu_priv_extsram(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */
regval = MPU_RACR_S | /* Shareable */
MPU_RACR_C | /* Cacheable */
MPU_RACR_B | /* Bufferable */
MPU_RACR_AP_RWNO; /* P:RW U:None */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
/****************************************************************************
* Name: mpu_peripheral
*
* Description:
* Configure a region as privileged periperal address space
*
****************************************************************************/
static inline void mpu_peripheral(uintptr_t base, size_t size)
{
unsigned int region = mpu_allocregion();
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
/* Select the region */
mpu_set_rgnr(region);
/* Select the region base address */
mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region);
/* Select the region size and the sub-region map */
l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* Then configure the region */
regval = MPU_RACR_S | /* Shareable */
MPU_RACR_B | /* Bufferable */
MPU_RACR_AP_RWNO | /* P:RW U:None */
MPU_RACR_XN; /* Instruction access disable */
mpu_set_dracr(regval);
regval = MPU_RASR_ENABLE | /* Enable region */
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
mpu_set_drsr(regval);
}
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_ARMV7R_MPU_H */

View file

@ -0,0 +1,545 @@
/************************************************************************************
* arch/arm/src/armv7-r/sctlr.h
* CP15 System Control Registers
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References:
*
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright
* 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414)
*
* 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_ARMV7_R_SCTLR_H
#define __ARCH_ARM_SRC_ARMV7_R_SCTLR_H
/************************************************************************************
* Included Files
************************************************************************************/
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* CP15 c0 Registers ****************************************************************/
/* Main ID Register (MIDR): CRn=c0, opc1=0, CRm=c0, opc2=0
* TODO: To be provided
*/
/* Cache Type Register (CTR): CRn=c0, opc1=0, CRm=c0, opc2=1
* TODO: To be provided
*/
/* TCM Type Register (TCMTR): CRn=c0, opc1=0, CRm=c0, opc2=2
* Details implementation defined.
*/
/* Aliases of Main ID register (MIDR): CRn=c0, opc1=0, CRm=c0, opc2=3,7
* TODO: To be provided
*/
/* MPU Type Register (MPUIR): CRn=c0, opc1=0, CRm=c0, opc2=4
* TODO: To be provided
*/
/* Multiprocessor Affinity Register (MPIDR): CRn=c0, opc1=0, CRm=c0, opc2=5
* TODO: To be provided
*/
/* Revision ID Register (REVIDR): CRn=c0, opc1=0, CRm=c0, opc2=6
* TODO: To be provided
*/
/* Processor Feature Register 0 (ID_PFR0): CRn=c0, opc1=0, CRm=c1, opc2=0
* Processor Feature Register 1 (ID_PFR1): CRn=c0, opc1=0, CRm=c1, opc2=1
* TODO: To be provided
*/
/* Debug Feature Register 0 (ID_DFR0): CRn=c0, opc1=0, CRm=c1, opc2=2
* TODO: To be provided
*/
/* Auxiliary Feature Register 0 (ID_AFR0): CRn=c0, opc1=0, CRm=c1, opc2=3
* TODO: To be provided
*/
/* Memory Model Features Register 0 (ID_MMFR0): CRn=c0, opc1=0, CRm=c1, opc2=4
* Memory Model Features Register 1 (ID_MMFR1): CRn=c0, opc1=0, CRm=c1, opc2=5
* Memory Model Features Register 2 (ID_MMFR2): CRn=c0, opc1=0, CRm=c1, opc2=6
* Memory Model Features Register 3 (ID_MMFR3): CRn=c0, opc1=0, CRm=c1, opc2=7
* TODO: To be provided
*/
/* Instruction Set Attributes Register 0 (ID_ISAR0): CRn=c0, opc1=0, CRm=c2, opc2=0
* Instruction Set Attributes Register 1 (ID_ISAR1): CRn=c0, opc1=0, CRm=c2, opc2=1
* Instruction Set Attributes Register 2 (ID_ISAR2): CRn=c0, opc1=0, CRm=c2, opc2=2
* Instruction Set Attributes Register 3 (ID_ISAR3): CRn=c0, opc1=0, CRm=c2, opc2=3
* Instruction Set Attributes Register 4 (ID_ISAR4): CRn=c0, opc1=0, CRm=c2, opc2=4
* Instruction Set Attributes Register 5 (ID_ISAR5): CRn=c0, opc1=0, CRm=c2, opc2=5
* Instruction Set Attributes Register 6-7 (ID_ISAR6-7). Reserved.
* TODO: Others to be provided
*/
/* Reserved: CRn=c0, opc1=0, CRm=c3-c7, opc2=* */
/* Cache Size Identification Register (CCSIDR): CRn=c0, opc1=1, CRm=c0, opc2=0
* TODO: To be provided
*/
/* Cache Level ID Register (CLIDR): CRn=c0, opc1=1, CRm=c0, opc2=1
* TODO: To be provided
*/
/* Auxiliary ID Register (AIDR): CRn=c0, opc1=1, CRm=c0, opc2=7
* TODO: To be provided
*/
/* Cache Size Selection Register (CSSELR): CRn=c0, opc1=2, CRm=c0, opc2=0
* TODO: To be provided
*/
/* CP15 c1 Registers ****************************************************************/
/* System Control Register (SCTLR): CRn=c1, opc1=0, CRm=c0, opc2=0
*/
#define SCTLR_M (1 << 0) /* Bit 0: MPU enable bit */
#define SCTLR_A (1 << 1) /* Bit 1: Enables strict alignment of data */
#define SCTLR_C (1 << 2) /* Bit 2: Determines if data can be cached */
/* Bits 3-4: Reserved */
#define SCTLR_CCP15BEN (1 << 5) /* Bit 5: CP15 barrier enable */
/* Bit 6: Reserved */
#define SCTLR_B (1 << 7) /* Bit 7: Should be zero on ARMv7-R */
/* Bits 8-9: Reserved */
#define SCTLR_SW (1 << 10) /* Bit 10: SWP/SWPB Enable bit */
#define SCTLR_Z (1 << 11) /* Bit 11: Program flow prediction control */
#define SCTLR_I (1 << 12) /* Bit 12: Determines if instructions can be cached */
#define SCTLR_V (1 << 13) /* Bit 13: Vectors bit */
#define SCTLR_RR (1 << 14) /* Bit 14: Cache replacement strategy */
/* Bits 15-16: Reserved */
#define SCTLR_BR (1 << 17) /* Bit 17: Background Region bit */
/* Bit 18: Reserved */
#define SCTLR_DZ (1 << 19) /* Bit 19: Divide by Zero fault enable bit */
/* Bit 20: Reserved */
#define SCTLR_FI (1 << 21) /* Bit 21: Fast interrupts configuration enable bit */
#define SCTLR_U (1 << 22) /* Bit 22: Unaligned access model (always one) */
#define SCTLR_VE (1 << 24) /* Bit 24: Interrupt Vectors Enable bit */
#define SCTLR_EE (1 << 25) /* Bit 25: Determines the value the CPSR.E */
#define SCTLR_NMFI (1 << 27) /* Bit 27: Non-maskable FIQ (NMFI) support */
/* Bits 28-29: Reserved */
#define SCTLR_TE (1 << 30) /* Bit 30: Thumb exception enable */
#define SCTLR_IE (1 << 31) /* Bit 31: Instruction endian-ness */
/* Auxiliary Control Register (ACTLR): CRn=c1, opc1=0, CRm=c0, opc2=1
* Implementation defined
*/
/* Coprocessor Access Control Register (CPACR): CRn=c1, opc1=0, CRm=c0, opc2=2
* TODO: To be provided
*/
/* CP15 c2-c4 Registers *************************************************************/
/* Not used on ARMv7-R */
/* CP15 c5 Registers ****************************************************************/
/* Data Fault Status Register (DFSR): CRn=c5, opc1=0, CRm=c0, opc2=0
* TODO: To be provided
*/
/* Instruction Fault Status Register (IFSR): CRn=c5, opc1=0, CRm=c0, opc2=1
* TODO: To be provided
*/
/* Auxiliary DFSR (ADFSR): CRn=c5, opc1=0, CRm=c1, opc2=0
* TODO: To be provided
*/
/* Auxiliary IFSR (AIFSR): CRn=c5, opc1=0, CRm=c1, opc2=1
* TODO: To be provided
*/
/* CP15 c6 Registers ****************************************************************/
/* Data Fault Address Register(DFAR): CRn=c6, opc1=0, CRm=c0, opc2=0
*
* Holds the MVA of the faulting address when a synchronous fault occurs
*/
/* Instruction Fault Address Register(IFAR): CRn=c6, opc1=0, CRm=c0, opc2=1
*
* Holds the MVA of the faulting address of the instruction that caused a prefetch
* abort.
*/
/* Data Region Base Address Register (DRBAR): CRn=c6, opc1=0, CRm=c1, opc2=0
* TODO: To be provided
*/
/* Instruction Region Base Address Register (IRBAR): CRn=c6, opc1=0, CRm=c1, opc2=1
* TODO: To be provided
*/
/* Data Region Size and Enable Register (DRSR): CRn=c6, opc1=0, CRm=c1, opc2=2
* TODO: To be provided
*/
/* Instruction Region Size and Enable Register (IRSR): CRn=c6, opc1=0, CRm=c1, opc2=3
* TODO: To be provided
*/
/* Data Region Access Control Register (DRACR): CRn=c6, opc1=0, CRm=c1, opc2=4
* TODO: To be provided
*/
/* Instruction Region Access Control Register (IRACR): CRn=c6, opc1=0, CRm=c1, opc2=5
* TODO: To be provided
*/
/* MPU Region Number Register (RGNR): CRn=c6, opc1=0, CRm=c2, opc2=0
* TODO: To be provided
*/
/* CP15 c7 Registers ****************************************************************/
/* See cp15_cacheops.h */
/* CP15 c8 Registers ****************************************************************/
/* Not used on ARMv7-R */
/* CP15 c9 Registers ****************************************************************/
/* 32-bit Performance Monitors Control Register (PMCR): CRn=c9, opc1=0, CRm=c12, opc2=0
* TODO: To be provided
*/
#define PCMR_E (1 << 0) /* Enable all counters */
#define PCMR_P (1 << 1) /* Reset all counter eventts (except PMCCNTR) */
#define PCMR_C (1 << 2) /* Reset cycle counter (PMCCNTR) to zero */
#define PCMR_D (1 << 3) /* Enable cycle counter clock (PMCCNTR) divider */
#define PCMR_X (1 << 4) /* Export of events is enabled */
#define PCMR_DP (1 << 5) /* Disable PMCCNTR if event counting is prohibited */
#define PCMR_N_SHIFT (11) /* Bits 11-15: Number of event counters */
#define PCMR_N_MASK (0x1f << PCMR_N_SHIFT)
#define PCMR_IDCODE_SHIFT (16) /* Bits 16-23: Identification code */
#define PCMR_IDCODE_MASK (0xff << PCMR_IDCODE_SHIFT)
#define PCMR_IMP_SHIFT (24) /* Bits 24-31: Implementer code */
#define PCMR_IMP_MASK (0xff << PCMR_IMP_SHIFT)
/* 32-bit Performance Monitors Count Enable Set register (PMCNTENSET): CRn=c9, opc1=0, CRm=c12, opc2=1
* TODO: To be provided
*/
/* 32-bit Performance Monitors Count Enable Clear register (PMCNTENCLR): CRn=c9, opc1=0, CRm=c12, opc2=2
* TODO: To be provided
*/
/* 32-bit Performance Monitors Overflow Flag Status Register (PMOVSR): CRn=c9, opc1=0, CRm=c12, opc2=3
* TODO: To be provided
*/
/* 32-bit Performance Monitors Software Increment register (PMSWINC): CRn=c9, opc1=0, CRm=c12, opc2=4
* TODO: To be provided
*/
/* 32-bit Performance Monitors Event Counter Selection Register (PMSELR): CRn=c9, opc1=0, CRm=c12, opc2=5
* TODO: To be provided
*/
/* 32-bit Performance Monitors Common Event Identification (PMCEID0): CRn=c9, opc1=0, CRm=c12, opc2=6
* TODO: To be provided
*/
/* 32-bit Performance Monitors Common Event Identification (PMCEID1): CRn=c9, opc1=0, CRm=c12, opc2=7
* TODO: To be provided
*/
/* 32-bit Performance Monitors Cycle Count Register (PMCCNTR): CRn=c9, opc1=0, CRm=c13, opc2=0
* TODO: To be provided
*/
/* 32-bit Performance Monitors Event Type Select Register (PMXEVTYPER): CRn=c9, opc1=0, CRm=c13, opc2=1
* TODO: To be provided
*/
/* 32-bit Performance Monitors Event Count Register (PMXEVCNTR): CRn=c9, opc1=0, CRm=c13, opc2=2
* TODO: To be provided
*/
/* 32-bit Performance Monitors User Enable Register (PMUSERENR): CRn=c9, opc1=0, CRm=c14, opc2=0
* TODO: To be provided
*/
/* 32-bit Performance Monitors Interrupt Enable Set register (PMINTENSET): CRn=c9, opc1=0, CRm=c14, opc2=1
* TODO: To be provided
*/
/* 32-bit Performance Monitors Interrupt Enable Clear register (PMINTENCLR): CRn=c9, opc1=0, CRm=c14, opc2=2
* TODO: To be provided
*/
/* CP15 c10 Registers ***************************************************************/
/* Not used on ARMv7-R */
/* CP15 c11 Registers ***************************************************************/
/* Reserved for implementation defined DMA functions */
/* CP15 c12 Registers ***************************************************************/
/* Not used on ARMv7-R */
/* CP15 c13 Registers ***************************************************************/
/* Context ID Register (CONTEXTIDR): CRn=c13, opc1=0, CRm=c0, opc2=1
* 32-Bit ContextID value.
*/
/* User Read/Write (TPIDRURW): CRn=c13, opc1=0, CRm=c0, opc2=2
* TODO: To be provided
*/
/* User Read Only (TPIDRURO): CRn=c13, opc1=0, CRm=c0, opc2=3
* TODO: To be provided
*/
/* PL1 only (TPIDRPRW): CRn=c13, opc1=0, CRm=c0, opc2=4
* TODO: To be provided
*/
/* CP15 c14 Registers ***************************************************************/
/* Counter Frequency register (CNTFRQ): CRn=c14, opc1=0, CRm=c0, opc2=0
* TODO: To be provided
*/
/* Timer PL1 Control register (CNTKCTL): CRn=c14, opc1=0, CRm=c1, opc2=0
* TODO: To be provided
*/
/* PL1 Physical TimerValue register (CNTP_TVAL): CRn=c14, opc1=0, CRm=c2, opc2=0
* TODO: To be provided
*/
/* PL1 Physical Timer Control register (CNTP_CTL): CRn=c14, opc1=0, CRm=c2, opc2=0
* TODO: To be provided
*/
/* Virtual TimerValue register (CNTV_TVAL): CRn=c14, opc1=0, CRm=c3, opc2=0
* TODO: To be provided
*/
/* Virtual Timer Control register (CNTV_CTL): CRn=c14, opc1=0, CRm=c3, opc2=0
* TODO: To be provided
*/
/* 64-bit Physical Count register (CNTPCT): CRn=c14, opc1=0, CRm=c14, opc2=n
* TODO: To be provided
*/
/* Virtual Count register (CNTVCT): CRn=c14, opc1=1, CRm=c14, opc2=n
* TODO: To be provided
*/
/* PL1 Physical Timer CompareValue register (CNTP_CVAL): CRn=c14, opc1=2, CRm=c14, opc2=n
* TODO: To be provided
*/
/* Virtual Timer CompareValue register (CNTV_CVAL): CRn=c14, opc1=3, CRm=c14, opc2=n
* TODO: To be provided
*/
/* CP15 c15 Registers ***************************************************************/
/* Implementation defined */
/************************************************************************************
* Assemby Macros
************************************************************************************/
#ifdef __ASSEMBLY__
/* Get the device ID */
.macro cp15_rdid, id
mrc p15, 0, \id, c0, c0, 0
.endm
/* Read/write the system control register (SCTLR) */
.macro cp15_rdsctlr, sctlr
mrc p15, 0, \sctlr, c1, c0, 0
.endm
.macro cp15_wrsctlr, sctlr
mcr p15, 0, \sctlr, c1, c0, 0
nop
nop
nop
nop
nop
nop
nop
nop
.endm
#endif /* __ASSEMBLY__ */
/************************************************************************************
* Inline Functions
************************************************************************************/
#ifndef __ASSEMBLY__
/* Get the device ID */
static inline unsigned int cp15_rdid(void)
{
unsigned int id;
__asm__ __volatile__
(
"\tmrc p15, 0, %0, c0, c0, 0"
: "=r" (id)
:
: "memory"
);
return id;
}
/* Read/write the system control register (SCTLR) */
static inline unsigned int cp15_rdsctlr(void)
{
unsigned int sctlr;
__asm__ __volatile__
(
"\tmrc p15, 0, %0, c1, c0, 0\n"
: "=r" (sctlr)
:
: "memory"
);
return sctlr;
}
static inline void cp15_wrsctlr(unsigned int sctlr)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c1, c0, 0\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
:
: "r" (sctlr)
: "memory"
);
}
/* Read/write the implementation defined Auxiliary Control Regster (ACTLR) */
static inline unsigned int cp15_rdactlr(void)
{
unsigned int actlr;
__asm__ __volatile__
(
"\tmrc p15, 0, %0, c1, c0, 1\n"
: "=r" (actlr)
:
: "memory"
);
return actlr;
}
static inline void cp15_wractlr(unsigned int actlr)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c1, c0, 1\n"
:
: "r" (actlr)
: "memory"
);
}
/* Read/write the Performance Monitor Control Register (PMCR) */
static inline unsigned int cp15_rdpmcr(void)
{
unsigned int pmcr;
__asm__ __volatile__
(
"\tmrc p15, 0, %0, c9, c12, 0\n"
: "=r" (pmcr)
:
: "memory"
);
return pmcr;
}
static inline void cp15_wrpmcr(unsigned int pmcr)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c9, c12, 0\n"
:
: "r" (pmcr)
: "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 /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_ARMV7_R_SCTLR_H */

View file

@ -0,0 +1,130 @@
/************************************************************************************
* arch/arm/src/armv7-r/svcall.h
*
* Copyright (C) 2015 Gregory Nutt. 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.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_ARMV7_R_SVCALL_H
#define __ARCH_ARM_SRC_ARMV7_R_SVCALL_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_LIB_SYSCALL
# include <syscall.h>
#endif
#ifdef CONFIG_LIB_SYSCALL
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Configuration ********************************************************************/
/* This logic uses one system call for the syscall return. So a minimum of one
* syscall values must be reserved. If CONFIG_BUILD_KERNEL is defined, then four
* more syscall values must be reserved.
*/
#ifdef CONFIG_BUILD_KERNEL
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 6"
# elif CONFIG_SYS_RESERVED != 6
# error "CONFIG_SYS_RESERVED must have the value 6"
# endif
#else
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 1"
# elif CONFIG_SYS_RESERVED != 1
# error "CONFIG_SYS_RESERVED must have the value 1"
# endif
#endif
/* Cortex-R system calls ************************************************************/
/* SYS call 0:
*
* void up_syscall_return(void);
*/
#define SYS_syscall_return (0)
#ifdef CONFIG_BUILD_KERNEL
/* SYS call 1:
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*/
#define SYS_context_restore (1)
/* SYS call 2:
*
* void up_task_start(main_t taskentry, int argc, FAR char *argv[])
* noreturn_function;
*/
#define SYS_task_start (2)
/* SYS call 3:
*
* void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
* noreturn_function
*/
#define SYS_pthread_start (3)
/* SYS call 4:
*
* void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info,
* FAR void *ucontext);
*/
#define SYS_signal_handler (4)
/* SYS call 5:
*
* void signal_handler_return(void);
*/
#define SYS_signal_handler_return (5)
#endif /* CONFIG_BUILD_KERNEL */
/************************************************************************************
* Inline Functions
************************************************************************************/
#endif /* CONFIG_LIB_SYSCALL */
#endif /* __ARCH_ARM_SRC_ARMV7_R_SVCALL_H */

View file

@ -47,6 +47,8 @@ CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -50,6 +50,8 @@ CMN_CSRCS += up_undefinedinsn.c up_usestack.c calypso_power.c up_vfork.c
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -48,6 +48,8 @@ CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -81,6 +81,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_ARCH_FPU),y)

View file

@ -439,7 +439,7 @@ void up_irqinitialize(void)
* Fault handler.
*/
#ifdef CONFIG_ARMV7M_MPU
#ifdef CONFIG_ARM_MPU
irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
up_enable_irq(EFM32_IRQ_MEMFAULT);
#endif
@ -448,7 +448,7 @@ void up_irqinitialize(void)
#ifdef CONFIG_DEBUG
irq_attach(EFM32_IRQ_NMI, efm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
#ifndef CONFIG_ARM_MPU
irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
#endif
irq_attach(EFM32_IRQ_BUSFAULT, efm32_busfault);

View file

@ -47,6 +47,8 @@ CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -79,6 +79,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
# Required Kinetis files

View file

@ -411,7 +411,7 @@ void up_irqinitialize(void)
* Fault handler.
*/
#ifdef CONFIG_ARMV7M_MPU
#ifdef CONFIG_ARM_MPU
irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
up_enable_irq(KINETIS_IRQ_MEMFAULT);
#endif
@ -420,7 +420,7 @@ void up_irqinitialize(void)
#ifdef CONFIG_DEBUG
irq_attach(KINETIS_IRQ_NMI, kinetis_nmi);
#ifndef CONFIG_ARMV7M_MPU
#ifndef CONFIG_ARM_MPU
irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
#endif
irq_attach(KINETIS_IRQ_BUSFAULT, kinetis_busfault);

View file

@ -46,7 +46,7 @@
#include "mpu.h"
#include "kinetis_mpuinit.h"
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARMV7M_MPU)
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU)
/****************************************************************************
* Pre-processor Definitions
@ -120,5 +120,5 @@ void kinetis_mpu_uheap(uintptr_t start, size_t size)
mpu_user_intsram(start, size);
}
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARMV7M_MPU */
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */

View file

@ -61,6 +61,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_DEBUG),y)

View file

@ -61,6 +61,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_DEBUG),y)

View file

@ -94,6 +94,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_ARCH_FPU),y)

View file

@ -383,7 +383,7 @@ void up_irqinitialize(void)
* Fault handler.
*/
#ifdef CONFIG_ARMV7M_MPU
#ifdef CONFIG_ARM_MPU
irq_attach(LPC17_IRQ_MEMFAULT, up_memfault);
up_enable_irq(LPC17_IRQ_MEMFAULT);
#endif
@ -392,7 +392,7 @@ void up_irqinitialize(void)
#ifdef CONFIG_DEBUG
irq_attach(LPC17_IRQ_NMI, lpc17_nmi);
#ifndef CONFIG_ARMV7M_MPU
#ifndef CONFIG_ARM_MPU
irq_attach(LPC17_IRQ_MEMFAULT, up_memfault);
#endif
irq_attach(LPC17_IRQ_BUSFAULT, lpc17_busfault);

View file

@ -46,7 +46,7 @@
#include "mpu.h"
#include "lpc17_mpuinit.h"
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARMV7M_MPU)
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU)
/****************************************************************************
* Pre-processor Definitions
@ -120,5 +120,5 @@ void lpc17_mpu_uheap(uintptr_t start, size_t size)
mpu_user_intsram(start, size);
}
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARMV7M_MPU */
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */

View file

@ -52,6 +52,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -56,6 +56,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -53,6 +53,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)

View file

@ -78,6 +78,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_ARCH_FPU),y)

View file

@ -386,7 +386,7 @@ void up_irqinitialize(void)
* Fault handler.
*/
#ifdef CONFIG_ARMV7M_MPU
#ifdef CONFIG_ARM_MPU
irq_attach(LPC43_IRQ_MEMFAULT, up_memfault);
up_enable_irq(LPC43_IRQ_MEMFAULT);
#endif
@ -395,7 +395,7 @@ void up_irqinitialize(void)
#ifdef CONFIG_DEBUG
irq_attach(LPC43_IRQ_NMI, lpc43_nmi);
#ifndef CONFIG_ARMV7M_MPU
#ifndef CONFIG_ARM_MPU
irq_attach(LPC43_IRQ_MEMFAULT, up_memfault);
#endif
irq_attach(LPC43_IRQ_BUSFAULT, lpc43_busfault);

View file

@ -46,7 +46,7 @@
#include "mpu.h"
#include "lpc43_mpuinit.h"
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARMV7M_MPU)
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU)
/****************************************************************************
* Pre-processor Definitions
@ -120,5 +120,5 @@ void lpc43_mpu_uheap(uintptr_t start, size_t size)
mpu_user_intsram(start, size);
}
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARMV7M_MPU */
#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */

View file

@ -50,6 +50,8 @@ CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c up_etherstub.c
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
CHIP_ASRCS = moxart_lowputc.S

View file

@ -61,6 +61,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_DEBUG),y)

View file

@ -85,6 +85,8 @@ endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
else ifeq ($(CONFIG_MODULE),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_ARCH_FPU),y)

Some files were not shown because too many files have changed in this diff Show more