mirror of
https://github.com/apache/nuttx.git
synced 2026-09-07 09:26:38 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
510dc7872d
149 changed files with 17794 additions and 406 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
412
arch/arm/include/armv7-r/irq.h
Normal file
412
arch/arm/include/armv7-r/irq.h
Normal 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 */
|
||||
243
arch/arm/include/armv7-r/syscall.h
Normal file
243
arch/arm/include/armv7-r/syscall.h
Normal 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 */
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
361
arch/arm/include/tms570/chip.h
Normal file
361
arch/arm/include/tms570/chip.h
Normal 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 */
|
||||
94
arch/arm/include/tms570/irq.h
Normal file
94
arch/arm/include/tms570/irq.h
Normal 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 */
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Cortex M3 system calls ***********************************************************/
|
||||
/* Cortex-A system calls ************************************************************/
|
||||
|
||||
/* SYS call 0:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Cortex M3 system calls ***********************************************************/
|
||||
/* Cortex-M system calls ************************************************************/
|
||||
|
||||
/* SYS call 0:
|
||||
*
|
||||
|
|
|
|||
99
arch/arm/src/armv7-m/up_coherent_dcache.c
Normal file
99
arch/arm/src/armv7-m/up_coherent_dcache.c
Normal 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
|||
180
arch/arm/src/armv7-r/Kconfig
Normal file
180
arch/arm/src/armv7-r/Kconfig
Normal 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().
|
||||
156
arch/arm/src/armv7-r/Toolchain.defs
Normal file
156
arch/arm/src/armv7-r/Toolchain.defs
Normal 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
139
arch/arm/src/armv7-r/arm.h
Normal 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 */
|
||||
416
arch/arm/src/armv7-r/arm_assert.c
Normal file
416
arch/arm/src/armv7-r/arm_assert.c
Normal 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 *)¤t_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);
|
||||
}
|
||||
164
arch/arm/src/armv7-r/arm_blocktask.c
Normal file
164
arch/arm/src/armv7-r/arm_blocktask.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
97
arch/arm/src/armv7-r/arm_coherent_dcache.c
Normal file
97
arch/arm/src/armv7-r/arm_coherent_dcache.c
Normal 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
|
||||
}
|
||||
}
|
||||
87
arch/arm/src/armv7-r/arm_copyarmstate.c
Normal file
87
arch/arm/src/armv7-r/arm_copyarmstate.c
Normal 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 */
|
||||
85
arch/arm/src/armv7-r/arm_copyfullstate.c
Normal file
85
arch/arm/src/armv7-r/arm_copyfullstate.c
Normal 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++;
|
||||
}
|
||||
}
|
||||
199
arch/arm/src/armv7-r/arm_dataabort.c
Normal file
199
arch/arm/src/armv7-r/arm_dataabort.c
Normal 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 */
|
||||
122
arch/arm/src/armv7-r/arm_doirq.c
Normal file
122
arch/arm/src/armv7-r/arm_doirq.c
Normal 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;
|
||||
}
|
||||
273
arch/arm/src/armv7-r/arm_elf.c
Normal file
273
arch/arm/src/armv7-r/arm_elf.c
Normal 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;
|
||||
}
|
||||
92
arch/arm/src/armv7-r/arm_fpuconfig.S
Normal file
92
arch/arm/src/armv7-r/arm_fpuconfig.S
Normal 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
|
||||
176
arch/arm/src/armv7-r/arm_fullcontextrestore.S
Normal file
176
arch/arm/src/armv7-r/arm_fullcontextrestore.S
Normal 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
|
||||
536
arch/arm/src/armv7-r/arm_head.S
Normal file
536
arch/arm/src/armv7-r/arm_head.S
Normal 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
|
||||
140
arch/arm/src/armv7-r/arm_initialstate.c
Normal file
140
arch/arm/src/armv7-r/arm_initialstate.c
Normal 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;
|
||||
}
|
||||
874
arch/arm/src/armv7-r/arm_l2cc_pl310.c
Normal file
874
arch/arm/src/armv7-r/arm_l2cc_pl310.c
Normal 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 */
|
||||
433
arch/arm/src/armv7-r/arm_memcpy.S
Normal file
433
arch/arm/src/armv7-r/arm_memcpy.S
Normal 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
|
||||
316
arch/arm/src/armv7-r/arm_mpu.c
Normal file
316
arch/arm/src/armv7-r/arm_mpu.c
Normal 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;
|
||||
}
|
||||
175
arch/arm/src/armv7-r/arm_prefetchabort.c
Normal file
175
arch/arm/src/armv7-r/arm_prefetchabort.c
Normal 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 */
|
||||
135
arch/arm/src/armv7-r/arm_releasepending.c
Normal file
135
arch/arm/src/armv7-r/arm_releasepending.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
189
arch/arm/src/armv7-r/arm_reprioritizertr.c
Normal file
189
arch/arm/src/armv7-r/arm_reprioritizertr.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
110
arch/arm/src/armv7-r/arm_restorefpu.S
Normal file
110
arch/arm/src/armv7-r/arm_restorefpu.S
Normal 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
|
||||
|
||||
106
arch/arm/src/armv7-r/arm_savefpu.S
Normal file
106
arch/arm/src/armv7-r/arm_savefpu.S
Normal 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
|
||||
132
arch/arm/src/armv7-r/arm_saveusercontext.S
Normal file
132
arch/arm/src/armv7-r/arm_saveusercontext.S
Normal 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
|
||||
203
arch/arm/src/armv7-r/arm_schedulesigaction.c
Normal file
203
arch/arm/src/armv7-r/arm_schedulesigaction.c
Normal 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 */
|
||||
139
arch/arm/src/armv7-r/arm_sigdeliver.c
Normal file
139
arch/arm/src/armv7-r/arm_sigdeliver.c
Normal 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 */
|
||||
119
arch/arm/src/armv7-r/arm_signal_dispatch.c
Normal file
119
arch/arm/src/armv7-r/arm_signal_dispatch.c
Normal 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 */
|
||||
121
arch/arm/src/armv7-r/arm_signal_handler.S
Normal file
121
arch/arm/src/armv7-r/arm_signal_handler.S
Normal 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__ */
|
||||
532
arch/arm/src/armv7-r/arm_syscall.c
Normal file
532
arch/arm/src/armv7-r/arm_syscall.c
Normal 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
|
||||
162
arch/arm/src/armv7-r/arm_unblocktask.c
Normal file
162
arch/arm/src/armv7-r/arm_unblocktask.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
87
arch/arm/src/armv7-r/arm_undefinedinsn.c
Normal file
87
arch/arm/src/armv7-r/arm_undefinedinsn.c
Normal 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 */
|
||||
}
|
||||
87
arch/arm/src/armv7-r/arm_vectoraddrexcptn.S
Normal file
87
arch/arm/src/armv7-r/arm_vectoraddrexcptn.S
Normal 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
|
||||
977
arch/arm/src/armv7-r/arm_vectors.S
Normal file
977
arch/arm/src/armv7-r/arm_vectors.S
Normal 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
|
||||
110
arch/arm/src/armv7-r/arm_vectortab.S
Normal file
110
arch/arm/src/armv7-r/arm_vectortab.S
Normal 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
|
||||
140
arch/arm/src/armv7-r/arm_vfork.S
Normal file
140
arch/arm/src/armv7-r/arm_vfork.S
Normal 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
|
||||
207
arch/arm/src/armv7-r/cache.h
Normal file
207
arch/arm/src/armv7-r/cache.h
Normal 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
169
arch/arm/src/armv7-r/cp15.h
Normal 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 */
|
||||
999
arch/arm/src/armv7-r/cp15_cacheops.h
Normal file
999
arch/arm/src/armv7-r/cp15_cacheops.h
Normal 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 */
|
||||
115
arch/arm/src/armv7-r/cp15_clean_dcache.S
Normal file
115
arch/arm/src/armv7-r/cp15_clean_dcache.S
Normal 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
|
||||
137
arch/arm/src/armv7-r/cp15_coherent_dcache.S
Normal file
137
arch/arm/src/armv7-r/cp15_coherent_dcache.S
Normal 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
|
||||
115
arch/arm/src/armv7-r/cp15_flush_dcache.S
Normal file
115
arch/arm/src/armv7-r/cp15_flush_dcache.S
Normal 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
|
||||
122
arch/arm/src/armv7-r/cp15_invalidate_dcache.S
Normal file
122
arch/arm/src/armv7-r/cp15_invalidate_dcache.S
Normal 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
|
||||
116
arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S
Normal file
116
arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S
Normal 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
|
||||
93
arch/arm/src/armv7-r/fpu.h
Normal file
93
arch/arm/src/armv7-r/fpu.h
Normal 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
258
arch/arm/src/armv7-r/l2cc.h
Normal 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 */
|
||||
497
arch/arm/src/armv7-r/l2cc_pl310.h
Normal file
497
arch/arm/src/armv7-r/l2cc_pl310.h
Normal 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
740
arch/arm/src/armv7-r/mpu.h
Normal 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 */
|
||||
545
arch/arm/src/armv7-r/sctlr.h
Normal file
545
arch/arm/src/armv7-r/sctlr.h
Normal 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 */
|
||||
130
arch/arm/src/armv7-r/svcall.h
Normal file
130
arch/arm/src/armv7-r/svcall.h
Normal 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 */
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue