diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1decfd35437..a20d54216f6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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 diff --git a/arch/arm/include/armv7-a/syscall.h b/arch/arm/include/armv7-a/syscall.h index e3a0ab90eb9..9b86d064659 100644 --- a/arch/arm/include/armv7-a/syscall.h +++ b/arch/arm/include/armv7-a/syscall.h @@ -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 diff --git a/arch/arm/include/armv7-r/irq.h b/arch/arm/include/armv7-r/irq.h new file mode 100644 index 00000000000..7365e6648d3 --- /dev/null +++ b/arch/arm/include/armv7-r/irq.h @@ -0,0 +1,412 @@ +/**************************************************************************** + * arch/arm/include/armv7-r/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +#ifndef __ASSEMBLY__ +# include +# include +#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 + * S<2n+1> maps to the most significant half of D. + */ + +#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 */ diff --git a/arch/arm/include/armv7-r/syscall.h b/arch/arm/include/armv7-r/syscall.h new file mode 100644 index 00000000000..2c0cb7ca37d --- /dev/null +++ b/arch/arm/include/armv7-r/syscall.h @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/include/armv7-r/syscall.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#ifndef __ASSEMBLY__ +# include +#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 */ diff --git a/arch/arm/include/irq.h b/arch/arm/include/irq.h index 5f3389bfa27..0a4ad1bc3e6 100644 --- a/arch/arm/include/irq.h +++ b/arch/arm/include/irq.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 * * 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 +#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 #elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ defined(CONFIG_ARCH_CORTEXM7) # include diff --git a/arch/arm/include/tms570/chip.h b/arch/arm/include/tms570/chip.h new file mode 100644 index 00000000000..dcff36c2347 --- /dev/null +++ b/arch/arm/include/tms570/chip.h @@ -0,0 +1,361 @@ +/**************************************************************************************************** + * arch/arm/include/tms570/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/**************************************************************************************************** + * 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 */ diff --git a/arch/arm/include/tms570/irq.h b/arch/arm/include/tms570/irq.h new file mode 100644 index 00000000000..41465fb0375 --- /dev/null +++ b/arch/arm/include/tms570/irq.h @@ -0,0 +1,94 @@ +/**************************************************************************************** + * arch/arm/include/tms570/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +/**************************************************************************************** + * 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 */ + diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile index f36e19f5712..95dcacd228d 100644 --- a/arch/arm/src/Makefile +++ b/arch/arm/src/Makefile @@ -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 diff --git a/arch/arm/src/a1x/Make.defs b/arch/arm/src/a1x/Make.defs index dc7a61b5a18..cd37e623cee 100644 --- a/arch/arm/src/a1x/Make.defs +++ b/arch/arm/src/a1x/Make.defs @@ -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) diff --git a/arch/arm/src/armv7-a/arm_coherent_dcache.c b/arch/arm/src/armv7-a/arm_coherent_dcache.c index 1cb134c9229..363e88f8046 100644 --- a/arch/arm/src/armv7-a/arm_coherent_dcache.c +++ b/arch/arm/src/armv7-a/arm_coherent_dcache.c @@ -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 @@ -44,7 +44,7 @@ #include "cp15_cacheops.h" -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/arch/arm/src/armv7-a/arm_copyarmstate.c b/arch/arm/src/armv7-a/arm_copyarmstate.c index 9c8a7797afa..56848737662 100644 --- a/arch/arm/src/armv7-a/arm_copyarmstate.c +++ b/arch/arm/src/armv7-a/arm_copyarmstate.c @@ -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: */ diff --git a/arch/arm/src/armv7-a/arm_head.S b/arch/arm/src/armv7-a/arm_head.S index 1f29f83f2fe..da3f8d6f2ec 100644 --- a/arch/arm/src/armv7-a/arm_head.S +++ b/arch/arm/src/armv7-a/arm_head.S @@ -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 diff --git a/arch/arm/src/armv7-a/arm_memcpy.S b/arch/arm/src/armv7-a/arm_memcpy.S index f66307a6036..48e1294986b 100644 --- a/arch/arm/src/armv7-a/arm_memcpy.S +++ b/arch/arm/src/armv7-a/arm_memcpy.S @@ -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} diff --git a/arch/arm/src/armv7-a/arm_pghead.S b/arch/arm/src/armv7-a/arm_pghead.S index e7d72951c12..e785360dfec 100644 --- a/arch/arm/src/armv7-a/arm_pghead.S +++ b/arch/arm/src/armv7-a/arm_pghead.S @@ -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). diff --git a/arch/arm/src/armv7-a/arm_undefinedinsn.c b/arch/arm/src/armv7-a/arm_undefinedinsn.c index 392cfb9740c..c0af4cae728 100644 --- a/arch/arm/src/armv7-a/arm_undefinedinsn.c +++ b/arch/arm/src/armv7-a/arm_undefinedinsn.c @@ -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 diff --git a/arch/arm/src/armv7-a/cp15.h b/arch/arm/src/armv7-a/cp15.h index c0f5c76f7b9..8da017b419b 100644 --- a/arch/arm/src/armv7-a/cp15.h +++ b/arch/arm/src/armv7-a/cp15.h @@ -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 */ diff --git a/arch/arm/src/armv7-a/cp15_clean_dcache.S b/arch/arm/src/armv7-a/cp15_clean_dcache.S index 4c2310b1ec4..0f2f8e39eb8 100644 --- a/arch/arm/src/armv7-a/cp15_clean_dcache.S +++ b/arch/arm/src/armv7-a/cp15_clean_dcache.S @@ -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 diff --git a/arch/arm/src/armv7-a/cp15_coherent_dcache.S b/arch/arm/src/armv7-a/cp15_coherent_dcache.S index 2dc245e75b3..8f3ee3196b7 100644 --- a/arch/arm/src/armv7-a/cp15_coherent_dcache.S +++ b/arch/arm/src/armv7-a/cp15_coherent_dcache.S @@ -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 */ diff --git a/arch/arm/src/armv7-a/cp15_flush_dcache.S b/arch/arm/src/armv7-a/cp15_flush_dcache.S index bac23761ae0..ca43fa1adff 100644 --- a/arch/arm/src/armv7-a/cp15_flush_dcache.S +++ b/arch/arm/src/armv7-a/cp15_flush_dcache.S @@ -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 diff --git a/arch/arm/src/armv7-a/cp15_invalidate_dcache.S b/arch/arm/src/armv7-a/cp15_invalidate_dcache.S index a51b4021be1..56ff8837bfb 100644 --- a/arch/arm/src/armv7-a/cp15_invalidate_dcache.S +++ b/arch/arm/src/armv7-a/cp15_invalidate_dcache.S @@ -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 diff --git a/arch/arm/src/armv7-a/l2cc.h b/arch/arm/src/armv7-a/l2cc.h index 1c09f81fd6a..f43ae9b6535 100644 --- a/arch/arm/src/armv7-a/l2cc.h +++ b/arch/arm/src/armv7-a/l2cc.h @@ -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 diff --git a/arch/arm/src/armv7-a/mmu.h b/arch/arm/src/armv7-a/mmu.h index 869299c8615..9ce8280b732 100644 --- a/arch/arm/src/armv7-a/mmu.h +++ b/arch/arm/src/armv7-a/mmu.h @@ -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 diff --git a/arch/arm/src/armv7-a/svcall.h b/arch/arm/src/armv7-a/svcall.h index 513299c1701..9e3c679e899 100644 --- a/arch/arm/src/armv7-a/svcall.h +++ b/arch/arm/src/armv7-a/svcall.h @@ -72,7 +72,7 @@ # endif #endif -/* Cortex M3 system calls ***********************************************************/ +/* Cortex-A system calls ************************************************************/ /* SYS call 0: * diff --git a/arch/arm/src/armv7-m/mpu.h b/arch/arm/src/armv7-m/mpu.h index 990e30aa1df..1418ca97708 100644 --- a/arch/arm/src/armv7-m/mpu.h +++ b/arch/arm/src/armv7-m/mpu.h @@ -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 */ diff --git a/arch/arm/src/armv7-m/svcall.h b/arch/arm/src/armv7-m/svcall.h index f9f85c597ab..cc2b2716b2e 100644 --- a/arch/arm/src/armv7-m/svcall.h +++ b/arch/arm/src/armv7-m/svcall.h @@ -72,7 +72,7 @@ # endif #endif -/* Cortex M3 system calls ***********************************************************/ +/* Cortex-M system calls ************************************************************/ /* SYS call 0: * diff --git a/arch/arm/src/armv7-m/up_coherent_dcache.c b/arch/arm/src/armv7-m/up_coherent_dcache.c new file mode 100644 index 00000000000..019205f46bc --- /dev/null +++ b/arch/arm/src/armv7-m/up_coherent_dcache.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_coherent_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include "cache.h" + +#include + +/**************************************************************************** + * 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(); + } +} diff --git a/arch/arm/src/armv7-m/up_elf.c b/arch/arm/src/armv7-m/up_elf.c index abefae88b5f..bf492f1acaa 100644 --- a/arch/arm/src/armv7-m/up_elf.c +++ b/arch/arm/src/armv7-m/up_elf.c @@ -48,20 +48,6 @@ #include #include -#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 */ diff --git a/arch/arm/src/armv7-m/up_mpu.c b/arch/arm/src/armv7-m/up_mpu.c index 91113dc21b4..05aadda4b6b 100644 --- a/arch/arm/src/armv7-m/up_mpu.c +++ b/arch/arm/src/armv7-m/up_mpu.c @@ -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++; } diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig new file mode 100644 index 00000000000..1924934a0d0 --- /dev/null +++ b/arch/arm/src/armv7-r/Kconfig @@ -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(). diff --git a/arch/arm/src/armv7-r/Toolchain.defs b/arch/arm/src/armv7-r/Toolchain.defs new file mode 100644 index 00000000000..b902c139bce --- /dev/null +++ b/arch/arm/src/armv7-r/Toolchain.defs @@ -0,0 +1,156 @@ +############################################################################ +# arch/arm/src/armv7-r/Toolchain.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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 diff --git a/arch/arm/src/armv7-r/arm.h b/arch/arm/src/armv7-r/arm.h new file mode 100644 index 00000000000..1c0155e4a31 --- /dev/null +++ b/arch/arm/src/armv7-r/arm.h @@ -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 + * + * 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 */ diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c new file mode 100644 index 00000000000..d04d61c1582 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_assert.c @@ -0,0 +1,416 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_assert.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/* 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#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); +} diff --git a/arch/arm/src/armv7-r/arm_blocktask.c b/arch/arm/src/armv7-r/arm_blocktask.c new file mode 100644 index 00000000000..bb03e86d509 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_blocktask.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/up_blocktask.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include +#include + +#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); + } + } +} diff --git a/arch/arm/src/armv7-r/arm_coherent_dcache.c b/arch/arm/src/armv7-r/arm_coherent_dcache.c new file mode 100644 index 00000000000..3be6b8df5c8 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_coherent_dcache.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/up_coherent_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include "cp15_cacheops.h" + +#include + +/**************************************************************************** + * 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 + } +} diff --git a/arch/arm/src/armv7-r/arm_copyarmstate.c b/arch/arm/src/armv7-r/arm_copyarmstate.c new file mode 100644 index 00000000000..601e074e1d2 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_copyarmstate.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_copyarmstate.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#include + +#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 */ diff --git a/arch/arm/src/armv7-r/arm_copyfullstate.c b/arch/arm/src/armv7-r/arm_copyfullstate.c new file mode 100644 index 00000000000..35c0805af2e --- /dev/null +++ b/arch/arm/src/armv7-r/arm_copyfullstate.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_copyfullstate.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#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++; + } +} diff --git a/arch/arm/src/armv7-r/arm_dataabort.c b/arch/arm/src/armv7-r/arm_dataabort.c new file mode 100644 index 00000000000..86280e10e8d --- /dev/null +++ b/arch/arm/src/armv7-r/arm_dataabort.c @@ -0,0 +1,199 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_dataabort.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/* 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 +#include + +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_PAGING +# include +# 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 */ diff --git a/arch/arm/src/armv7-r/arm_doirq.c b/arch/arm/src/armv7-r/arm_doirq.c new file mode 100644 index 00000000000..7aa78aa3d28 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_doirq.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_doirq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#include +#include + +#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; +} diff --git a/arch/arm/src/armv7-r/arm_elf.c b/arch/arm/src/armv7-r/arm_elf.c new file mode 100644 index 00000000000..698ecd0084f --- /dev/null +++ b/arch/arm/src/armv7-r/arm_elf.c @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_elf.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * 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; +} diff --git a/arch/arm/src/armv7-r/arm_fpuconfig.S b/arch/arm/src/armv7-r/arm_fpuconfig.S new file mode 100644 index 00000000000..7f81415ad46 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_fpuconfig.S @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_fpuconfig.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#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 diff --git a/arch/arm/src/armv7-r/arm_fullcontextrestore.S b/arch/arm/src/armv7-r/arm_fullcontextrestore.S new file mode 100644 index 00000000000..58acde09143 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_fullcontextrestore.S @@ -0,0 +1,176 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_fullcontextrestore.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#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 diff --git a/arch/arm/src/armv7-r/arm_head.S b/arch/arm/src/armv7-r/arm_head.S new file mode 100644 index 00000000000..6813f1ba51c --- /dev/null +++ b/arch/arm/src/armv7-r/arm_head.S @@ -0,0 +1,536 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_head.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include "arm.h" +#include "cp15.h" +#include "sctlr.h" + +#include "up_internal.h" +#include "up_arch.h" + +#include + +/********************************************************************************** + * 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 diff --git a/arch/arm/src/armv7-r/arm_initialstate.c b/arch/arm/src/armv7-r/arm_initialstate.c new file mode 100644 index 00000000000..2150020510e --- /dev/null +++ b/arch/arm/src/armv7-r/arm_initialstate.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_initialstate.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include + +#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; +} diff --git a/arch/arm/src/armv7-r/arm_l2cc_pl310.c b/arch/arm/src/armv7-r/arm_l2cc_pl310.c new file mode 100644 index 00000000000..440198e8122 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_l2cc_pl310.c @@ -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 + * + * 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 + +#include +#include +#include + +#include + +#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 */ diff --git a/arch/arm/src/armv7-r/arm_memcpy.S b/arch/arm/src/armv7-r/arm_memcpy.S new file mode 100644 index 00000000000..b88a0e08691 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_memcpy.S @@ -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 diff --git a/arch/arm/src/armv7-r/arm_mpu.c b/arch/arm/src/armv7-r/arm_mpu.c new file mode 100644 index 00000000000..93bda133850 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_mpu.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_mpu.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#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; +} diff --git a/arch/arm/src/armv7-r/arm_prefetchabort.c b/arch/arm/src/armv7-r/arm_prefetchabort.c new file mode 100644 index 00000000000..b3931890e38 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_prefetchabort.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_prefetchabort.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/* 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 +#include + +#include +#ifdef CONFIG_PAGING +# include +#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 */ diff --git a/arch/arm/src/armv7-r/arm_releasepending.c b/arch/arm/src/armv7-r/arm_releasepending.c new file mode 100644 index 00000000000..87647a62157 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_releasepending.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_releasepending.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#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); + } + } +} diff --git a/arch/arm/src/armv7-r/arm_reprioritizertr.c b/arch/arm/src/armv7-r/arm_reprioritizertr.c new file mode 100644 index 00000000000..784d0de7ebc --- /dev/null +++ b/arch/arm/src/armv7-r/arm_reprioritizertr.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_reprioritizertr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include +#include +#include + +#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); + } + } + } +} diff --git a/arch/arm/src/armv7-r/arm_restorefpu.S b/arch/arm/src/armv7-r/arm_restorefpu.S new file mode 100644 index 00000000000..1557986e556 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_restorefpu.S @@ -0,0 +1,110 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/arm_restorefpu.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#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 + diff --git a/arch/arm/src/armv7-r/arm_savefpu.S b/arch/arm/src/armv7-r/arm_savefpu.S new file mode 100644 index 00000000000..af637ada9fc --- /dev/null +++ b/arch/arm/src/armv7-r/arm_savefpu.S @@ -0,0 +1,106 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/arm_savefpu.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#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 diff --git a/arch/arm/src/armv7-r/arm_saveusercontext.S b/arch/arm/src/armv7-r/arm_saveusercontext.S new file mode 100644 index 00000000000..19b198077c4 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_saveusercontext.S @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_saveusercontext.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#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 diff --git a/arch/arm/src/armv7-r/arm_schedulesigaction.c b/arch/arm/src/armv7-r/arm_schedulesigaction.c new file mode 100644 index 00000000000..fa60f5bca29 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_schedulesigaction.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_schedulesigaction.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include + +#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 */ diff --git a/arch/arm/src/armv7-r/arm_sigdeliver.c b/arch/arm/src/armv7-r/arm_sigdeliver.c new file mode 100644 index 00000000000..ce442b3f46c --- /dev/null +++ b/arch/arm/src/armv7-r/arm_sigdeliver.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_sigdeliver.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include +#include +#include +#include + +#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 */ diff --git a/arch/arm/src/armv7-r/arm_signal_dispatch.c b/arch/arm/src/armv7-r/arm_signal_dispatch.c new file mode 100644 index 00000000000..c17f521c6af --- /dev/null +++ b/arch/arm/src/armv7-r/arm_signal_dispatch.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_signal_dispatch.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +#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 */ diff --git a/arch/arm/src/armv7-r/arm_signal_handler.S b/arch/arm/src/armv7-r/arm_signal_handler.S new file mode 100644 index 00000000000..43f629a3ba9 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_signal_handler.S @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_signal_handler.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#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__ */ diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c new file mode 100644 index 00000000000..d5bdddfc98d --- /dev/null +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -0,0 +1,532 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_syscall.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/* 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 +#include +#include +#include +#include + +#include +#include + +#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 diff --git a/arch/arm/src/armv7-r/arm_unblocktask.c b/arch/arm/src/armv7-r/arm_unblocktask.c new file mode 100644 index 00000000000..5eecd53fccf --- /dev/null +++ b/arch/arm/src/armv7-r/arm_unblocktask.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_unblocktask.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#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); + } + } +} diff --git a/arch/arm/src/armv7-r/arm_undefinedinsn.c b/arch/arm/src/armv7-r/arm_undefinedinsn.c new file mode 100644 index 00000000000..21f08efb3f1 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_undefinedinsn.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_undefinedinsn.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/* 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 +#include +#include + +#include + +#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 */ +} diff --git a/arch/arm/src/armv7-r/arm_vectoraddrexcptn.S b/arch/arm/src/armv7-r/arm_vectoraddrexcptn.S new file mode 100644 index 00000000000..42775bd3b57 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vectoraddrexcptn.S @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_vectoraddrexceptn.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#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 diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S new file mode 100644 index 00000000000..1d0f690e070 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -0,0 +1,977 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/arm_vectors.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +#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 diff --git a/arch/arm/src/armv7-r/arm_vectortab.S b/arch/arm/src/armv7-r/arm_vectortab.S new file mode 100644 index 00000000000..6c8f9944757 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vectortab.S @@ -0,0 +1,110 @@ +/**************************************************************************** + * arch/arm/src/arm7-r/arm_vectortab.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + + .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 diff --git a/arch/arm/src/armv7-r/arm_vfork.S b/arch/arm/src/armv7-r/arm_vfork.S new file mode 100644 index 00000000000..635a5759c46 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vfork.S @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_vfork.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#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 diff --git a/arch/arm/src/armv7-r/cache.h b/arch/arm/src/armv7-r/cache.h new file mode 100644 index 00000000000..ec0a892c3fa --- /dev/null +++ b/arch/arm/src/armv7-r/cache.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/cache.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#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 */ diff --git a/arch/arm/src/armv7-r/cp15.h b/arch/arm/src/armv7-r/cp15.h new file mode 100644 index 00000000000..99a841ffc54 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15.h @@ -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 + * + * 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 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* System control register descriptions. + * + * CP15 registers are accessed with MRC and MCR instructions as follows: + * + * MRC p15, , , , , ; Read CP15 Register + * MCR p15, , , , , ; Write CP15 Register + * + * Where + * + * is the Opcode_1 value for the register + * is a general purpose register + * is the register number within CP15 + * is the operational register + * 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 */ diff --git a/arch/arm/src/armv7-r/cp15_cacheops.h b/arch/arm/src/armv7-r/cp15_cacheops.h new file mode 100644 index 00000000000..aa0dee9906c --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_cacheops.h @@ -0,0 +1,999 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/cp15_cacheops.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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, , c7, c1, 0 + * CP15 Register: BPIALLIS + * Description: Invalidate entire branch predictor array Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , 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, , c7, c5, 0 + * CP15 Register: ICIMVAU + * Description: Invalidate instruction cache by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c5, 1 + * CP15 Register: CP15ISB + * Description: Instruction Synchronization Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c5, 4 + * CP15 Register: BPIALL + * Description: Invalidate entire branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 6 + * CP15 Register: BPIMVA + * Description: Invalidate VA from branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 7 + * CP15 Register: DCIMVAC + * Description: Invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c6, 1 + * CP15 Register: DCISW + * Description: Invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c6, 2 + * CP15 Register: DCCMVAC + * Description: Clean data cache line to PoC by VA. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c10, 1 + * CP15 Register: DCCSW + * Description: Clean data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c10, 2 + * CP15 Register: CP15DSB + * Description: Data Synchronization Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c10, 4 + * CP15 Register: CP15DMB + * Description: Data Memory Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c10, 5 + * CP15 Register: DCCMVAU + * Description: Clean data or unified cache line by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c11, 1 + * CP15 Register: DCCIMVAC + * Description: Clean and invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c14, 1 + * CP15 Register: DCCISW + * Description: Clean and invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , 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 */ diff --git a/arch/arm/src/armv7-r/cp15_clean_dcache.S b/arch/arm/src/armv7-r/cp15_clean_dcache.S new file mode 100644 index 00000000000..f4739c02d39 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_clean_dcache.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_clean_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 diff --git a/arch/arm/src/armv7-r/cp15_coherent_dcache.S b/arch/arm/src/armv7-r/cp15_coherent_dcache.S new file mode 100644 index 00000000000..fa8b728f287 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_coherent_dcache.S @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_coherent_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 diff --git a/arch/arm/src/armv7-r/cp15_flush_dcache.S b/arch/arm/src/armv7-r/cp15_flush_dcache.S new file mode 100644 index 00000000000..d7d1fe278ed --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_flush_dcache.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_flush_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 diff --git a/arch/arm/src/armv7-r/cp15_invalidate_dcache.S b/arch/arm/src/armv7-r/cp15_invalidate_dcache.S new file mode 100644 index 00000000000..2dc6ab0ce61 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_invalidate_dcache.S @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_invalidate_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 diff --git a/arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S b/arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S new file mode 100644 index 00000000000..da32c8c9ad5 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S @@ -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 + * + * 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 diff --git a/arch/arm/src/armv7-r/fpu.h b/arch/arm/src/armv7-r/fpu.h new file mode 100644 index 00000000000..1f8fdfdba16 --- /dev/null +++ b/arch/arm/src/armv7-r/fpu.h @@ -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 + * + * 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 + +/**************************************************************************** + * 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 */ diff --git a/arch/arm/src/armv7-r/l2cc.h b/arch/arm/src/armv7-r/l2cc.h new file mode 100644 index 00000000000..05a69ab94dc --- /dev/null +++ b/arch/arm/src/armv7-r/l2cc.h @@ -0,0 +1,258 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/l2cc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#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 */ diff --git a/arch/arm/src/armv7-r/l2cc_pl310.h b/arch/arm/src/armv7-r/l2cc_pl310.h new file mode 100644 index 00000000000..12431ace378 --- /dev/null +++ b/arch/arm/src/armv7-r/l2cc_pl310.h @@ -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 + * + * 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 + +/* 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 */ diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h new file mode 100644 index 00000000000..703883988fd --- /dev/null +++ b/arch/arm/src/armv7-r/mpu.h @@ -0,0 +1,740 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/mpu.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#ifndef __ASSEMBLY__ +# include +# include +# include +# include + +# 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 */ diff --git a/arch/arm/src/armv7-r/sctlr.h b/arch/arm/src/armv7-r/sctlr.h new file mode 100644 index 00000000000..76ab8081df1 --- /dev/null +++ b/arch/arm/src/armv7-r/sctlr.h @@ -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 + * + * 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 */ diff --git a/arch/arm/src/armv7-r/svcall.h b/arch/arm/src/armv7-r/svcall.h new file mode 100644 index 00000000000..0fdec03d164 --- /dev/null +++ b/arch/arm/src/armv7-r/svcall.h @@ -0,0 +1,130 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/svcall.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#ifdef CONFIG_LIB_SYSCALL +# include +#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 */ diff --git a/arch/arm/src/c5471/Make.defs b/arch/arm/src/c5471/Make.defs index b1c64bed3aa..92320e5d480 100644 --- a/arch/arm/src/c5471/Make.defs +++ b/arch/arm/src/c5471/Make.defs @@ -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) diff --git a/arch/arm/src/calypso/Make.defs b/arch/arm/src/calypso/Make.defs index 009100c43ad..c3d6b6b0bb5 100644 --- a/arch/arm/src/calypso/Make.defs +++ b/arch/arm/src/calypso/Make.defs @@ -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) diff --git a/arch/arm/src/dm320/Make.defs b/arch/arm/src/dm320/Make.defs index 530d70bd226..ab9b2afa638 100644 --- a/arch/arm/src/dm320/Make.defs +++ b/arch/arm/src/dm320/Make.defs @@ -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) diff --git a/arch/arm/src/efm32/Make.defs b/arch/arm/src/efm32/Make.defs index 609ac46d14e..5e23655f645 100644 --- a/arch/arm/src/efm32/Make.defs +++ b/arch/arm/src/efm32/Make.defs @@ -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) diff --git a/arch/arm/src/efm32/efm32_irq.c b/arch/arm/src/efm32/efm32_irq.c index e8830e41213..29999b0eb14 100644 --- a/arch/arm/src/efm32/efm32_irq.c +++ b/arch/arm/src/efm32/efm32_irq.c @@ -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); diff --git a/arch/arm/src/imx/Make.defs b/arch/arm/src/imx/Make.defs index 46d16d41486..792d6c3244e 100644 --- a/arch/arm/src/imx/Make.defs +++ b/arch/arm/src/imx/Make.defs @@ -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) diff --git a/arch/arm/src/kinetis/Make.defs b/arch/arm/src/kinetis/Make.defs index d4bce7b4a78..b8a6bb5cce4 100644 --- a/arch/arm/src/kinetis/Make.defs +++ b/arch/arm/src/kinetis/Make.defs @@ -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 diff --git a/arch/arm/src/kinetis/kinetis_irq.c b/arch/arm/src/kinetis/kinetis_irq.c index 0457957752d..8a215f75bd2 100644 --- a/arch/arm/src/kinetis/kinetis_irq.c +++ b/arch/arm/src/kinetis/kinetis_irq.c @@ -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); diff --git a/arch/arm/src/kinetis/kinetis_mpuinit.c b/arch/arm/src/kinetis/kinetis_mpuinit.c index 8e2bceb622a..6c41f85bf4f 100644 --- a/arch/arm/src/kinetis/kinetis_mpuinit.c +++ b/arch/arm/src/kinetis/kinetis_mpuinit.c @@ -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 */ diff --git a/arch/arm/src/kl/Make.defs b/arch/arm/src/kl/Make.defs index 20d5a64f584..68c58af802e 100644 --- a/arch/arm/src/kl/Make.defs +++ b/arch/arm/src/kl/Make.defs @@ -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) diff --git a/arch/arm/src/lpc11xx/Make.defs b/arch/arm/src/lpc11xx/Make.defs index 9bde780de7c..a40c1435455 100644 --- a/arch/arm/src/lpc11xx/Make.defs +++ b/arch/arm/src/lpc11xx/Make.defs @@ -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) diff --git a/arch/arm/src/lpc17xx/Make.defs b/arch/arm/src/lpc17xx/Make.defs index daf388a1172..ff8285474e7 100644 --- a/arch/arm/src/lpc17xx/Make.defs +++ b/arch/arm/src/lpc17xx/Make.defs @@ -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) diff --git a/arch/arm/src/lpc17xx/lpc17_irq.c b/arch/arm/src/lpc17xx/lpc17_irq.c index 0f7149ec0a9..1804f4193d4 100644 --- a/arch/arm/src/lpc17xx/lpc17_irq.c +++ b/arch/arm/src/lpc17xx/lpc17_irq.c @@ -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); diff --git a/arch/arm/src/lpc17xx/lpc17_mpuinit.c b/arch/arm/src/lpc17xx/lpc17_mpuinit.c index adc4bc918c2..9cf561fcf22 100644 --- a/arch/arm/src/lpc17xx/lpc17_mpuinit.c +++ b/arch/arm/src/lpc17xx/lpc17_mpuinit.c @@ -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 */ diff --git a/arch/arm/src/lpc214x/Make.defs b/arch/arm/src/lpc214x/Make.defs index 364c2c52ee2..ea9bc404490 100644 --- a/arch/arm/src/lpc214x/Make.defs +++ b/arch/arm/src/lpc214x/Make.defs @@ -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) diff --git a/arch/arm/src/lpc2378/Make.defs b/arch/arm/src/lpc2378/Make.defs index 4df2d7eb3e5..a79ce91ddd9 100644 --- a/arch/arm/src/lpc2378/Make.defs +++ b/arch/arm/src/lpc2378/Make.defs @@ -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) diff --git a/arch/arm/src/lpc31xx/Make.defs b/arch/arm/src/lpc31xx/Make.defs index a8bbcb5087b..03c6c0bef6e 100644 --- a/arch/arm/src/lpc31xx/Make.defs +++ b/arch/arm/src/lpc31xx/Make.defs @@ -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) diff --git a/arch/arm/src/lpc43xx/Make.defs b/arch/arm/src/lpc43xx/Make.defs index 3b3f8b1948f..a8fa5d5b4a3 100644 --- a/arch/arm/src/lpc43xx/Make.defs +++ b/arch/arm/src/lpc43xx/Make.defs @@ -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) diff --git a/arch/arm/src/lpc43xx/lpc43_irq.c b/arch/arm/src/lpc43xx/lpc43_irq.c index 2752c50dbf4..692bc2beaae 100644 --- a/arch/arm/src/lpc43xx/lpc43_irq.c +++ b/arch/arm/src/lpc43xx/lpc43_irq.c @@ -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); diff --git a/arch/arm/src/lpc43xx/lpc43_mpuinit.c b/arch/arm/src/lpc43xx/lpc43_mpuinit.c index 499c38a9773..3ed8d8a8c74 100644 --- a/arch/arm/src/lpc43xx/lpc43_mpuinit.c +++ b/arch/arm/src/lpc43xx/lpc43_mpuinit.c @@ -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 */ diff --git a/arch/arm/src/moxart/Make.defs b/arch/arm/src/moxart/Make.defs index 1752223114d..48b9a21fa08 100644 --- a/arch/arm/src/moxart/Make.defs +++ b/arch/arm/src/moxart/Make.defs @@ -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 diff --git a/arch/arm/src/nuc1xx/Make.defs b/arch/arm/src/nuc1xx/Make.defs index 753322fb34a..3a9f0651912 100644 --- a/arch/arm/src/nuc1xx/Make.defs +++ b/arch/arm/src/nuc1xx/Make.defs @@ -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) diff --git a/arch/arm/src/sam34/Make.defs b/arch/arm/src/sam34/Make.defs index 551a5cdd682..03b241d632c 100644 --- a/arch/arm/src/sam34/Make.defs +++ b/arch/arm/src/sam34/Make.defs @@ -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) diff --git a/arch/arm/src/sam34/sam_irq.c b/arch/arm/src/sam34/sam_irq.c index 55ce2d1bf9c..314aff78e98 100644 --- a/arch/arm/src/sam34/sam_irq.c +++ b/arch/arm/src/sam34/sam_irq.c @@ -447,7 +447,7 @@ void up_irqinitialize(void) * Fault handler. */ -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU irq_attach(SAM_IRQ_MEMFAULT, up_memfault); up_enable_irq(SAM_IRQ_MEMFAULT); #endif @@ -456,7 +456,7 @@ void up_irqinitialize(void) #ifdef CONFIG_DEBUG irq_attach(SAM_IRQ_NMI, sam_nmi); -#ifndef CONFIG_ARMV7M_MPU +#ifndef CONFIG_ARM_MPU irq_attach(SAM_IRQ_MEMFAULT, up_memfault); #endif irq_attach(SAM_IRQ_BUSFAULT, sam_busfault); diff --git a/arch/arm/src/sam34/sam_mpuinit.c b/arch/arm/src/sam34/sam_mpuinit.c index a33788b7d1f..f49bb68d10a 100644 --- a/arch/arm/src/sam34/sam_mpuinit.c +++ b/arch/arm/src/sam34/sam_mpuinit.c @@ -46,7 +46,7 @@ #include "mpu.h" #include "sam_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 sam_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 */ diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs index 65a203c45f0..cb6ac5a784f 100644 --- a/arch/arm/src/sama5/Make.defs +++ b/arch/arm/src/sama5/Make.defs @@ -114,6 +114,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) diff --git a/arch/arm/src/sama5/sam_udphs.c b/arch/arm/src/sama5/sam_udphs.c index 39f72d63ff1..fde1365e8a4 100644 --- a/arch/arm/src/sama5/sam_udphs.c +++ b/arch/arm/src/sama5/sam_udphs.c @@ -2395,8 +2395,9 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno) * REVISIT: On the SAMV7, I found that you really need to * wait for the TX completion interrupt before calling * sam_req_write(). For the SAMV7, the logic here just - * enables that TX completion interrupt. The symptom of - * the problem was occassional missing zero-length packets. + * enables that TX completion interrupt if BYCT > 0. The + * symptom of the problem was occasional missing zero-length + * packets because sam_req_write() was called too soon. */ DEBUGASSERT(USB_ISEPIN(privep->ep.eplog)); diff --git a/arch/arm/src/samdl/Make.defs b/arch/arm/src/samdl/Make.defs index 9b52be03102..d9a82f959e5 100644 --- a/arch/arm/src/samdl/Make.defs +++ b/arch/arm/src/samdl/Make.defs @@ -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) diff --git a/arch/arm/src/samv7/Kconfig b/arch/arm/src/samv7/Kconfig index 94cdc0a7925..42479b5a8f1 100644 --- a/arch/arm/src/samv7/Kconfig +++ b/arch/arm/src/samv7/Kconfig @@ -384,7 +384,7 @@ config SAMV7_QSPI bool "Quad SPI (QSPI)" default n select ARCH_USE_MPU - select ARMV7M_MPU + select ARM_MPU config SAMV7_RTC bool "Real Time Clock (RTC)" diff --git a/arch/arm/src/samv7/Make.defs b/arch/arm/src/samv7/Make.defs index 79559c93804..0a9af083f39 100644 --- a/arch/arm/src/samv7/Make.defs +++ b/arch/arm/src/samv7/Make.defs @@ -90,7 +90,7 @@ ifeq ($(CONFIG_ARCH_MEMCPY),y) CMN_ASRCS += up_memcpy.S endif -ifeq ($(CONFIG_ARMV7M_MPU),y) +ifeq ($(CONFIG_ARM_MPU),y) CMN_CSRCS += up_mpu.c ifeq ($(CONFIG_BUILD_PROTECTED),y) CMN_CSRCS += up_task_start.c up_pthread_start.c @@ -102,7 +102,9 @@ endif endif ifeq ($(CONFIG_ELF),y) -CMN_CSRCS += up_elf.c +CMN_CSRCS += up_elf.c up_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c endif ifeq ($(CONFIG_STACK_COLORATION),y) @@ -121,7 +123,7 @@ ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += sam_timerisr.c endif -ifeq ($(CONFIG_ARMV7M_MPU),y) +ifeq ($(CONFIG_ARM_MPU),y) CHIP_CSRCS += sam_mpuinit.c ifeq ($(CONFIG_BUILD_PROTECTED),y) CHIP_CSRCS += sam_userspace.c diff --git a/arch/arm/src/samv7/sam_irq.c b/arch/arm/src/samv7/sam_irq.c index 5a0e6ff9c23..7db06249c58 100644 --- a/arch/arm/src/samv7/sam_irq.c +++ b/arch/arm/src/samv7/sam_irq.c @@ -447,7 +447,7 @@ void up_irqinitialize(void) * Fault handler. */ -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU irq_attach(SAM_IRQ_MEMFAULT, up_memfault); up_enable_irq(SAM_IRQ_MEMFAULT); #endif @@ -456,7 +456,7 @@ void up_irqinitialize(void) #ifdef CONFIG_DEBUG irq_attach(SAM_IRQ_NMI, sam_nmi); -#ifndef CONFIG_ARMV7M_MPU +#ifndef CONFIG_ARM_MPU irq_attach(SAM_IRQ_MEMFAULT, up_memfault); #endif irq_attach(SAM_IRQ_BUSFAULT, sam_busfault); diff --git a/arch/arm/src/samv7/sam_mpuinit.c b/arch/arm/src/samv7/sam_mpuinit.c index b2f730f40e8..e9b0b377543 100644 --- a/arch/arm/src/samv7/sam_mpuinit.c +++ b/arch/arm/src/samv7/sam_mpuinit.c @@ -49,7 +49,7 @@ #include "sam_mpuinit.h" -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU /**************************************************************************** * Pre-processor Definitions @@ -146,5 +146,5 @@ void sam_mpu_uheap(uintptr_t start, size_t size) } #endif -#endif /* CONFIG_ARMV7M_MPU */ +#endif /* CONFIG_ARM_MPU */ diff --git a/arch/arm/src/samv7/sam_mpuinit.h b/arch/arm/src/samv7/sam_mpuinit.h index e8745f8e6b7..ef5a9d037aa 100644 --- a/arch/arm/src/samv7/sam_mpuinit.h +++ b/arch/arm/src/samv7/sam_mpuinit.h @@ -77,7 +77,7 @@ extern "C" * ****************************************************************************/ -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU void sam_mpu_initialize(void); #else # define sam_mpu_initialize() diff --git a/arch/arm/src/samv7/sam_start.c b/arch/arm/src/samv7/sam_start.c index 285e429b6b4..9d5331721f8 100644 --- a/arch/arm/src/samv7/sam_start.c +++ b/arch/arm/src/samv7/sam_start.c @@ -367,7 +367,7 @@ void __start(void) sam_boardinitialize(); -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU /* For the case of the separate user-/kernel-space build, perform whatever * platform specific initialization of the user memory is required. * Normally this just means initializing the user space .data and .bss diff --git a/arch/arm/src/samv7/sam_usbdevhs.c b/arch/arm/src/samv7/sam_usbdevhs.c index f3225c8573c..ae47f4654d6 100644 --- a/arch/arm/src/samv7/sam_usbdevhs.c +++ b/arch/arm/src/samv7/sam_usbdevhs.c @@ -2490,20 +2490,60 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno) if (privep->epstate == USBHS_EPSTATE_SENDING) { + uint32_t nbusybk; + uint32_t byct; + /* This is an IN endpoint. Continuing processing the write - * request. We must call sam_req_write in the IDLE state - * with the number of bytes transferred in 'inflight' + * request. */ DEBUGASSERT(USB_ISEPIN(privep->ep.eplog)); sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTICR(epno)); -#if 1 /* Wait for TXINI */ - sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIER(epno)); -#else - privep->epstate = USBHS_EPSTATE_IDLE; - (void)sam_req_write(priv, privep); -#endif + /* Have all of the bytes in the FIFO been transmitted to the + * host? + * + * BYCT == 0 Means that all of the data has been transferred + * out of the FIFO. + * Warning: This field may be updated one clock cycle + * after the RWALL bit changes, so the user should not + * poll this field as an interrupt bit. + * NBUSYBK == 0 Indicates that all banks that have been sent to + * the host. + */ + + regval = sam_getreg(SAM_USBHS_DEVEPTISR(epno)); + byct = (regval & USBHS_DEVEPTISR_BYCT_MASK) >> USBHS_DEVEPTISR_BYCT_SHIFT; + nbusybk = (regval & USBHS_DEVEPTISR_NBUSYBK_MASK) >> USBHS_DEVEPTISR_NBUSYBK_SHIFT; + + if (byct > 0 || nbusybk > 0) + { + /* Not all of the data has been sent to the host. A TXIN + * interrupt will be generated later. Enable the TXIN + * interrupt now and wait for the transfer to complete. + * + * REVISIT: How many TXIN interrupts will be generated + * before the tranfer completes? This assumes one. If + * there are more than one than sam_req_write() will be + * called too soon. + */ + + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIER(epno)); + } + else + { + /* All bytes have been sent to the host. We must call + * sam_req_write() now in the IDLE state with the number of + * bytes transferred in 'inflight' + * + * REVISIT: Isn't there a race condition here? Could TXIN + * have fired just before calculating byct? Could TXIN be + * pending here? + */ + + privep->epstate = USBHS_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } } else if (privep->epstate == USBHS_EPSTATE_RECEIVING) { diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 11a6ca3ff92..173f4ddb8e7 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -6182,6 +6182,108 @@ menu "QEncoder Driver" depends on QENCODER depends on STM32_TIM1 || STM32_TIM2 || STM32_TIM3 || STM32_TIM4 || STM32_TIM5 || STM32_TIM8 +config STM32_TIM1_QE + bool "TIM1" + default n + depends on STM32_TIM1 + ---help--- + Reserve TIM1 for use by QEncoder. + +if STM32_TIM1_QE + +config STM32_TIM1_QECLKOUT + int "TIM1 output clock" + default 2800000 + ---help--- + The output clock of TIM1. + +endif + +config STM32_TIM2_QE + bool "TIM2" + default n + depends on STM32_TIM2 + ---help--- + Reserve TIM2 for use by QEncoder. + +if STM32_TIM2_QE + +config STM32_TIM2_QECLKOUT + int "TIM2 output clock" + default 2800000 + ---help--- + The output clock of TIM2. + +endif + +config STM32_TIM3_QE + bool "TIM3" + default n + depends on STM32_TIM3 + ---help--- + Reserve TIM3 for use by QEncoder. + +if STM32_TIM3_QE + +config STM32_TIM3_QECLKOUT + int "TIM3 output clock" + default 2800000 + ---help--- + The output clock of TIM3. + +endif + +config STM32_TIM4_QE + bool "TIM4" + default n + depends on STM32_TIM4 + ---help--- + Reserve TIM4 for use by QEncoder. + +if STM32_TIM4_QE + +config STM32_TIM4_QECLKOUT + int "TIM4 output clock" + default 2800000 + ---help--- + The output clock of TIM4. + +endif + +config STM32_TIM5_QE + bool "TIM5" + default n + depends on STM32_TIM5 + ---help--- + Reserve TIM5 for use by QEncoder. + +if STM32_TIM5_QE + +config STM32_TIM5_QECLKOUT + int "TIM5 output clock" + default 2800000 + ---help--- + The output clock of TIM5. + +endif + +config STM32_TIM8_QE + bool "TIM8" + default n + depends on STM32_TIM8 + ---help--- + Reserve TIM8 for use by QEncoder. + +if STM32_TIM8_QE + +config STM32_TIM8_QECLKOUT + int "TIM8 output clock" + default 2800000 + ---help--- + The output clock of TIM8. + +endif + config STM32_QENCODER_FILTER bool "Enable filtering on STM32 QEncoder input" default y diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index e1b4d6d9fd7..752069b8db0 100644 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -89,6 +89,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) diff --git a/arch/arm/src/stm32/chip/stm32f103v_pinmap.h b/arch/arm/src/stm32/chip/stm32f103v_pinmap.h index c63a5f96bf9..61895a74e9b 100644 --- a/arch/arm/src/stm32/chip/stm32f103v_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f103v_pinmap.h @@ -338,7 +338,7 @@ #define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) -#define GPIO_TIM5_CH4IN (GGPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) #if 0 /* Needs further investigation */ diff --git a/arch/arm/src/stm32/chip/stm32f105v_pinmap.h b/arch/arm/src/stm32/chip/stm32f105v_pinmap.h index 73a08bd3534..71ffe846487 100644 --- a/arch/arm/src/stm32/chip/stm32f105v_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f105v_pinmap.h @@ -334,7 +334,7 @@ #define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) -#define GPIO_TIM5_CH4IN (GGPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) #if 0 /* Needs further investigation */ diff --git a/arch/arm/src/stm32/chip/stm32f107v_pinmap.h b/arch/arm/src/stm32/chip/stm32f107v_pinmap.h index 66de9a70a0b..33af4826428 100644 --- a/arch/arm/src/stm32/chip/stm32f107v_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f107v_pinmap.h @@ -340,7 +340,7 @@ #define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) -#define GPIO_TIM5_CH4IN (GGPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) #if 0 /* Needs further investigation */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h index 38ae3f0c368..7bc9ed67db3 100644 --- a/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h @@ -258,7 +258,7 @@ #define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN9) #define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN9) #define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) -#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|PIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) #define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN8) #define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN13) #define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) @@ -267,7 +267,7 @@ #define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN11) #define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN11) #define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) -#define GPIO_TIM1_CHOUT2_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) #define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN10) #define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) #define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) @@ -443,7 +443,7 @@ #define GPIO_TIM16_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM16_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM16_CH1IN_5 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) -#define GPIO_TIM16_CHOUT1_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1OUT_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) #define GPIO_TIM16_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) #define GPIO_TIM16_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) @@ -451,7 +451,7 @@ #define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) #define GPIO_TIM17_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM17_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) -#define GPIO_TIM17_CH1IN_2 (GPIO_ALT|GGPIO_FLOAT|PIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM17_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) #define GPIO_TIM17_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) #define GPIO_TIM17_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) #define GPIO_TIM17_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h index 4cc7543f74c..6f48b4bf1e8 100644 --- a/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h @@ -341,7 +341,7 @@ #define GPIO_TIM16_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM16_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM16_CH1IN_5 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) -#define GPIO_TIM16_CHOUT1_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1OUT_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) #define GPIO_TIM16_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) #define GPIO_TIM16_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) @@ -349,7 +349,7 @@ #define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) #define GPIO_TIM17_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM17_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) -#define GPIO_TIM17_CH1IN_2 (GPIO_ALT|GGPIO_FLOAT|PIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM17_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) #define GPIO_TIM17_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) #define GPIO_TIM17_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) #define GPIO_TIM17_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) diff --git a/arch/arm/src/stm32/stm32_irq.c b/arch/arm/src/stm32/stm32_irq.c index 2d8f7b9f7dd..cf9fe37c36f 100644 --- a/arch/arm/src/stm32/stm32_irq.c +++ b/arch/arm/src/stm32/stm32_irq.c @@ -394,7 +394,7 @@ void up_irqinitialize(void) * Fault handler. */ -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU irq_attach(STM32_IRQ_MEMFAULT, up_memfault); up_enable_irq(STM32_IRQ_MEMFAULT); #endif @@ -403,7 +403,7 @@ void up_irqinitialize(void) #ifdef CONFIG_DEBUG irq_attach(STM32_IRQ_NMI, stm32_nmi); -#ifndef CONFIG_ARMV7M_MPU +#ifndef CONFIG_ARM_MPU irq_attach(STM32_IRQ_MEMFAULT, up_memfault); #endif irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault); diff --git a/arch/arm/src/stm32/stm32_mpuinit.c b/arch/arm/src/stm32/stm32_mpuinit.c index e5f727ae388..552e75d1fd9 100644 --- a/arch/arm/src/stm32/stm32_mpuinit.c +++ b/arch/arm/src/stm32/stm32_mpuinit.c @@ -46,7 +46,7 @@ #include "mpu.h" #include "stm32_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 stm32_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 */ diff --git a/arch/arm/src/stm32/stm32_pwm.c b/arch/arm/src/stm32/stm32_pwm.c index 1a4d2242577..6885b914345 100644 --- a/arch/arm/src/stm32/stm32_pwm.c +++ b/arch/arm/src/stm32/stm32_pwm.c @@ -84,20 +84,21 @@ #define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ #define TIMTYPE_TIM1 TIMTYPE_ADVANCED -#ifdef CONFIG_STM32_STM32L15XX +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) # define TIMTYPE_TIM2 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM3 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM4 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM5 TIMTYPE_GENERAL32 -#elif defined(CONFIG_STM32_STM32F10XX) -# define TIMTYPE_TIM2 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM3 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM4 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM5 TIMTYPE_GENERAL16 #else # define TIMTYPE_TIM2 TIMTYPE_GENERAL32 +#endif +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) # define TIMTYPE_TIM3 TIMTYPE_GENERAL32 # define TIMTYPE_TIM4 TIMTYPE_GENERAL32 +#else +# define TIMTYPE_TIM3 TIMTYPE_GENERAL16 +# define TIMTYPE_TIM4 TIMTYPE_GENERAL16 +#endif +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define TIMTYPE_TIM5 TIMTYPE_GENERAL16 +#else # define TIMTYPE_TIM5 TIMTYPE_GENERAL32 #endif #define TIMTYPE_TIM6 TIMTYPE_BASIC diff --git a/arch/arm/src/stm32/stm32_qencoder.c b/arch/arm/src/stm32/stm32_qencoder.c index d9eff8a2d6d..8823554c080 100644 --- a/arch/arm/src/stm32/stm32_qencoder.c +++ b/arch/arm/src/stm32/stm32_qencoder.c @@ -93,11 +93,12 @@ #endif /* Timers ***************************************************************************/ -/* On the F1 series, all timers are 16-bit. */ #undef HAVE_32BIT_TIMERS #undef HAVE_16BIT_TIMERS +/* On the F1 series, all timers are 16-bit. */ + #if defined(CONFIG_STM32_STM32F10XX) # define HAVE_16BIT_TIMERS 1 @@ -111,6 +112,33 @@ # define TIM5_BITWIDTH 16 # define TIM8_BITWIDTH 16 +/* On the F3 series, TIM5 is 32-bit. All of the rest are 16-bit */ + +#elif defined(CONFIG_STM32_STM32F30XX) + + /* If TIM5 is enabled, then we have 32-bit timers */ + +# if defined(CONFIG_STM32_TIM5_QE) +# define HAVE_32BIT_TIMERS 1 +# endif + + /* If TIM1,2,3,4, or 8 are enabled, then we have 16-bit timers */ + +# if defined(CONFIG_STM32_TIM1_QE) || defined(CONFIG_STM32_TIM2_QE) || \ + defined(CONFIG_STM32_TIM3_QE) || defined(CONFIG_STM32_TIM4_QE) || \ + defined(CONFIG_STM32_TIM8_QE) +# define HAVE_16BIT_TIMERS 1 +# endif + + /* The width in bits of each timer */ + +# define TIM1_BITWIDTH 16 +# define TIM2_BITWIDTH 16 +# define TIM3_BITWIDTH 16 +# define TIM4_BITWIDTH 16 +# define TIM5_BITWIDTH 32 +# define TIM8_BITWIDTH 16 + /* On the F4 series, TIM2 and TIM5 are 32-bit. All of the rest are 16-bit */ #elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) @@ -146,6 +174,7 @@ #endif /* Input filter *********************************************************************/ + #ifdef CONFIG_STM32_QENCODER_FILTER # if defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS) # if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_1) @@ -204,6 +233,17 @@ # define STM32_QENCODER_ICF GTIM_CCMR_ICF_NOFILT #endif +#if defined(CONFIG_STM32_STM32F10XX) +# define STM32_GPIO_INPUT_FLOAT (GPIO_INPUT | GPIO_CNF_INFLOAT | \ + GPIO_MODE_INPUT) +#elif defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define STM32_GPIO_INPUT_FLOAT (GPIO_INPUT | GPIO_FLOAT); +#else +# error "Unrecognized STM32 chip" +#endif + /* Debug ****************************************************************************/ /* Non-standard debug that may be enabled just for testing the quadrature encoder */ @@ -234,12 +274,12 @@ struct stm32_qeconfig_s #ifdef HAVE_MIXEDWIDTH_TIMERS uint8_t width; /* Timer width (16- or 32-bits) */ #endif -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) - uint32_t ti1cfg; /* TI1 input pin configuration (20-bit encoding) */ - uint32_t ti2cfg; /* TI2 input pin configuration (20-bit encoding) */ -#else +#ifdef CONFIG_STM32_STM32F10XX uint16_t ti1cfg; /* TI1 input pin configuration (16-bit encoding) */ uint16_t ti2cfg; /* TI2 input pin configuration (16-bit encoding) */ +#else + uint32_t ti1cfg; /* TI1 input pin configuration (20-bit encoding) */ + uint32_t ti2cfg; /* TI2 input pin configuration (20-bit encoding) */ #endif uint32_t base; /* Register base address */ uint32_t psc; /* Timer input clock prescaler */ @@ -272,13 +312,13 @@ struct stm32_lowerhalf_s ************************************************************************************/ /* Helper functions */ -static uint16_t stm32_getreg16(struct stm32_lowerhalf_s *priv, int offset); -static void stm32_putreg16(struct stm32_lowerhalf_s *priv, int offset, uint16_t value); +static uint16_t stm32_getreg16(FAR struct stm32_lowerhalf_s *priv, int offset); +static void stm32_putreg16(FAR struct stm32_lowerhalf_s *priv, int offset, uint16_t value); static uint32_t stm32_getreg32(FAR struct stm32_lowerhalf_s *priv, int offset); static void stm32_putreg32(FAR struct stm32_lowerhalf_s *priv, int offset, uint32_t value); #if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_VERBOSE) -static void stm32_dumpregs(struct stm32_lowerhalf_s *priv, FAR const char *msg); +static void stm32_dumpregs(FAR struct stm32_lowerhalf_s *priv, FAR const char *msg); #else # define stm32_dumpregs(priv,msg) #endif @@ -313,7 +353,7 @@ static int stm32_tim8interrupt(int irq, FAR void *context); static int stm32_setup(FAR struct qe_lowerhalf_s *lower); static int stm32_shutdown(FAR struct qe_lowerhalf_s *lower); -static int stm32_position(FAR struct qe_lowerhalf_s *lower, int32_t *pos); +static int stm32_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos); static int stm32_reset(FAR struct qe_lowerhalf_s *lower); static int stm32_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned long arg); @@ -528,7 +568,7 @@ static uint16_t stm32_getreg16(struct stm32_lowerhalf_s *priv, int offset) * ************************************************************************************/ -static void stm32_putreg16(struct stm32_lowerhalf_s *priv, int offset, uint16_t value) +static void stm32_putreg16(FAR struct stm32_lowerhalf_s *priv, int offset, uint16_t value) { putreg16(value, priv->config->base + offset); } @@ -592,7 +632,7 @@ static void stm32_putreg32(FAR struct stm32_lowerhalf_s *priv, int offset, uint3 ****************************************************************************/ #if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_VERBOSE) -static void stm32_dumpregs(struct stm32_lowerhalf_s *priv, FAR const char *msg) +static void stm32_dumpregs(FAR struct stm32_lowerhalf_s *priv, FAR const char *msg) { snvdbg("%s:\n", msg); snvdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", @@ -615,8 +655,8 @@ static void stm32_dumpregs(struct stm32_lowerhalf_s *priv, FAR const char *msg) stm32_getreg16(priv, STM32_GTIM_CCR2_OFFSET), stm32_getreg16(priv, STM32_GTIM_CCR3_OFFSET), stm32_getreg16(priv, STM32_GTIM_CCR4_OFFSET)); -#if defined(CONFIG_STM32_TIM1_QENCODER) || defined(CONFIG_STM32_TIM8_QENCODER) - if (priv->timtype == TIMTYPE_ADVANCED) +#if defined(CONFIG_STM32_TIM1_QE) || defined(CONFIG_STM32_TIM8_QE) + if (priv->config->timid == 1 || priv->config->timid == 8) { snvdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", stm32_getreg16(priv, STM32_ATIM_RCR_OFFSET), @@ -819,7 +859,7 @@ static int stm32_setup(FAR struct qe_lowerhalf_s *lower) stm32_putreg32(priv, STM32_GTIM_ARR_OFFSET, 0xffff); #endif - /* Set the timerp rescaler value. The clock input value (CLKIN) is based on the + /* Set the timer prescaler value. The clock input value (CLKIN) is based on the * peripheral clock (PCLK) and a multiplier. These CLKIN values are provided in * the board.h file. The prescaler value is then that CLKIN value divided by the * configured CLKOUT value (minus one) @@ -837,7 +877,7 @@ static int stm32_setup(FAR struct qe_lowerhalf_s *lower) #endif /* Generate an update event to reload the Prescaler - * and the repetition counter(only for TIM1 and TIM8) value immediatly + * and the repetition counter (only for TIM1 and TIM8) value immediately */ stm32_putreg16(priv, STM32_GTIM_EGR_OFFSET, GTIM_EGR_UG); @@ -1090,29 +1130,15 @@ static int stm32_shutdown(FAR struct qe_lowerhalf_s *lower) /* Put the TI1 GPIO pin back to its default state */ - pincfg = priv->config->ti1cfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); - -#if defined(CONFIG_STM32_STM32F10XX) - pincfg |= (GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT); -#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) - pincfg |= (GPIO_INPUT | GPIO_FLOAT); -#else -# error "Unrecognized STM32 chip" -#endif + pincfg = priv->config->ti1cfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg |= STM32_GPIO_INPUT_FLOAT; stm32_configgpio(pincfg); /* Put the TI2 GPIO pin back to its default state */ - pincfg = priv->config->ti2cfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); - -#if defined(CONFIG_STM32_STM32F10XX) - pincfg |= (GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT); -#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) - pincfg |= (GPIO_INPUT | GPIO_FLOAT); -#else -# error "Unrecognized STM32 chip" -#endif + pincfg = priv->config->ti2cfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg |= STM32_GPIO_INPUT_FLOAT; stm32_configgpio(pincfg); return -ENOSYS; @@ -1126,7 +1152,7 @@ static int stm32_shutdown(FAR struct qe_lowerhalf_s *lower) * ************************************************************************************/ -static int stm32_position(FAR struct qe_lowerhalf_s *lower, int32_t *pos) +static int stm32_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos) { FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; #ifdef HAVE_16BIT_TIMERS diff --git a/arch/arm/src/stm32/stm32_tim_lowerhalf.c b/arch/arm/src/stm32/stm32_tim_lowerhalf.c index 8c3d5394fe1..5595e946b7f 100644 --- a/arch/arm/src/stm32/stm32_tim_lowerhalf.c +++ b/arch/arm/src/stm32/stm32_tim_lowerhalf.c @@ -2,7 +2,9 @@ * arch/arm/src/stm32/stm32_tim_lowerhalf.c * * Copyright (C) 2015 Wail Khemir. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. * Authors: Wail Khemir + * Paul Alexander Patience * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,15 +54,46 @@ #include "stm32_tim.h" #if defined(CONFIG_TIMER) && \ - (defined(CONFIG_STM32_TIM1) || defined(CONFIG_STM32_TIM2) || \ - defined(CONFIG_STM32_TIM3) || defined(CONFIG_STM32_TIM4) || \ - defined(CONFIG_STM32_TIM5) || defined(CONFIG_STM32_TIM6) || \ - defined(CONFIG_STM32_TIM7) || defined(CONFIG_STM32_TIM8)) + (defined(CONFIG_STM32_TIM1) || defined(CONFIG_STM32_TIM2) || \ + defined(CONFIG_STM32_TIM3) || defined(CONFIG_STM32_TIM4) || \ + defined(CONFIG_STM32_TIM5) || defined(CONFIG_STM32_TIM6) || \ + defined(CONFIG_STM32_TIM7) || defined(CONFIG_STM32_TIM8) || \ + defined(CONFIG_STM32_TIM9) || defined(CONFIG_STM32_TIM10) || \ + defined(CONFIG_STM32_TIM11) || defined(CONFIG_STM32_TIM12) || \ + defined(CONFIG_STM32_TIM13) || defined(CONFIG_STM32_TIM14)) /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#define STM32_TIM1_RES 16 +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) +# define STM32_TIM2_RES 16 +#else +# define STM32_TIM2_RES 32 +#endif +#if defined(CONFIG_STM32_STM32L20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_TIM3_RES 32 +# define STM32_TIM4_RES 32 +#else +# define STM32_TIM3_RES 16 +# define STM32_TIM4_RES 16 +#endif +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define STM32_TIM5_RES 16 +#else +# define STM32_TIM5_RES 32 +#endif +#define STM32_TIM6_RES 16 +#define STM32_TIM7_RES 16 +#define STM32_TIM8_RES 16 +#define STM32_TIM9_RES 16 +#define STM32_TIM10_RES 16 +#define STM32_TIM11_RES 16 +#define STM32_TIM12_RES 16 +#define STM32_TIM13_RES 16 +#define STM32_TIM14_RES 16 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -71,23 +104,18 @@ struct stm32_lowerhalf_s { - const struct timer_ops_s *ops; /* Lower half operations */ - struct stm32_tim_dev_s *tim; /* stm32 timer driver */ - tccb_t handlerUsr; /* Current user interrupt handler */ - const xcpt_t handlerTim; /* Current timer interrupt handler */ - bool started; /* True: Timer has been started */ - const uint8_t timerResolution; /* number of bits in the timer (16 or 32 bits) */ + FAR const struct timer_ops_s *ops; /* Lower half operations */ + FAR struct stm32_tim_dev_s *tim; /* stm32 timer driver */ + tccb_t usrhandler; /* Current user interrupt handler */ + const xcpt_t timhandler; /* Current timer interrupt handler */ + bool started; /* True: Timer has been started */ + const uint8_t resolution; /* Number of bits in the timer (16 or 32 bits) */ }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -/* Helper functions *********************************************************/ - -static struct stm32_lowerhalf_s *stm32_get_lowerhalf(int timer); -static xcpt_t stm32_get_interrupt(int timer); - /* Interrupt handling *******************************************************/ #ifdef CONFIG_STM32_TIM1 @@ -133,15 +161,15 @@ static int stm32_tim13_interrupt(int irq, FAR void *context); static int stm32_tim14_interrupt(int irq, FAR void *context); #endif -static int stm32_timer_handler(struct stm32_lowerhalf_s *attr); +static int stm32_timer_handler(FAR struct stm32_lowerhalf_s *lower); /* "Lower half" driver methods **********************************************/ -static int stm32_start(struct timer_lowerhalf_s *lower); -static int stm32_stop(struct timer_lowerhalf_s *lower); -static int stm32_settimeout(struct timer_lowerhalf_s *lower, +static int stm32_start(FAR struct timer_lowerhalf_s *lower); +static int stm32_stop(FAR struct timer_lowerhalf_s *lower); +static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, uint32_t timeout); -static tccb_t stm32_sethandler(struct timer_lowerhalf_s *lower, +static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower, tccb_t handler); /**************************************************************************** @@ -153,153 +181,135 @@ static const struct timer_ops_s g_timer_ops = { .start = stm32_start, .stop = stm32_stop, - .getstatus = 0, + .getstatus = NULL, .settimeout = stm32_settimeout, .sethandler = stm32_sethandler, - .ioctl = 0, + .ioctl = NULL, }; #ifdef CONFIG_STM32_TIM1 -static struct stm32_lowerhalf_s g_tim1_lowerHalf = +static struct stm32_lowerhalf_s g_tim1_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim1_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim1_interrupt, + .resolution = STM32_TIM1_RES, }; #endif #ifdef CONFIG_STM32_TIM2 -static struct stm32_lowerhalf_s g_tim2_lowerHalf = +static struct stm32_lowerhalf_s g_tim2_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim2_interrupt, -#ifdef CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F205 || CONFIG_STM32_STM32F207 || \ - CONFIG_STM32_STM32F30XX || CONFIG_STM32_STM32F37XX || \ - CONFIG_STM32_STM32F40XX || CONFIG_STM32_STM32F401 || CONFIG_STM32_STM32F411 || \ - CONFIG_STM32_STM32F405 || CONFIG_STM32_STM32F407 || CONFIG_STM32_STM32F427 || \ - CONFIG_STM32_STM32F429 || CONFIG_STM32_STM32F446 - - .timerResolution = 32, -#else - .timerResolution = 16, -#endif + .ops = &g_timer_ops, + .timhandler = stm32_tim2_interrupt, + .resolution = STM32_TIM2_RES, }; #endif #ifdef CONFIG_STM32_TIM3 -static struct stm32_lowerhalf_s g_tim3_lowerHalf = +static struct stm32_lowerhalf_s g_tim3_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim3_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim3_interrupt, + .resolution = STM32_TIM3_RES, }; #endif #ifdef CONFIG_STM32_TIM4 -static struct stm32_lowerhalf_s g_tim4_lowerHalf = +static struct stm32_lowerhalf_s g_tim4_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim4_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim4_interrupt, + .resolution = STM32_TIM4_RES, }; #endif #ifdef CONFIG_STM32_TIM5 -static struct stm32_lowerhalf_s g_tim5_lowerHalf = +static struct stm32_lowerhalf_s g_tim5_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim5_interrupt, -#ifdef CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F205 || CONFIG_STM32_STM32F207 || \ - CONFIG_STM32_STM32F37XX || \ - CONFIG_STM32_STM32F40XX || CONFIG_STM32_STM32F401 || CONFIG_STM32_STM32F411 || \ - CONFIG_STM32_STM32F405 || CONFIG_STM32_STM32F407 || CONFIG_STM32_STM32F427 || \ - CONFIG_STM32_STM32F429 || CONFIG_STM32_STM32F446 - - .timerResolution = 32, -#else - .timerResolution = 16, -#endif + .ops = &g_timer_ops, + .timhandler = stm32_tim5_interrupt, + .resolution = STM32_TIM5_RES, }; #endif #ifdef CONFIG_STM32_TIM6 -static struct stm32_lowerhalf_s g_tim6_lowerHalf = +static struct stm32_lowerhalf_s g_tim6_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim6_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim6_interrupt, + .resolution = STM32_TIM6_RES, }; #endif #ifdef CONFIG_STM32_TIM7 -static struct stm32_lowerhalf_s g_tim7_lowerHalf = +static struct stm32_lowerhalf_s g_tim7_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim7_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim7_interrupt, + .resolution = STM32_TIM7_RES, }; #endif #ifdef CONFIG_STM32_TIM8 -static struct stm32_lowerhalf_s g_tim8_lowerHalf = +static struct stm32_lowerhalf_s g_tim8_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim8_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim8_interrupt, + .resolution = STM32_TIM8_RES, }; #endif #ifdef CONFIG_STM32_TIM9 -static struct stm32_lowerhalf_s g_tim9_lowerHalf = +static struct stm32_lowerhalf_s g_tim9_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim9_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim9_interrupt, + .resolution = STM32_TIM9_RES, }; #endif #ifdef CONFIG_STM32_TIM10 -static struct stm32_lowerhalf_s g_tim10_lowerHalf = +static struct stm32_lowerhalf_s g_tim10_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim10_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim10_interrupt, + .resolution = STM32_TIM10_RES, }; #endif #ifdef CONFIG_STM32_TIM11 -static struct stm32_lowerhalf_s g_tim11_lowerHalf = +static struct stm32_lowerhalf_s g_tim11_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim11_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim11_interrupt, + .resolution = STM32_TIM11_RES, }; #endif #ifdef CONFIG_STM32_TIM12 -static struct stm32_lowerhalf_s g_tim12_lowerHalf = +static struct stm32_lowerhalf_s g_tim12_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim12_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim12_interrupt, + .resolution = STM32_TIM12_RES, }; #endif #ifdef CONFIG_STM32_TIM13 -static struct stm32_lowerhalf_s g_tim13_lowerHalf = +static struct stm32_lowerhalf_s g_tim13_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim13_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim13_interrupt, + .resolution = STM32_TIM13_RES, }; #endif #ifdef CONFIG_STM32_TIM14 -static struct stm32_lowerhalf_s g_tim14_lowerHalf = +static struct stm32_lowerhalf_s g_tim14_lowerhalf = { - .ops = &g_timer_ops, - .handlerTim = stm32_tim14_interrupt, - .timerResolution = 16, + .ops = &g_timer_ops, + .timhandler = stm32_tim14_interrupt, + .resolution = STM32_TIM14_RES, }; #endif @@ -307,103 +317,6 @@ static struct stm32_lowerhalf_s g_tim14_lowerHalf = * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: stm32_get_lowerhalf - * - * Description: - * Get the lower half timer structure of the corresponding timer - * - * Input Parameters: - * timer - the timer's number - * - * Returned Values: - * A pointer to the lower half structure on success, NULL on failure - * - ****************************************************************************/ - -static struct stm32_lowerhalf_s *stm32_get_lowerhalf(int timer) -{ - struct stm32_lowerhalf_s *lower; - - switch (timer) - { -#ifdef CONFIG_STM32_TIM1 - case 1: - lower = &g_tim1_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM2 - case 2: - lower = &g_tim2_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM3 - case 3: - lower = &g_tim3_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM4 - case 4: - lower = &g_tim4_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM5 - case 5: - lower = &g_tim5_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM6 - case 6: - lower = &g_tim6_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM7 - case 7: - lower = &g_tim7_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM8 - case 8: - lower = &g_tim8_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM9 - case 9: - lower = &g_tim9_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM10 - case 10: - lower = &g_tim10_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM11 - case 11: - lower = &g_tim11_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM12 - case 12: - lower = &g_tim12_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM13 - case 13: - lower = &g_tim13_lowerHalf; - break; -#endif -#ifdef CONFIG_STM32_TIM14 - case 14: - lower = &g_tim14_lowerHalf; - break; -#endif - default: - lower = 0; - } - - return lower; -} - /**************************************************************************** * Name: stm32_timN_interrupt, N=1..14 * @@ -415,98 +328,98 @@ static struct stm32_lowerhalf_s *stm32_get_lowerhalf(int timer) #ifdef CONFIG_STM32_TIM1 static int stm32_tim1_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim1_lowerHalf); + return stm32_timer_handler(&g_tim1_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM2 static int stm32_tim2_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim2_lowerHalf); + return stm32_timer_handler(&g_tim2_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM3 static int stm32_tim3_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim3_lowerHalf); + return stm32_timer_handler(&g_tim3_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM4 static int stm32_tim4_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim4_lowerHalf); + return stm32_timer_handler(&g_tim4_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM5 static int stm32_tim5_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim5_lowerHalf); + return stm32_timer_handler(&g_tim5_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM6 static int stm32_tim6_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim6_lowerHalf); + return stm32_timer_handler(&g_tim6_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM7 static int stm32_tim7_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim7_lowerHalf); + return stm32_timer_handler(&g_tim7_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM8 static int stm32_tim8_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim8_lowerHalf); + return stm32_timer_handler(&g_tim8_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM9 static int stm32_tim9_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim9_lowerHalf); + return stm32_timer_handler(&g_tim9_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM10 static int stm32_tim10_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim10_lowerHalf); + return stm32_timer_handler(&g_tim10_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM11 static int stm32_tim11_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim11_lowerHalf); + return stm32_timer_handler(&g_tim11_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM12 static int stm32_tim12_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim12_lowerHalf); + return stm32_timer_handler(&g_tim12_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM13 static int stm32_tim13_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim13_lowerHalf); + return stm32_timer_handler(&g_tim13_lowerhalf); } #endif #ifdef CONFIG_STM32_TIM14 static int stm32_tim14_interrupt(int irq, FAR void *context) { - return stm32_timer_handler(&g_tim14_lowerHalf); + return stm32_timer_handler(&g_tim14_lowerhalf); } #endif @@ -522,14 +435,13 @@ static int stm32_tim14_interrupt(int irq, FAR void *context) * ****************************************************************************/ -static int stm32_timer_handler(struct stm32_lowerhalf_s *lower) +static int stm32_timer_handler(FAR struct stm32_lowerhalf_s *lower) { + uint32_t next_interval_us = 0; + STM32_TIM_ACKINT(lower->tim, 0); - uint32_t next_interval_us = 0; - bool ret = (*lower->handlerUsr)(&next_interval_us); - - if (ret == true) + if (lower->usrhandler(&next_interval_us)) { if (next_interval_us > 0) { @@ -538,10 +450,10 @@ static int stm32_timer_handler(struct stm32_lowerhalf_s *lower) } else { - stm32_stop(lower); + stm32_stop((struct timer_lowerhalf_s *)lower); } - return 0; + return OK; } /**************************************************************************** @@ -559,17 +471,17 @@ static int stm32_timer_handler(struct stm32_lowerhalf_s *lower) * ****************************************************************************/ -static int stm32_start(struct timer_lowerhalf_s *lower) +static int stm32_start(FAR struct timer_lowerhalf_s *lower) { - struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; if (!priv->started) { STM32_TIM_SETMODE(priv->tim, STM32_TIM_MODE_UP); - if (priv->handlerUsr) + if (priv->usrhandler != NULL) { - STM32_TIM_SETISR(priv->tim, priv->handlerTim, 0); + STM32_TIM_SETISR(priv->tim, priv->timhandler, 0); STM32_TIM_ENABLEINT(priv->tim, 0); } @@ -631,21 +543,22 @@ static int stm32_stop(struct timer_lowerhalf_s *lower) * ****************************************************************************/ -static int stm32_settimeout(struct timer_lowerhalf_s *lower, uint32_t timeout) +static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, uint32_t timeout) { - struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint64_t maxtimeout; if (priv->started) { return -EPERM; } - uint64_t maxTimeout = (1 << priv->timerResolution) - 1; - if(timeout > maxTimeout) + maxtimeout = (1 << priv->resolution) - 1; + if (timeout > maxtimeout) { - uint64_t freq = (maxTimeout * 1000000) / timeout; + uint64_t freq = (maxtimeout * 1000000) / timeout; STM32_TIM_SETCLOCK(priv->tim, freq); - STM32_TIM_SETPERIOD(priv->tim, maxTimeout); + STM32_TIM_SETPERIOD(priv->tim, maxtimeout); } else { @@ -675,24 +588,24 @@ static int stm32_settimeout(struct timer_lowerhalf_s *lower, uint32_t timeout) * ****************************************************************************/ -static tccb_t stm32_sethandler(struct timer_lowerhalf_s *lower, +static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower, tccb_t newhandler) { - struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; irqstate_t flags = irqsave(); /* Get the old handler return value */ - tccb_t oldhandler = priv->handlerUsr; + tccb_t oldhandler = priv->usrhandler; /* Save the new handler */ - priv->handlerUsr = newhandler; + priv->usrhandler = newhandler; - if (newhandler && priv->started) + if (newhandler != NULL && priv->started) { - STM32_TIM_SETISR(priv->tim, priv->handlerTim, 0); + STM32_TIM_SETISR(priv->tim, priv->timhandler, 0); STM32_TIM_ENABLEINT(priv->tim, 0); } else @@ -729,19 +642,91 @@ static tccb_t stm32_sethandler(struct timer_lowerhalf_s *lower, int stm32_timer_initialize(FAR const char *devpath, int timer) { - struct stm32_lowerhalf_s *lower = stm32_get_lowerhalf(timer); - if(!lower) + FAR struct stm32_lowerhalf_s *lower; + + switch (timer) { - return -ENODEV; +#ifdef CONFIG_STM32_TIM1 + case 1: + lower = &g_tim1_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM2 + case 2: + lower = &g_tim2_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case 3: + lower = &g_tim3_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case 4: + lower = &g_tim4_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case 5: + lower = &g_tim5_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM6 + case 6: + lower = &g_tim6_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM7 + case 7: + lower = &g_tim7_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM8 + case 8: + lower = &g_tim8_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM9 + case 9: + lower = &g_tim9_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM10 + case 10: + lower = &g_tim10_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM11 + case 11: + lower = &g_tim11_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM12 + case 12: + lower = &g_tim12_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM13 + case 13: + lower = &g_tim13_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM14 + case 14: + lower = &g_tim14_lowerhalf; + break; +#endif + default: + return -ENODEV; } /* Initialize the elements of lower half state structure */ lower->started = false; - lower->handlerUsr = 0; + lower->usrhandler = NULL; lower->tim = stm32_tim_init(timer); - if (!lower->tim) + if (lower->tim == NULL) { return -EINVAL; } @@ -751,8 +736,9 @@ int stm32_timer_initialize(FAR const char *devpath, int timer) * REVISIT: The returned handle is discard here. */ - void *drvr = timer_register(devpath, (struct timer_lowerhalf_s *)lower); - if (!drvr) + FAR void *drvr = timer_register(devpath, + (FAR struct timer_lowerhalf_s *)lower); + if (drvr == NULL) { /* The actual cause of the failure may have been a failure to allocate * perhaps a failure to register the timer driver (such as if the diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index 1fa9d5de13e..3239f8d725b 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -99,7 +99,9 @@ endif endif ifeq ($(CONFIG_ELF),y) -CMN_CSRCS += up_elf.c +CMN_CSRCS += up_elf.c up_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c endif ifeq ($(CONFIG_STACK_COLORATION),y) diff --git a/arch/arm/src/stm32f7/stm32_irq.c b/arch/arm/src/stm32f7/stm32_irq.c index 12446fc69b0..481417a68f4 100644 --- a/arch/arm/src/stm32f7/stm32_irq.c +++ b/arch/arm/src/stm32f7/stm32_irq.c @@ -481,7 +481,7 @@ void up_irqinitialize(void) * Fault handler. */ -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU irq_attach(STM32_IRQ_MEMFAULT, up_memfault); up_enable_irq(STM32_IRQ_MEMFAULT); #endif @@ -490,7 +490,7 @@ void up_irqinitialize(void) #ifdef CONFIG_DEBUG irq_attach(STM32_IRQ_NMI, stm32_nmi); -#ifndef CONFIG_ARMV7M_MPU +#ifndef CONFIG_ARM_MPU irq_attach(STM32_IRQ_MEMFAULT, up_memfault); #endif irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault); diff --git a/arch/arm/src/stm32f7/stm32_mpuinit.c b/arch/arm/src/stm32f7/stm32_mpuinit.c index 60f0c69dc1e..096742a0ecc 100644 --- a/arch/arm/src/stm32f7/stm32_mpuinit.c +++ b/arch/arm/src/stm32f7/stm32_mpuinit.c @@ -46,7 +46,7 @@ #include "mpu.h" #include "stm32_mpuinit.h" -#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARMV7M_MPU) +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) /**************************************************************************** * Pre-processor Definitions @@ -112,5 +112,5 @@ void stm32_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 */ diff --git a/arch/arm/src/str71x/Make.defs b/arch/arm/src/str71x/Make.defs index 00ce4a36254..00db6c3b8f0 100644 --- a/arch/arm/src/str71x/Make.defs +++ b/arch/arm/src/str71x/Make.defs @@ -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) diff --git a/arch/arm/src/tiva/Make.defs b/arch/arm/src/tiva/Make.defs index bd417ea9dcb..b8cb81e7e6d 100644 --- a/arch/arm/src/tiva/Make.defs +++ b/arch/arm/src/tiva/Make.defs @@ -71,6 +71,8 @@ endif ifeq ($(CONFIG_ELF),y) CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c endif CHIP_ASRCS = diff --git a/arch/arm/src/tiva/tiva_irq.c b/arch/arm/src/tiva/tiva_irq.c index 5ea559e4cd4..4cc712dc6a0 100644 --- a/arch/arm/src/tiva/tiva_irq.c +++ b/arch/arm/src/tiva/tiva_irq.c @@ -465,7 +465,7 @@ void up_irqinitialize(void) * Fault handler. */ -#ifdef CONFIG_ARMV7M_MPU +#ifdef CONFIG_ARM_MPU irq_attach(TIVA_IRQ_MEMFAULT, up_memfault); up_enable_irq(TIVA_IRQ_MEMFAULT); #endif @@ -474,7 +474,7 @@ void up_irqinitialize(void) #ifdef CONFIG_DEBUG irq_attach(TIVA_IRQ_NMI, tiva_nmi); -#ifndef CONFIG_ARMV7M_MPU +#ifndef CONFIG_ARM_MPU irq_attach(TIVA_IRQ_MEMFAULT, up_memfault); #endif irq_attach(TIVA_IRQ_BUSFAULT, tiva_busfault); diff --git a/arch/arm/src/tiva/tiva_mpuinit.c b/arch/arm/src/tiva/tiva_mpuinit.c index a1fe80d86e2..a9a6aed9a21 100644 --- a/arch/arm/src/tiva/tiva_mpuinit.c +++ b/arch/arm/src/tiva/tiva_mpuinit.c @@ -46,7 +46,7 @@ #include "mpu.h" #include "tiva_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 tiva_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 */ diff --git a/arch/arm/src/tms570/Kconfig b/arch/arm/src/tms570/Kconfig new file mode 100644 index 00000000000..5425a91e118 --- /dev/null +++ b/arch/arm/src/tms570/Kconfig @@ -0,0 +1,93 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_TMS570 + +comment "TMS570 Configuration Options" + +# Chip Capabilities + +# Summary Configurations + +# Chip Selection + +choice + prompt "TI TMS570 Chip Selection" + default ARCH_CHIP_TMS570LS1227ZWT + +config ARCH_CHIP_TMS570LS0232PZ + bool "TI TMS570LS0232PZ" + select ARCH_CORTEXR4 + +config ARCH_CHIP_TMS570LS0332PZ + bool "TI TMS570LS0332PZ" + select ARCH_CORTEXR4 + +config ARCH_CHIP_TMS570LS0432PZ + bool "TI TMS570LS0432PZ" + select ARCH_CORTEXR4 + +config ARCH_CHIP_TMS570LS0714PZ + bool "TI TMS570LS0714PZ" + select ARCH_CORTEXR4F + +config ARCH_CHIP_TMS570LS0714PGE + bool "TI TMS570LS0714PGE" + select ARCH_CORTEXR4F + +config ARCH_CHIP_TMS570LS0714ZWT + bool "TI TMS570LS0714ZWT" + select ARCH_CORTEXR4F + +config ARCH_CHIP_TMS570LS1227ZWT + bool "TI TMS570LS1227ZWT" + select ARCH_CORTEXR4F + +endchoice # TI TMS570 Chip Selection + +menu "TMS570 Peripheral Support" + +config TMS570_MIBADC + bool "MibADC" + default n + +config TMS570_DCAN1 + bool "Controller Area Network 1 (DCAN1)" + default n + +config TMS570_DCAN2 + bool "Controller Area Network 1 (DCAN2)" + default n + +config TMS570_QEP + bool "Enhanced Quadrature Encoder Unit (eQEP)" + default n + +config TMS570_N2HET + bool "High-End Timer (N2HET)" + default n + +config TMS570_DCAN1 + bool "Controller Area Network 1 (D" + default n + +config TMS570_MIBASPI1 + bool "Multi-Buffered Serial Peripheral Interface Module (MibSPI1)" + default n + +config TMS570_SCI1 + bool "Serial Communication Interface 1 (SCI1)" + default n + select ARCH_HAVE_SCI1 + +endmenu # TMS570 Peripheral Support + +config TMS570_SELFTEST + bool "Power-on Selftest" + default n + ---help--- + Enable power-on self-test of memories and ECC logic. + +endif # ARCH_CHIP_TMS570 diff --git a/arch/arm/src/tms570/Make.defs b/arch/arm/src/tms570/Make.defs new file mode 100644 index 00000000000..c1e97b9aa8d --- /dev/null +++ b/arch/arm/src/tms570/Make.defs @@ -0,0 +1,108 @@ +############################################################################ +# arch/arm/tms570/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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 Gregory Nutt 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. +# +############################################################################ + +# The vector table is the "head" object, i.e., the one that must forced into +# the link in order to draw in all of the other components + +HEAD_ASRC = arm_vectortab.S + +# Common assembly language files + +CMN_ASRCS += arm_vectors.S arm_fpuconfig.S arm_head.S arm_fullcontextrestore.S +CMN_ASRCS += arm_saveusercontext.S arm_vectoraddrexcptn.S arm_vfork.S +CMN_ASRCS += cp15_coherent_dcache.S cp15_invalidate_dcache.S +CMN_ASRCS += cp15_clean_dcache.S cp15_flush_dcache.S cp15_invalidate_dcache_all.S + +# Configuration dependent assembly language files + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += arm_memcpy.S +endif + +# Common C source files + +CMN_CSRCS = up_allocateheap.c up_initialize.c up_idle.c up_interruptcontext.c +CMN_CSRCS += up_exit.c up_createstack.c up_releasestack.c up_usestack.c +CMN_CSRCS += up_vfork.c up_puts.c up_mdelay.c up_stackframe.c up_udelay.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c + +CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c +CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_prefetchabort.c +CMN_CSRCS += arm_releasepending.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c +CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c + +# Configuration dependent C files + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += arm_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += arm_signal_dispatch.c +CMN_UASRCS += arm_signal_handler.S +endif +endif + +ifeq ($(CONFIG_ARMV7R_L2CC_PL310),y) +CMN_CSRCS += arm_l2cc_pl310.c +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) +CMN_ASRCS += arm_savefpu.S arm_restorefpu.S +CMN_CSRCS += arm_copyarmstate.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# SAMA5-specific assembly language files + +CHIP_ASRCS = + +# SAMA5-specific C source files + +CHIP_CSRCS = tms570_boot.c tms570_clockconfig.c tms570_irq.c + +# Configuration dependent C and assembly language files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += tms570_timerisr.c +endif diff --git a/arch/arm/src/tms570/chip.h b/arch/arm/src/tms570/chip.h new file mode 100644 index 00000000000..c4da84da7ab --- /dev/null +++ b/arch/arm/src/tms570/chip.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/tms570/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_TMS570_CHIP_H +#define __ARCH_ARM_SRC_TMS570_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/tms570_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* arch/arm/src/armv7-a/l2cc_pl310.h includes this file and expects it to provide the + * address of the L2CC-PL310 implementation. + */ + +#define L2CC_VBASE SAM_L2CC_VSECTION + +/* Cache line sizes (in bytes)for the SAVA5Dx */ + +#define ARMV7A_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARMV7A_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_H */ diff --git a/arch/arm/src/tms570/chip/tms570_esm.h b/arch/arm/src/tms570/chip/tms570_esm.h new file mode 100644 index 00000000000..450c469fdf7 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_esm.h @@ -0,0 +1,201 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_esm.h + * Error Signalling Module Error Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_ESM_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_ESM_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +#define ESM_GROUP1 0 +#define ESM_GROUP2 1 +#define ESM_GROUP3 2 + +/* Register Offsets *********************************************************************************/ + +#define TMS570_ESM_EEPAPR1_OFFSET 0x0000 /* ESM Enable ERROR Pin Action/Response Register 1 */ +#define TMS570_ESM_DEPAPR1_OFFSET 0x0004 /* ESM Disable ERROR Pin Action/Response Register 1 */ +#define TMS570_ESM_IESR1_OFFSET 0x0008 /* ESM Interrupt Enable Set/Status Register 1 */ +#define TMS570_ESM_IECR1_OFFSET 0x000c /* ESM Interrupt Enable Clear/Status Register 1 */ +#define TMS570_ESM_ILSR1_OFFSET 0x0010 /* Interrupt Level Set/Status Register 1 */ +#define TMS570_ESM_ILCR1_OFFSET 0x0014 /* Interrupt Level Clear/Status Register 1 */ +#define TMS570_ESM_SR_OFFSET(n) (0x0018 + ((n) << 2)) /* n=0, 1, 2 */ +# define TMS570_ESM_SR1_OFFSET 0x0018 /* ESM Status Register for group 1 */ +# define TMS570_ESM_SR2_OFFSET 0x001c /* ESM Status Register for group 2 */ +# define TMS570_ESM_SR3_OFFSET 0x0020 /* ESM Status Register for group 3 */ +#define TMS570_ESM_EPSR_OFFSET 0x0024 /* ESM ERROR Pin Status Register */ +#define TMS570_ESM_IOFFHR_OFFSET 0x0028 /* ESM Interrupt Offset High Register */ +#define TMS570_ESM_IOFFLR_OFFSET 0x002c /* ESM Interrupt Offset Low Register */ +#define TMS570_ESM_LTCR_OFFSET 0x0030 /* ESM Low-Time Counter Register Section */ +#define TMS570_ESM_LTCPR_OFFSET 0x0034 /* ESM Low-Time Counter Preload Register */ +#define TMS570_ESM_EKR_OFFSET 0x0038 /* ESM Error Key Register */ +#define TMS570_ESM_SSR2_OFFSET 0x003c /* ESM Status Shadow Register 2 */ +#define TMS570_ESM_IEPSR4_OFFSET 0x0040 /* ESM Influence ERROR Pin Set/Status Register 4 */ +#define TMS570_ESM_IEPCR4_OFFSET 0x0044 /* ESM Influence ERROR Pin Clear/Status Register 4 */ +#define TMS570_ESM_IESR4_OFFSET 0x0048 /* ESM Interrupt Enable Set/Status Register 4 */ +#define TMS570_ESM_IECR4_OFFSET 0x004c /* ESM Interrupt Enable Clear/Status Register 4 */ +#define TMS570_ESM_ILSR4_OFFSET 0x0050 /* Interrupt Level Set/Status Register 4 */ +#define TMS570_ESM_ILCR4_OFFSET 0x0054 /* Interrupt Level Clear/Status Register 4 */ +#define TMS570_ESM_SR4_OFFSET 0x0058 /* ESM Status Register 4 */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_ESM_EEPAPR1 (TMS570_ESM_BASE+TMS570_ESM_EEPAPR1_OFFSET) +#define TMS570_ESM_DEPAPR1 (TMS570_ESM_BASE+TMS570_ESM_DEPAPR1_OFFSET) +#define TMS570_ESM_IESR1 (TMS570_ESM_BASE+TMS570_ESM_IESR1_OFFSET) +#define TMS570_ESM_IECR1 (TMS570_ESM_BASE+TMS570_ESM_IECR1_OFFSET) +#define TMS570_ESM_ILSR1 (TMS570_ESM_BASE+TMS570_ESM_ILSR1_OFFSET) +#define TMS570_ESM_ILCR1 (TMS570_ESM_BASE+TMS570_ESM_ILCR1_OFFSET) +#define TMS570_ESM_SR(n) (TMS570_ESM_BASE+TMS570_ESM_SR_OFFSET(n)) +# define TMS570_ESM_SR1 (TMS570_ESM_BASE+TMS570_ESM_SR1_OFFSET) +# define TMS570_ESM_SR2 (TMS570_ESM_BASE+TMS570_ESM_SR2_OFFSET) +# define TMS570_ESM_SR3 (TMS570_ESM_BASE+TMS570_ESM_SR3_OFFSET) +#define TMS570_ESM_EPSR (TMS570_ESM_BASE+TMS570_ESM_EPSR_OFFSET) +#define TMS570_ESM_IOFFHR (TMS570_ESM_BASE+TMS570_ESM_IOFFHR_OFFSET) +#define TMS570_ESM_IOFFLR (TMS570_ESM_BASE+TMS570_ESM_IOFFLR_OFFSET) +#define TMS570_ESM_LTCR (TMS570_ESM_BASE+TMS570_ESM_LTCR_OFFSET) +#define TMS570_ESM_LTCPR (TMS570_ESM_BASE+TMS570_ESM_LTCPR_OFFSET) +#define TMS570_ESM_EKR (TMS570_ESM_BASE+TMS570_ESM_EKR_OFFSET) +#define TMS570_ESM_SSR2 (TMS570_ESM_BASE+TMS570_ESM_SSR2_OFFSET) +#define TMS570_ESM_IEPSR4 (TMS570_ESM_BASE+TMS570_ESM_IEPSR4_OFFSET) +#define TMS570_ESM_IEPCR4 (TMS570_ESM_BASE+TMS570_ESM_IEPCR4_OFFSET) +#define TMS570_ESM_IESR4 (TMS570_ESM_BASE+TMS570_ESM_IESR4_OFFSET) +#define TMS570_ESM_IECR4 (TMS570_ESM_BASE+TMS570_ESM_IECR4_OFFSET) +#define TMS570_ESM_ILSR4 (TMS570_ESM_BASE+TMS570_ESM_ILSR4_OFFSET) +#define TMS570_ESM_ILCR4 (TMS570_ESM_BASE+TMS570_ESM_ILCR4_OFFSET) +#define TMS570_ESM_SR4 (TMS570_ESM_BASE+TMS570_ESM_SR4_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* ESM Enable ERROR Pin Action/Response Register 1 */ + +#define ESM_EEPAPR1_CHAN(n) (1 << (n)) /* Bit n: Channel n enable */ + +/* ESM Disable ERROR Pin Action/Response Register 1 */ + +#define ESM_DEPAPR1_CHAN(n) (1 << (n)) /* Bit n: Channel n disable */ + +/* ESM Interrupt Enable Set/Status Register 1 */ + +#define ESM_IESR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt enable */ + +/* ESM Interrupt Enable Clear/Status Register 1 */ + +#define ESM_IECR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt clear */ + +/* Interrupt Level Set/Status Register 1 */ + +#define ESM_ILSR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt level high */ + +/* Interrupt Level Clear/Status Register 1 */ + +#define ESM_ILCR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt level low (write) */ + +/* ESM Status Register for groups 1, 2, 3, and 4 */ + +#define ESM_SR_PENDING(n) (1 << (n)) /* Bit n: Channel n error interrupt pending (read) */ +#define ESM_SR_CLEAR(n) (1 << (n)) /* Bit n: Channel n error interrupt clear (write) */ + +/* ESM ERROR Pin Status Register */ + +#define ESM_EPSR_NOERROR(n) (1 << (n)) /* Bit n: Channel n no error (read) */ + +/* ESM Interrupt Offset High Register */ + +#define ESM_IOFFHR_MASK 0x0000007f /* Bits 0-6: Interrupt offset high level */ + +/* ESM Interrupt Offset Low Register */ + +#define ESM_IOFFLR_MASK 0x0000007f /* Bits 0-6: Interrupt offset low level */ + +/* ESM Low-Time Counter Register Section */ + +#define ESM_LTCR_MASK 0x0000ffff /* Bits 0-15: ERROR pin low time counter */ + +/* ESM Low-Time Counter Preload Register */ + +#define ESM_LTCPR_MASK 0x0000ffff /* Bits 0-15: ERROR pin low time counter pre-load */ + +/* ESM Error Key Register */ + +#define ESM_EKR_MASK 0x0000000f /* Bits 0-3: Error key value */ +# define ESM_EKR_NORMAL 0x00000000 /* Activates normal mode */ +# define ESM_EKR_ERROR 0x00000005 /* nERROR set high when LTC completes */ +# define ESM_EKR_FORCE 0x0000000a /* Forces error on nERROR pin */ + +/* ESM Status Shadow Register 2 */ + +#define ESM_SSR2_ERROR(n) (1 << (n)) /* Bit n: Channel n error occurred (read) */ +#define ESM_SSR2_CLEAR(n) (1 << (n)) /* Bit n: Channel n error clear (write) */ + +/* ESM Influence ERROR Pin Set/Status Register 4 */ + +#define ESM_IEPSR4_CHAN(n) (1 << (n)) /* Bit n: Channel n read failure enable */ + +/* ESM Influence ERROR Pin Clear/Status Register 4 */ + +#define ESM_IEPCR4_CHAN(n) (1 << (n)) /* Bit n: Channel n read failure disable */ + +/* ESM Interrupt Enable Set/Status Register 4 */ + +#define ESM_IESR4_CHAN(n) (1 << (n)) /* Bit n: Channel n interrupt enable */ + +/* ESM Interrupt Enable Clear/Status Register 4 */ + +#define ESM_IECR4_CHAN(n) (1 << (n)) /* Bit n: Channel n interrupt disable */ + +/* Interrupt Level Set/Status Register 4 */ + +#define ESM_ILSR4_CHAN(n) (1 << (n)) /* Bit n: Maps channel n high level interrupt */ + +/* Interrupt Level Clear/Status Register 4 */ + +#define ESM_ILCR4_CHAN(n) (1 << (n)) /* Bit n: Maps channel n low level interrupt */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_ESM_H */ diff --git a/arch/arm/src/tms570/chip/tms570_flash.h b/arch/arm/src/tms570/chip/tms570_flash.h new file mode 100644 index 00000000000..d1b14666760 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_flash.h @@ -0,0 +1,271 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_flash.h + * FLASH Module Controller Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_FLASH_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_FLASH_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_FLASH_FRDCNTL_OFFSET 0x000 /* Flash Option Control Register */ +#define TMS570_FLASH_FEDACTRL1_OFFSET 0x008 /* Flash Error Detection and Correction Control Register 1 */ +#define TMS570_FLASH_FEDACTRL2_OFFSET 0x00c /* Flash Error Detection and Correction Control Register 2 */ +#define TMS570_FLASH_FCORERRCNT_OFFSET 0x010 /* Flash Correctable Error Count Register */ +#define TMS570_FLASH_FCORERRADD_OFFSET 0x014 /* Flash Correctable Error Address Register */ +#define TMS570_FLASH_FCORERRPOS_OFFSET 0x018 /* Flash Correctable Error Position Register */ +#define TMS570_FLASH_FEDACSTATUS_OFFSET 0x01c /* Flash Error Detection and Correction Status Register */ +#define TMS570_FLASH_FUNCERRADD_OFFSET 0x020 /* Flash Un-Correctable Error Address Register */ +#define TMS570_FLASH_FEDACSDIS_OFFSET 0x024 /* Flash Error Detection and Correction Sector Disable Register */ +#define TMS570_FLASH_FPRIMADDTAG_OFFSET 0x028 /* Flash Primary Address Tag Register */ +#define TMS570_FLASH_FDUPDDTAG_OFFSET 0x02c /* Flash Duplicate Address Tag Register */ +#define TMS570_FLASH_FBPROT_OFFSET 0x030 /* Flash Bank Protection Register */ +#define TMS570_FLASH_FBSE_OFFSET 0x034 /* Flash Bank Sector Enable Register */ +#define TMS570_FLASH_FBBUSY_OFFSET 0x038 /* Flash Bank Busy Register */ +#define TMS570_FLASH_FBAC_OFFSET 0x03c /* Flash Bank Access Control Register */ +#define TMS570_FLASH_FBFALLBACK_OFFSET 0x040 /* Flash Bank Fallback Power Register */ +#define TMS570_FLASH_FBPRDY_OFFSET 0x044 /* Flash Bank/Pump Ready Register */ +#define TMS570_FLASH_FPAC1_OFFSET 0x048 /* Flash Pump Access Control Register 1 */ +#define TMS570_FLASH_FPAC2_OFFSET 0x04c /* Flash Pump Access Control Register 2 */ +#define TMS570_FLASH_FMAC_OFFSET 0x050 /* Flash Module Access Control Register */ +#define TMS570_FLASH_FMSTAT_OFFSET 0x054 /* Flash Module Status Register */ +#define TMS570_FLASH_FEMUDMSW_OFFSET 0x058 /* EEPROM Emulation Data MSW Register */ +#define TMS570_FLASH_FEMUDLSW_OFFSET 0x05c /* EEPROM Emulation Data LSW Register */ +#define TMS570_FLASH_FEMUECC_OFFSET 0x060 /* EEPROM Emulation ECC Register */ +#define TMS570_FLASH_FEMUADDR_OFFSET 0x068 /* EEPROM Emulation Address Register */ +#define TMS570_FLASH_FDIAGCTRL_OFFSET 0x06c /* Diagnostic Control Register */ +#define TMS570_FLASH_FRAWDATAH_OFFSET 0x070 /* Uncorrected Raw Data High Register */ +#define TMS570_FLASH_FRAWDATAL_OFFSET 0x074 /* Uncorrected Raw Data Low Register */ +#define TMS570_FLASH_FRAWECC_OFFSET 0x078 /* Uncorrected Raw ECC Register */ +#define TMS570_FLASH_FPAROVR_OFFSET 0x07c /* Parity Override Register */ +#define TMS570_FLASH_FEDACSDIS2_OFFSET 0x0c0 /* Flash Error Detection and Correction Sector Disable Register 2 */ +#define TMS570_FLASH_FSMWRENA_OFFSET 0x288 /* FSM Register Write Enable */ +#define TMS570_FLASH_FSMSECTOR_OFFSET 0x2a4 /* FSM Sector Register */ +#define TMS570_FLASH_EEPROMCFG_OFFSET 0x2b8 /* EEPROM Emulation Configuration Register */ +#define TMS570_FLASH_EECTRL1_OFFSET 0x308 /* EEPROM Emulation Error Detection and Correction Control Register 1 */ +#define TMS570_FLASH_EECTRL2_OFFSET 0x30c /* EEPROM Emulation Error Detection and Correction Control Register 2 */ +#define TMS570_FLASH_EECORERRCNT_OFFSET 0x310 /* EEPROM Emulation Correctable Error Count Register */ +#define TMS570_FLASH_EECORERRADD_OFFSET 0x314 /* EEPROM Emulation Correctable Error Address Register */ +#define TMS570_FLASH_EECORERRPOS_OFFSET 0x318 /* EEPROM Emulation Correctable Error Bit Position Register */ +#define TMS570_FLASH_EESTATUS_OFFSET 0x31c /* EEPROM Emulation Error Status Register */ +#define TMS570_FLASH_EEUNCERRADD_OFFSET 0x320 /* EEPROM Emulation Un-Correctable Error Address Register */ +#define TMS570_FLASH_FCFGBANK_OFFSET 0x400 /* Flash Bank Configuration Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_FLASH_FRDCNTL (TMS570_FWRAP_BASE+TMS570_FLASH_FRDCNTL_OFFSET) +#define TMS570_FLASH_FEDACTRL1 (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACTRL1_OFFSET) +#define TMS570_FLASH_FEDACTRL2 (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACTRL2_OFFSET) +#define TMS570_FLASH_FCORERRCNT (TMS570_FWRAP_BASE+TMS570_FLASH_FCORERRCNT_OFFSET) +#define TMS570_FLASH_FCORERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_FCORERRADD_OFFSET) +#define TMS570_FLASH_FCORERRPOS (TMS570_FWRAP_BASE+TMS570_FLASH_FCORERRPOS_OFFSET) +#define TMS570_FLASH_FEDACSTATUS (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACSTATUS_OFFSET) +#define TMS570_FLASH_FUNCERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_FUNCERRADD_OFFSET) +#define TMS570_FLASH_FEDACSDIS (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACSDIS_OFFSET) +#define TMS570_FLASH_FPRIMADDTAG (TMS570_FWRAP_BASE+TMS570_FLASH_FPRIMADDTAG_OFFSET) +#define TMS570_FLASH_FDUPDDTAG (TMS570_FWRAP_BASE+TMS570_FLASH_FDUPDDTAG_OFFSET) +#define TMS570_FLASH_FBPROT (TMS570_FWRAP_BASE+TMS570_FLASH_FBPROT_OFFSET) +#define TMS570_FLASH_FBSE (TMS570_FWRAP_BASE+TMS570_FLASH_FBSE_OFFSET) +#define TMS570_FLASH_FBBUSY (TMS570_FWRAP_BASE+TMS570_FLASH_FBBUSY_OFFSET) +#define TMS570_FLASH_FBAC (TMS570_FWRAP_BASE+TMS570_FLASH_FBAC_OFFSET) +#define TMS570_FLASH_FBFALLBACK (TMS570_FWRAP_BASE+TMS570_FLASH_FBFALLBACK_OFFSET) +#define TMS570_FLASH_FBPRDY (TMS570_FWRAP_BASE+TMS570_FLASH_FBPRDY_OFFSET) +#define TMS570_FLASH_FPAC1 (TMS570_FWRAP_BASE+TMS570_FLASH_FPAC1_OFFSET) +#define TMS570_FLASH_FPAC2 (TMS570_FWRAP_BASE+TMS570_FLASH_FPAC2_OFFSET) +#define TMS570_FLASH_FMAC (TMS570_FWRAP_BASE+TMS570_FLASH_FMAC_OFFSET) +#define TMS570_FLASH_FMSTAT (TMS570_FWRAP_BASE+TMS570_FLASH_FMSTAT_OFFSET) +#define TMS570_FLASH_FEMUDMSW (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUDMSW_OFFSET) +#define TMS570_FLASH_FEMUDLSW (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUDLSW_OFFSET) +#define TMS570_FLASH_FEMUECC (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUECC_OFFSET) +#define TMS570_FLASH_FEMUADDR (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUADDR_OFFSET) +#define TMS570_FLASH_FDIAGCTRL (TMS570_FWRAP_BASE+TMS570_FLASH_FDIAGCTRL_OFFSET) +#define TMS570_FLASH_FRAWDATAH (TMS570_FWRAP_BASE+TMS570_FLASH_FRAWDATAH_OFFSET) +#define TMS570_FLASH_FRAWDATAL (TMS570_FWRAP_BASE+TMS570_FLASH_FRAWDATAL_OFFSET) +#define TMS570_FLASH_FRAWECC (TMS570_FWRAP_BASE+TMS570_FLASH_FRAWECC_OFFSET) +#define TMS570_FLASH_FPAROVR (TMS570_FWRAP_BASE+TMS570_FLASH_FPAROVR_OFFSET) +#define TMS570_FLASH_FEDACSDIS2 (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACSDIS2_OFFSET) +#define TMS570_FLASH_FSMWRENA (TMS570_FWRAP_BASE+TMS570_FLASH_FSMWRENA_OFFSET) +#define TMS570_FLASH_FSMSECTOR (TMS570_FWRAP_BASE+TMS570_FLASH_FSMSECTOR_OFFSET) +#define TMS570_FLASH_EEPROMCFG (TMS570_FWRAP_BASE+TMS570_FLASH_EEPROMCFG_OFFSET) +#define TMS570_FLASH_EECTRL1 (TMS570_FWRAP_BASE+TMS570_FLASH_EECTRL1_OFFSET) +#define TMS570_FLASH_EECTRL2 (TMS570_FWRAP_BASE+TMS570_FLASH_EECTRL2_OFFSET) +#define TMS570_FLASH_EECORERRCNT (TMS570_FWRAP_BASE+TMS570_FLASH_EECORERRCNT_OFFSET) +#define TMS570_FLASH_EECORERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_EECORERRADD_OFFSET) +#define TMS570_FLASH_EECORERRPOS (TMS570_FWRAP_BASE+TMS570_FLASH_EECORERRPOS_OFFSET) +#define TMS570_FLASH_EESTATUS (TMS570_FWRAP_BASE+TMS570_FLASH_EESTATUS_OFFSET) +#define TMS570_FLASH_EEUNCERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_EEUNCERRADD_OFFSET) +#define TMS570_FLASH_FCFGBANK (TMS570_FWRAP_BASE+TMS570_FLASH_FCFGBANK_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Flash Option Control Register */ + +#define FLASH_FRDCNTL_ENPIPE (1 << 0) /* Bit 0: Enable Pipeline Mode */ +#define FLASH_FRDCNTL_ASWSTEN (1 << 4) /* Bit 4: Address Setup Wait State Enable */ +#define FLASH_FRDCNTL_RWAIT_SHIFT (8) /* Bits 8-11: Random/data Read Wait State */ +#define FLASH_FRDCNTL_RWAIT_MASK (15 << FLASH_FRDCNTL_RWAIT_SHIFT) +# define FLASH_FRDCNTL_RWAIT(n) ((uint32_t)(n) << FLASH_FRDCNTL_RWAIT_SHIFT) + +/* Flash Error Detection and Correction Control Register 1 */ +#define FLASH_FEDACTRL1_ +/* Flash Error Detection and Correction Control Register 2 */ +#define FLASH_FEDACTRL2_ +/* Flash Correctable Error Count Register */ +#define FLASH_FCORERRCNT_ +/* Flash Correctable Error Address Register */ +#define FLASH_FCORERRADD_ +/* Flash Correctable Error Position Register */ +#define FLASH_FCORERRPOS_ +/* Flash Error Detection and Correction Status Register */ +#define FLASH_FEDACSTATUS_ +/* Flash Un-Correctable Error Address Register */ +#define FLASH_FUNCERRADD_ +/* Flash Error Detection and Correction Sector Disable Register */ +#define FLASH_FEDACSDIS_ +/* Flash Primary Address Tag Register */ +#define FLASH_FPRIMADDTAG_ +/* Flash Duplicate Address Tag Register */ +#define FLASH_FDUPDDTAG_ +/* Flash Bank Protection Register */ +#define FLASH_FBPROT_ +/* Flash Bank Sector Enable Register */ +#define FLASH_FBSE_ +/* Flash Bank Busy Register */ +#define FLASH_FBBUSY_ +/* Flash Bank Access Control Register */ +#define FLASH_FBAC_ + +/* Flash Bank Fallback Power Register */ + +#define FLASH_FBFALLBACK_BANKPWR0_SHIFT (0) /* Bit 0: Bank 0 Fallback Power Mode */ +#define FLASH_FBFALLBACK_BANKPWR0_MASK (3 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR0_SLEEP (0 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR0_STDBY (1 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR0_ACTIV (3 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +#define FLASH_FBFALLBACK_BANKPWR1_SHIFT (2) /* Bit 2: Bank 1 Fallback Power Mode */ +#define FLASH_FBFALLBACK_BANKPWR1_MASK (3 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR1_SLEEP (0 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR1_STDBY (1 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR1_ACTIV (3 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +#define FLASH_FBFALLBACK_BANKPWR7_SHIFT (14) /* Bit 14: Bank 7 Fallback Power Mode */ +#define FLASH_FBFALLBACK_BANKPWR7_MASK (3 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR7_SLEEP (0 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR7_STDBY (1 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR7_ACTIV (3 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) + +/* Flash Bank/Pump Ready Register */ +#define FLASH_FBPRDY_ +/* Flash Pump Access Control Register 1 */ +#define FLASH_FPAC1_ +/* Flash Pump Access Control Register 2 */ +#define FLASH_FPAC2_ +/* Flash Module Access Control Register */ +#define FLASH_FMAC_ +/* Flash Module Status Register */ +#define FLASH_FMSTAT_ +/* EEPROM Emulation Data MSW Register */ +#define FLASH_FEMUDMSW_ +/* EEPROM Emulation Data LSW Register */ +#define FLASH_FEMUDLSW_ +/* EEPROM Emulation ECC Register */ +#define FLASH_FEMUECC_ +/* EEPROM Emulation Address Register */ +#define FLASH_FEMUADDR_ +/* Diagnostic Control Register */ +#define FLASH_FDIAGCTRL_ +/* Uncorrected Raw Data High Register */ +#define FLASH_FRAWDATAH_ +/* Uncorrected Raw Data Low Register */ +#define FLASH_FRAWDATAL_ +/* Uncorrected Raw ECC Register */ +#define FLASH_FRAWECC_ +/* Parity Override Register */ +#define FLASH_FPAROVR_ +/* Flash Error Detection and Correction Sector Disable Register 2 */ +#define FLASH_FEDACSDIS2_ + +/* FSM Register Write Enable */ + +#define FLASH_FSMWRENA_ENABLE_SHIFT (0) /* Bits 0-2: FSM Write Enable */ +#define FLASH_FSMWRENA_ENABLE_MASK (7 << FLASH_FSMWRENA_ENABLE_SHIFT) +# define FLASH_FSMWRENA_ENABLE (5 << FLASH_FSMWRENA_ENABLE_SHIFT) /* Enable write to FSM registers */ +# define FLASH_FSMWRENA_DISABLE (2 << FLASH_FSMWRENA_ENABLE_SHIFT) /* Any other value disables */ + +/* FSM Sector Register */ +#define FLASH_FSMSECTOR_ + +/* EEPROM Emulation Configuration Register */ + +#define FLASH_EEPROMCFG_GRACE_SHIFT (0) /* Bits 0-7: Auto-suspend Startup Grace Period */ +#define FLASH_EEPROMCFG_GRACE_MASK (0xff << FLASH_EEPROMCFG_GRACE_SHIFT) +# define FLASH_EEPROMCFG_GRACE(n) ((uint32_t)(n) << FLASH_EEPROMCFG_GRACE_SHIFT) +#define FLASH_EEPROMCFG_AUTOSUSPEN (1 << 8) /* Bit 8: Auto suspend enable */ +#define FLASH_EEPROMCFG_EWAIT_SHIFT (16) /* Bits 16-19: EEPROM Wait state Counter */ +#define FLASH_EEPROMCFG_EWAIT_MASK (15 << FLASH_EEPROMCFG_EWAIT_SHIFT) +# define FLASH_EEPROMCFG_EWAIT(n) ((uint32_t)(n) << FLASH_EEPROMCFG_EWAIT_SHIFT) + +/* EEPROM Emulation Error Detection and Correction Control Register 1 */ +#define FLASH_EECTRL1_ +/* EEPROM Emulation Error Detection and Correction Control Register 2 */ +#define FLASH_EECTRL2_ +/* EEPROM Emulation Correctable Error Count Register */ +#define FLASH_EECORERRCNT_ +/* EEPROM Emulation Correctable Error Address Register */ +#define FLASH_EECORERRADD_ +/* EEPROM Emulation Correctable Error Bit Position Register */ +#define FLASH_EECORERRPOS_ +/* EEPROM Emulation Error Status Register */ +#define FLASH_EESTATUS_ +/* EEPROM Emulation Un-Correctable Error Address Register */ +#define FLASH_EEUNCERRADD_ +/* Flash Bank Configuration Register */ +#define FLASH_FCFGBANK_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_FLASH_H */ diff --git a/arch/arm/src/tms570/chip/tms570_memorymap.h b/arch/arm/src/tms570/chip/tms570_memorymap.h new file mode 100644 index 00000000000..dc452cdaeec --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_memorymap.h @@ -0,0 +1,63 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_TMS570_CHIP_TMS570_MEMORYMAP_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_MEMORYMAP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0232PZ) +# error No memory map for the TMS570LS0232PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) +# include "chip/tms570ls04x03x_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) +# include "chip/tms570ls04x03x_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PZ) +# error No memory map for the TMS570LS0714PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PGE) +# error No memory map for the TMS570LS0714PGE +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714ZWT) +# error No memory map for the TMS570LS0714ZWT +#elif defined(CONFIG_ARCH_CHIP_TMS570LS1227ZWT) +# error No memory map for the TMS570LS1227ZWT +#else +# error "Unrecognized Hercules chip" +#endif + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_MEMORYMAP_H */ diff --git a/arch/arm/src/tms570/chip/tms570_pbist.h b/arch/arm/src/tms570/chip/tms570_pbist.h new file mode 100644 index 00000000000..666e71de8b7 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_pbist.h @@ -0,0 +1,133 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_pbist.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_PBIST_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PBIST_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_PBIST_RAMT_OFFSET 0x0160 /* RAM Configuration Register */ +#define TMS570_PBIST_DLR_OFFSET 0x0164 /* Datalogger Register */ +#define TMS570_PBIST_PCR_OFFSET 0x016c /* Program Control Register */ +#define TMS570_PBIST_PACT_OFFSET 0x0180 /* PBIST Activate/ROM Clock Enable Register */ +#define TMS570_PBIST_PBISTID_OFFSET 0x0184 /* PBIST ID Register */ +#define TMS570_PBIST_OVER_OFFSET 0x0188 /* Override Register */ +#define TMS570_PBIST_FSRF0_OFFSET 0x0190 /* Fail Status Fail Register 0 */ +#define TMS570_PBIST_FSRC0_OFFSET 0x0198 /* Fail Status Count Register 0 */ +#define TMS570_PBIST_FSRC1_OFFSET 0x019c /* Fail Status Count Register 1 */ +#define TMS570_PBIST_FSRA0_OFFSET 0x01a0 /* Fail Status Address 0 Register */ +#define TMS570_PBIST_FSRA1_OFFSET 0x01a4 /* Fail Status Address 1 Register */ +#define TMS570_PBIST_FSRDL0_OFFSET 0x01a8 /* Fail Status Data Register 0 */ +#define TMS570_PBIST_FSRDL1_OFFSET 0x01b0 /* Fail Status Data Register 1 */ +#define TMS570_PBIST_ROM_OFFSET 0x01c0 /* ROM Mask Register */ +#define TMS570_PBIST_ALGO_OFFSET 0x01c4 /* ROM Algorithm Mask Register */ +#define TMS570_PBIST_RINFOL_OFFSET 0x01c8 /* RAM Info Mask Lower Register */ +#define TMS570_PBIST_RINFOU_OFFSET 0x01cc /* RAM Info Mask Upper Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_PBIST_RAMT (TMS570_PBIST_BASE+TMS570_PBIST_RAMT_OFFSET) +#define TMS570_PBIST_DLR (TMS570_PBIST_BASE+TMS570_PBIST_DLR_OFFSET) +#define TMS570_PBIST_PCR (TMS570_PBIST_BASE+TMS570_PBIST_PCR_OFFSET) +#define TMS570_PBIST_PACT (TMS570_PBIST_BASE+TMS570_PBIST_PACT_OFFSET) +#define TMS570_PBIST_PBISTID (TMS570_PBIST_BASE+TMS570_PBIST_PBISTID_OFFSET) +#define TMS570_PBIST_OVER (TMS570_PBIST_BASE+TMS570_PBIST_OVER_OFFSET) +#define TMS570_PBIST_FSRF0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRF0_OFFSET) +#define TMS570_PBIST_FSRC0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRC0_OFFSET) +#define TMS570_PBIST_FSRC1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRC1_OFFSET) +#define TMS570_PBIST_FSRA0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRA0_OFFSET) +#define TMS570_PBIST_FSRA1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRA1_OFFSET) +#define TMS570_PBIST_FSRDL0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRDL0_OFFSET) +#define TMS570_PBIST_FSRDL1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRDL1_OFFSET) +#define TMS570_PBIST_ROM (TMS570_PBIST_BASE+TMS570_PBIST_ROM_OFFSET) +#define TMS570_PBIST_ALGO (TMS570_PBIST_BASE+TMS570_PBIST_ALGO_OFFSET) +#define TMS570_PBIST_RINFOL (TMS570_PBIST_BASE+TMS570_PBIST_RINFOL_OFFSET) +#define TMS570_PBIST_RINFOU (TMS570_PBIST_BASE+TMS570_PBIST_RINFOU_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* RAM Configuration Register */ +#define PBIST_RAMT_ +/* Datalogger Register */ +#define PBIST_DLR_ +/* Program Control Register */ +#define PBIST_PCR_ +/* PBIST Activate/ROM Clock Enable Register */ +#define PBIST_PACT_ +/* PBIST ID Register */ +#define PBIST_PBISTID_ +/* Override Register */ +#define PBIST_OVER_ +/* Fail Status Fail Register 0 */ +#define PBIST_FSRF0_ +/* Fail Status Count Register 0 */ +#define PBIST_FSRC0_ +/* Fail Status Count Register 1 */ +#define PBIST_FSRC1_ +/* Fail Status Address 0 Register */ +#define PBIST_FSRA0_ +/* Fail Status Address 1 Register */ +#define PBIST_FSRA1_ +/* Fail Status Data Register 0 */ +#define PBIST_FSRDL0_ +/* Fail Status Data Register 1 */ +#define PBIST_FSRDL1_ +/* ROM Mask Register */ +#define PBIST_ROM_ +/* ROM Algorithm Mask Register */ +#define PBIST_ALGO_ +/* RAM Info Mask Lower Register */ +#define PBIST_RINFOL_ +/* RAM Info Mask Upper Register */ +#define PBIST_RINFOU_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PBIST_H */ diff --git a/arch/arm/src/tms570/chip/tms570_pcr.h b/arch/arm/src/tms570/chip/tms570_pcr.h new file mode 100644 index 00000000000..c928da5e6ce --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_pcr.h @@ -0,0 +1,396 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_pcr.h + * Peripheral Control Register (PCR) Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_PCR_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PCR_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_PCR_PMPROTSET0_OFFSET 0x0000 /* Peripheral Memory Protection Set Register 0 */ +#define TMS570_PCR_PMPROTSET1_OFFSET 0x0004 /* Peripheral Memory Protection Set Register 1 */ +#define TMS570_PCR_PMPROTCLR0_OFFSET 0x0010 /* Peripheral Memory Protection Clear Register 0 */ +#define TMS570_PCR_PMPROTCLR1_OFFSET 0x0014 /* Peripheral Memory Protection Clear Register 1 */ +#define TMS570_PCR_PPROTSET0_OFFSET 0x0020 /* Peripheral Protection Set Register 0 */ +#define TMS570_PCR_PPROTSET1_OFFSET 0x0024 /* Peripheral Protection Set Register 1 */ +#define TMS570_PCR_PPROTSET2_OFFSET 0x0028 /* Peripheral Protection Set Register 2 */ +#define TMS570_PCR_PPROTSET3_OFFSET 0x002c /* Peripheral Protection Set Register 3 */ +#define TMS570_PCR_PPROTCLR0_OFFSET 0x0040 /* Peripheral Protection Clear Register 0 */ +#define TMS570_PCR_PPROTCLR1_OFFSET 0x0044 /* Peripheral Protection Clear Register 1 */ +#define TMS570_PCR_PPROTCLR2_OFFSET 0x0048 /* Peripheral Protection Clear Register 2 */ +#define TMS570_PCR_PPROTCLR3_OFFSET 0x004c /* Peripheral Protection Clear Register 3 */ +#define TMS570_PCR_PCSPWRDWNSET0_OFFSET 0x0060 /* Peripheral Memory Power-Down Set Register 0 */ +#define TMS570_PCR_PCSPWRDWNSET1_OFFSET 0x0064 /* Peripheral Memory Power-Down Set Register 1 */ +#define TMS570_PCR_PCSPWRDWNCLR0_OFFSET 0x0070 /* Peripheral Memory Power-Down Clear Register 0 */ +#define TMS570_PCR_PCSPWRDWNCLR1_OFFSET 0x0074 /* Peripheral Memory Power-Down Clear Register 1 */ +#define TMS570_PCR_PSPWRDWNSET0_OFFSET 0x0080 /* Peripheral Power-Down Set Register 0 */ +#define TMS570_PCR_PSPWRDWNSET1_OFFSET 0x0084 /* Peripheral Power-Down Set Register 1 */ +#define TMS570_PCR_PSPWRDWNSET2_OFFSET 0x0088 /* Peripheral Power-Down Set Register 2 */ +#define TMS570_PCR_PSPWRDWNSET3_OFFSET 0x008c /* Peripheral Power-Down Set Register 3 */ +#define TMS570_PCR_PSPWRDWNCLR0_OFFSET 0x00a0 /* Peripheral Power-Down Clear Register 0 */ +#define TMS570_PCR_PSPWRDWNCLR1_OFFSET 0x00a4 /* Peripheral Power-Down Clear Register 1 */ +#define TMS570_PCR_PSPWRDWNCLR2_OFFSET 0x00a8 /* Peripheral Power-Down Clear Register 2 */ +#define TMS570_PCR_PSPWRDWNCLR3_OFFSET 0x00ac /* Peripheral Power-Down Clear Register 3 */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_PCR_PMPROTSET0 (TMS570_PCR_BASE+TMS570_PCR_PMPROTSET0_OFFSET) +#define TMS570_PCR_PMPROTSET1 (TMS570_PCR_BASE+TMS570_PCR_PMPROTSET1_OFFSET) +#define TMS570_PCR_PMPROTCLR0 (TMS570_PCR_BASE+TMS570_PCR_PMPROTCLR0_OFFSET) +#define TMS570_PCR_PMPROTCLR1 (TMS570_PCR_BASE+TMS570_PCR_PMPROTCLR1_OFFSET) +#define TMS570_PCR_PPROTSET0 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET0_OFFSET) +#define TMS570_PCR_PPROTSET1 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET1_OFFSET) +#define TMS570_PCR_PPROTSET2 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET2_OFFSET) +#define TMS570_PCR_PPROTSET3 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET3_OFFSET) +#define TMS570_PCR_PPROTCLR0 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR0_OFFSET) +#define TMS570_PCR_PPROTCLR1 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR1_OFFSET) +#define TMS570_PCR_PPROTCLR2 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR2_OFFSET) +#define TMS570_PCR_PPROTCLR3 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR3_OFFSET) +#define TMS570_PCR_PCSPWRDWNSET0 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNSET0_OFFSET) +#define TMS570_PCR_PCSPWRDWNSET1 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNSET1_OFFSET) +#define TMS570_PCR_PCSPWRDWNCLR0 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNCLR0_OFFSET) +#define TMS570_PCR_PCSPWRDWNCLR1 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNCLR1_OFFSET) +#define TMS570_PCR_PSPWRDWNSET0 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET0_OFFSET) +#define TMS570_PCR_PSPWRDWNSET1 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET1_OFFSET) +#define TMS570_PCR_PSPWRDWNSET2 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET2_OFFSET) +#define TMS570_PCR_PSPWRDWNSET3 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET3_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR0 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR0_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR1 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR1_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR2 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR2_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR3 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR3_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Peripheral Memory Protection Set Register 0 */ +#define PCR_PMPROTSET0_ + +/* Peripheral Memory Protection Set Register 1 */ +#define PCR_PMPROTSET1_ + +/* Peripheral Memory Protection Clear Register 0 */ +#define PCR_PMPROTCLR0_ + +/* Peripheral Memory Protection Clear Register 1 */ +#define PCR_PMPROTCLR1_ + +/* Peripheral Protection Set Register 0 */ +#define PCR_PPROTSET0_ + +/* Peripheral Protection Set Register 1 */ +#define PCR_PPROTSET1_ + +/* Peripheral Protection Set Register 2 */ +#define PCR_PPROTSET2_ + +/* Peripheral Protection Set Register 3 */ +#define PCR_PPROTSET3_ + +/* Peripheral Protection Clear Register 0 */ +#define PCR_PPROTCLR0_ + +/* Peripheral Protection Clear Register 1 */ +#define PCR_PPROTCLR1_ + +/* Peripheral Protection Clear Register 2 */ +#define PCR_PPROTCLR2_ + +/* Peripheral Protection Clear Register 3 */ +#define PCR_PPROTCLR3_ + +/* Peripheral Memory Power-Down Set Register 0 */ +#define PCR_PCSPWRDWNSET0_ + +/* Peripheral Memory Power-Down Set Register 1 */ +#define PCR_PCSPWRDWNSET1_ + +/* Peripheral Memory Power-Down Clear Register 0 */ +#define PCR_PCSPWRDWNCLR0_ + +/* Peripheral Memory Power-Down Clear Register 1 */ +#define PCR_PCSPWRDWNCLR1_ + +/* Peripheral Power-Down Set Register 0 and Peripheral Power-Down Clear Register 0 */ + +#define PCR_PSPWERDWN0_PS0_SHIFT (0) /* Bits 0-3: Quadrants for PS0 */ +#define PCR_PSPWERDWN0_PS0_MASK (15 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q1 (1 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q2 (2 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q3 (4 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q4 (8 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_QALL (15 << PCR_PSPWERDWN0_PS0_SHIFT) +#define PCR_PSPWERDWN0_PS1_SHIFT (4) /* Bits 4-7: Quadrants for PS1 */ +#define PCR_PSPWERDWN0_PS1_MASK (15 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q1 (1 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q2 (2 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q3 (4 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q4 (8 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_QALL (15 << PCR_PSPWERDWN0_PS1_SHIFT) +#define PCR_PSPWERDWN0_PS2_SHIFT (8) /* Bits 8-11: Quadrants for PS2 */ +#define PCR_PSPWERDWN0_PS2_MASK (15 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q1 (1 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q2 (2 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q3 (4 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q4 (8 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_QALL (15 << PCR_PSPWERDWN0_PS2_SHIFT) +#define PCR_PSPWERDWN0_PS3_SHIFT (12) /* Bits 12-15: Quadrants for PS3 */ +#define PCR_PSPWERDWN0_PS3_MASK (15 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q1 (1 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q2 (2 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q3 (4 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q4 (8 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_QALL (15 << PCR_PSPWERDWN0_PS3_SHIFT) +#define PCR_PSPWERDWN0_PS4_SHIFT (16) /* Bits 16-19: Quadrants for PS4 */ +#define PCR_PSPWERDWN0_PS4_MASK (15 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q1 (1 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q2 (2 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q3 (4 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q4 (8 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_QALL (15 << PCR_PSPWERDWN0_PS4_SHIFT) +#define PCR_PSPWERDWN0_PS5_SHIFT (20) /* Bits 20-23: Quadrants for PS5 */ +#define PCR_PSPWERDWN0_PS5_MASK (15 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q1 (1 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q2 (2 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q3 (4 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q4 (8 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_QALL (15 << PCR_PSPWERDWN0_PS5_SHIFT) +#define PCR_PSPWERDWN0_PS6_SHIFT (24) /* Bits 24-27: Quadrants for PS6 */ +#define PCR_PSPWERDWN0_PS6_MASK (15 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q1 (1 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q2 (2 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q3 (4 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q4 (8 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_QALL (15 << PCR_PSPWERDWN0_PS6_SHIFT) +#define PCR_PSPWERDWN0_PS7_SHIFT (28) /* Bits 28-31: Quadrants for PS7 */ +#define PCR_PSPWERDWN0_PS7_MASK (15 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q1 (1 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q2 (2 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q3 (4 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q4 (8 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_QALL (15 << PCR_PSPWERDWN0_PS7_SHIFT) + +/* Peripheral Power-Down Set Register 1 and Peripheral Power-Down Clear Register 1 */ + +#define PCR_PSPWERDWN1_PS8_SHIFT (0) /* Bits 0-3: Quadrants for PS8 */ +#define PCR_PSPWERDWN1_PS8_MASK (15 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q1 (1 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q2 (2 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q3 (4 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q4 (8 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_QALL (15 << PCR_PSPWERDWN1_PS8_SHIFT) +#define PCR_PSPWERDWN1_PS9_SHIFT (4) /* Bits 4-7: Quadrants for PS9 */ +#define PCR_PSPWERDWN1_PS9_MASK (15 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q1 (1 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q2 (2 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q3 (4 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q4 (8 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_QALL (15 << PCR_PSPWERDWN1_PS9_SHIFT) +#define PCR_PSPWERDWN1_PS10_SHIFT (8) /* Bits 8-11: Quadrants for PS10 */ +#define PCR_PSPWERDWN1_PS10_MASK (15 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q1 (1 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q2 (2 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q3 (4 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q4 (8 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_QALL (15 << PCR_PSPWERDWN1_PS10_SHIFT) +#define PCR_PSPWERDWN1_PS11_SHIFT (12) /* Bits 12-15: Quadrants for PS11 */ +#define PCR_PSPWERDWN1_PS11_MASK (15 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q1 (1 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q2 (2 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q3 (4 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q4 (8 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_QALL (15 << PCR_PSPWERDWN1_PS11_SHIFT) +#define PCR_PSPWERDWN1_PS12_SHIFT (16) /* Bits 16-19: Quadrants for PS12 */ +#define PCR_PSPWERDWN1_PS12_MASK (15 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q1 (1 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q2 (2 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q3 (4 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q4 (8 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_QALL (15 << PCR_PSPWERDWN1_PS12_SHIFT) +#define PCR_PSPWERDWN1_PS13_SHIFT (20) /* Bits 20-23: Quadrants for PS13 */ +#define PCR_PSPWERDWN1_PS13_MASK (15 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q1 (1 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q2 (2 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q3 (4 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q4 (8 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_QALL (15 << PCR_PSPWERDWN1_PS13_SHIFT) +#define PCR_PSPWERDWN1_PS14_SHIFT (24) /* Bits 24-27: Quadrants for PS14 */ +#define PCR_PSPWERDWN1_PS14_MASK (15 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q1 (1 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q2 (2 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q3 (4 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q4 (8 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_QALL (15 << PCR_PSPWERDWN1_PS14_SHIFT) +#define PCR_PSPWERDWN1_PS15_SHIFT (28) /* Bits 28-31: Quadrants for PS15 */ +#define PCR_PSPWERDWN1_PS15_MASK (15 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q1 (1 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q2 (2 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q3 (4 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q4 (8 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_QALL (15 << PCR_PSPWERDWN1_PS15_SHIFT) + +/* Peripheral Power-Down Set Register 2 and Peripheral Power-Down Clear Register 2*/ + +#define PCR_PSPWERDWN2_PS16_SHIFT (0) /* Bits 0-3: Quadrants for PS16 */ +#define PCR_PSPWERDWN2_PS16_MASK (15 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q1 (1 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q2 (2 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q3 (4 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q4 (8 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_QALL (15 << PCR_PSPWERDWN2_PS16_SHIFT) +#define PCR_PSPWERDWN2_PS17_SHIFT (4) /* Bits 4-7: Quadrants for PS17 */ +#define PCR_PSPWERDWN2_PS17_MASK (15 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q1 (1 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q2 (2 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q3 (4 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q4 (8 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_QALL (15 << PCR_PSPWERDWN2_PS17_SHIFT) +#define PCR_PSPWERDWN2_PS18_SHIFT (8) /* Bits 8-11: Quadrants for PS18 */ +#define PCR_PSPWERDWN2_PS18_MASK (15 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q1 (1 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q2 (2 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q3 (4 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q4 (8 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_QALL (15 << PCR_PSPWERDWN2_PS18_SHIFT) +#define PCR_PSPWERDWN2_PS19_SHIFT (12) /* Bits 12-15: Quadrants for PS19 */ +#define PCR_PSPWERDWN2_PS19_MASK (15 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q1 (1 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q2 (2 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q3 (4 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q4 (8 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_QALL (15 << PCR_PSPWERDWN2_PS19_SHIFT) +#define PCR_PSPWERDWN2_PS20_SHIFT (16) /* Bits 16-19: Quadrants for PS20 */ +#define PCR_PSPWERDWN2_PS20_MASK (15 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q1 (1 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q2 (2 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q3 (4 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q4 (8 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_QALL (15 << PCR_PSPWERDWN2_PS20_SHIFT) +#define PCR_PSPWERDWN2_PS21_SHIFT (20) /* Bits 20-23: Quadrants for PS21 */ +#define PCR_PSPWERDWN2_PS21_MASK (15 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q1 (1 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q2 (2 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q3 (4 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q4 (8 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_QALL (15 << PCR_PSPWERDWN2_PS21_SHIFT) +#define PCR_PSPWERDWN2_PS22_SHIFT (24) /* Bits 24-27: Quadrants for PS22 */ +#define PCR_PSPWERDWN2_PS22_MASK (15 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q1 (1 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q2 (2 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q3 (4 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q4 (8 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_QALL (15 << PCR_PSPWERDWN2_PS22_SHIFT) +#define PCR_PSPWERDWN2_PS23_SHIFT (28) /* Bits 28-31: Quadrants for PS23 */ +#define PCR_PSPWERDWN2_PS23_MASK (15 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q1 (1 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q2 (2 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q3 (4 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q4 (8 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_QALL (15 << PCR_PSPWERDWN2_PS23_SHIFT) + +/* Peripheral Power-Down Set Register 3 and Peripheral Power-Down Clear Register 3 */ + +#define PCR_PSPWERDWN3_PS24_SHIFT (0) /* Bits 0-3: Quadrants for PS24 */ +#define PCR_PSPWERDWN3_PS24_MASK (15 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q1 (1 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q2 (2 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q3 (4 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q4 (8 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_QALL (15 << PCR_PSPWERDWN3_PS24_SHIFT) +#define PCR_PSPWERDWN3_PS25_SHIFT (4) /* Bits 4-7: Quadrants for PS25 */ +#define PCR_PSPWERDWN3_PS25_MASK (15 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q1 (1 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q2 (2 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q3 (4 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q4 (8 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_QALL (15 << PCR_PSPWERDWN3_PS25_SHIFT) +#define PCR_PSPWERDWN3_PS26_SHIFT (8) /* Bits 8-11: Quadrants for PS26 */ +#define PCR_PSPWERDWN3_PS26_MASK (15 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q1 (1 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q2 (2 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q3 (4 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q4 (8 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_QALL (15 << PCR_PSPWERDWN3_PS26_SHIFT) +#define PCR_PSPWERDWN3_PS27_SHIFT (12) /* Bits 12-15: Quadrants for PS27 */ +#define PCR_PSPWERDWN3_PS27_MASK (15 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q1 (1 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q2 (2 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q3 (4 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q4 (8 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_QALL (15 << PCR_PSPWERDWN3_PS27_SHIFT) +#define PCR_PSPWERDWN3_PS28_SHIFT (16) /* Bits 16-19: Quadrants for PS28 */ +#define PCR_PSPWERDWN3_PS28_MASK (15 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q1 (1 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q2 (2 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q3 (4 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q4 (8 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_QALL (15 << PCR_PSPWERDWN3_PS28_SHIFT) +#define PCR_PSPWERDWN3_PS29_SHIFT (20) /* Bits 20-23: Quadrants for PS29 */ +#define PCR_PSPWERDWN3_PS29_MASK (15 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q1 (1 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q2 (2 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q3 (4 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q4 (8 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_QALL (15 << PCR_PSPWERDWN3_PS29_SHIFT) +#define PCR_PSPWERDWN3_PS30_SHIFT (24) /* Bits 24-27: Quadrants for PS30 */ +#define PCR_PSPWERDWN3_PS30_MASK (15 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q1 (1 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q2 (2 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q3 (4 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q4 (8 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_QALL (15 << PCR_PSPWERDWN3_PS30_SHIFT) +#define PCR_PSPWERDWN3_PS31_SHIFT (28) /* Bits 28-31: Quadrants for PS31 */ +#define PCR_PSPWERDWN3_PS31_MASK (15 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q1 (1 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q2 (2 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q3 (4 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q4 (8 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_QALL (15 << PCR_PSPWERDWN3_PS31_SHIFT) + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PCR_H */ diff --git a/arch/arm/src/tms570/chip/tms570_sci.h b/arch/arm/src/tms570/chip/tms570_sci.h new file mode 100644 index 00000000000..074874588d6 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_sci.h @@ -0,0 +1,233 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_sci.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_SCI_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SCI_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_SCI_GCR0_OFFSET 0x0000 /* SCI Global Control Register 0 */ +#define TMS570_SCI_GCR1_OFFSET 0x0004 /* SCI Global Control Register 1 */ +#define TMS570_SCI_GCR2_OFFSET 0x0008 /* SCI Global Control Register 2 */ +#define TMS570_SCI_SETINT_OFFSET 0x000c /* SCI Set Interrupt Register */ +#define TMS570_SCI_CLEARINT_OFFSET 0x0010 /* SCI Clear Interrupt Register */ +#define TMS570_SCI_SETINTLVL_OFFSET 0x0014 /* SCI Set Interrupt Level Register */ +#define TMS570_SCI_CLEARINTLVL_OFFSET 0x0018 /* SCI Clear Interrupt Level Register */ +#define TMS570_SCI_FLR_OFFSET 0x001c /* SCI Flags Register */ +#define TMS570_SCI_INTVECT0_OFFSET 0x0020 /* SCI Interrupt Vector Offset 0 */ +#define TMS570_SCI_INTVECT1_OFFSET 0x0024 /* SCI Interrupt Vector Offset 1 */ +#define TMS570_SCI_FORMAT_OFFSET 0x0028 /* SCI Format Control Register */ +#define TMS570_SCI_BRS_OFFSET 0x002c /* Baud Rate Selection Register */ +#define TMS570_SCI_ED_OFFSET 0x0030 /* Receiver Emulation Data Buffer */ +#define TMS570_SCI_RD_OFFSET 0x0034 /* Receiver Data Buffer */ +#define TMS570_SCI_TD_OFFSET 0x0038 /* Transmit Data Buffer */ +#define TMS570_SCI_PIO0_OFFSET 0x003c /* SCI Pin I/O Control Register 0 */ +#define TMS570_SCI_PIO1_OFFSET 0x0040 /* SCI Pin I/O Control Register 1 */ +#define TMS570_SCI_PIO2_OFFSET 0x0044 /* SCI Pin I/O Control Register 2 */ +#define TMS570_SCI_PIO3_OFFSET 0x0048 /* SCI Pin I/O Control Register 3 */ +#define TMS570_SCI_PIO4_OFFSET 0x004c /* SCI Pin I/O Control Register 4 */ +#define TMS570_SCI_PIO5_OFFSET 0x0050 /* SCI Pin I/O Control Register 5 */ +#define TMS570_SCI_PIO6_OFFSET 0x0054 /* SCI Pin I/O Control Register 6 */ +#define TMS570_SCI_PIO7_OFFSET 0x0058 /* SCI Pin I/O Control Register 7 */ +#define TMS570_SCI_PIO8_OFFSET 0x005c /* SCI Pin I/O Control Register 8 */ +#define TMS570_LIN_COMPARE_OFFSET 0x0060 /* LIN Compare Register */ +#define TMS570_LIN_RD0_OFFSET 0x0064 /* LIN Receive Buffer 0 Register */ +#define TMS570_LIN_RD1_OFFSET 0x0068 /* LIN Receive Buffer 1 Register */ +#define TMS570_LIN_MASK_OFFSET 0x006c /* LIN Mask Register */ +#define TMS570_LIN_ID_OFFSET 0x0070 /* LIN Identification Register */ +#define TMS570_LIN_TD0_OFFSET 0x0074 /* LIN Transmit Buffer 0 */ +#define TMS570_LIN_TD1_OFFSET 0x0078 /* LIN Transmit Buffer 1 */ +#define TMS570_SCI_MBRS_OFFSET 0x007c /* Maximum Baud Rate Selection Register */ +#define TMS570_SCI_IODFTCTRL_OFFSET 0x0090 /* Input/Output Error Enable Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_SCI1_GCR0 (TMS570_SCI1_BASE+TMS570_SCI_GCR0_OFFSET) +#define TMS570_SCI1_GCR1 (TMS570_SCI1_BASE+TMS570_SCI_GCR1_OFFSET) +#define TMS570_SCI1_GCR2 (TMS570_SCI1_BASE+TMS570_SCI_GCR2_OFFSET) +#define TMS570_SCI1_SETINT (TMS570_SCI1_BASE+TMS570_SCI_SETINT_OFFSET) +#define TMS570_SCI1_CLEARINT (TMS570_SCI1_BASE+TMS570_SCI_CLEARINT_OFFSET) +#define TMS570_SCI1_SETINTLVL (TMS570_SCI1_BASE+TMS570_SCI_SETINTLVL_OFFSET) +#define TMS570_SCI1_CLEARINTLVL (TMS570_SCI1_BASE+TMS570_SCI_CLEARINTLVL_OFFSET) +#define TMS570_SCI1_FLR (TMS570_SCI1_BASE+TMS570_SCI_FLR_OFFSET) +#define TMS570_SCI1_INTVECT0 (TMS570_SCI1_BASE+TMS570_SCI_INTVECT0_OFFSET) +#define TMS570_SCI1_INTVECT1 (TMS570_SCI1_BASE+TMS570_SCI_INTVECT1_OFFSET) +#define TMS570_SCI1_FORMAT (TMS570_SCI1_BASE+TMS570_SCI_FORMAT_OFFSET) +#define TMS570_SCI1_BRS (TMS570_SCI1_BASE+TMS570_SCI_BRS_OFFSET) +#define TMS570_SCI1_ED (TMS570_SCI1_BASE+TMS570_SCI_ED_OFFSET) +#define TMS570_SCI1_RD (TMS570_SCI1_BASE+TMS570_SCI_RD_OFFSET) +#define TMS570_SCI1_TD (TMS570_SCI1_BASE+TMS570_SCI_TD_OFFSET) +#define TMS570_SCI1_PIO0 (TMS570_SCI1_BASE+TMS570_SCI_PIO0_OFFSET) +#define TMS570_SCI1_PIO1 (TMS570_SCI1_BASE+TMS570_SCI_PIO1_OFFSET) +#define TMS570_SCI1_PIO2 (TMS570_SCI1_BASE+TMS570_SCI_PIO2_OFFSET) +#define TMS570_SCI1_PIO3 (TMS570_SCI1_BASE+TMS570_SCI_PIO3_OFFSET) +#define TMS570_SCI1_PIO4 (TMS570_SCI1_BASE+TMS570_SCI_PIO4_OFFSET) +#define TMS570_SCI1_PIO5 (TMS570_SCI1_BASE+TMS570_SCI_PIO5_OFFSET) +#define TMS570_SCI1_PIO6 (TMS570_SCI1_BASE+TMS570_SCI_PIO6_OFFSET) +#define TMS570_SCI1_PIO7 (TMS570_SCI1_BASE+TMS570_SCI_PIO7_OFFSET) +#define TMS570_SCI1_PIO8 (TMS570_SCI1_BASE+TMS570_SCI_PIO8_OFFSET) +#define TMS570_LIN1_COMPARE (TMS570_SCI1_BASE+TMS570_LIN_COMPARE_OFFSET) +#define TMS570_LIN1_RD0 (TMS570_SCI1_BASE+TMS570_LIN_RD0_OFFSET) +#define TMS570_LIN1_RD1 (TMS570_SCI1_BASE+TMS570_LIN_RD1_OFFSET) +#define TMS570_LIN1_MASK (TMS570_SCI1_BASE+TMS570_LIN_MASK_OFFSET) +#define TMS570_LIN1_ID (TMS570_SCI1_BASE+TMS570_LIN_ID_OFFSET) +#define TMS570_LIN1_TD0 (TMS570_SCI1_BASE+TMS570_LIN_TD0_OFFSET) +#define TMS570_LIN1_TD1 (TMS570_SCI1_BASE+TMS570_LIN_TD1_OFFSET) +#define TMS570_SCI1_MBRS (TMS570_SCI1_BASE+TMS570_SCI_MBRS_OFFSET) +#define TMS570_SCI1_IODFTCTRL (TMS570_SCI1_BASE+TMS570_SCI_IODFTCTRL_OFFSET) + +#if TMS570_NSCI > 1 +# define TMS570_SCI2_GCR0 (TMS570_SCI2_BASE+TMS570_SCI_GCR0_OFFSET) +# define TMS570_SCI2_GCR1 (TMS570_SCI2_BASE+TMS570_SCI_GCR1_OFFSET) +# define TMS570_SCI2_GCR2 (TMS570_SCI2_BASE+TMS570_SCI_GCR2_OFFSET) +# define TMS570_SCI2_SETINT (TMS570_SCI2_BASE+TMS570_SCI_SETINT_OFFSET) +# define TMS570_SCI2_CLEARINT (TMS570_SCI2_BASE+TMS570_SCI_CLEARINT_OFFSET) +# define TMS570_SCI2_SETINTLVL (TMS570_SCI2_BASE+TMS570_SCI_SETINTLVL_OFFSET) +# define TMS570_SCI2_CLEARINTLVL (TMS570_SCI2_BASE+TMS570_SCI_CLEARINTLVL_OFFSET) +# define TMS570_SCI2_FLR (TMS570_SCI2_BASE+TMS570_SCI_FLR_OFFSET) +# define TMS570_SCI2_INTVECT0 (TMS570_SCI2_BASE+TMS570_SCI_INTVECT0_OFFSET) +# define TMS570_SCI2_INTVECT1 (TMS570_SCI2_BASE+TMS570_SCI_INTVECT1_OFFSET) +# define TMS570_SCI2_FORMAT (TMS570_SCI2_BASE+TMS570_SCI_FORMAT_OFFSET) +# define TMS570_SCI2_BRS (TMS570_SCI2_BASE+TMS570_SCI_BRS_OFFSET) +# define TMS570_SCI2_ED (TMS570_SCI2_BASE+TMS570_SCI_ED_OFFSET) +# define TMS570_SCI2_RD (TMS570_SCI2_BASE+TMS570_SCI_RD_OFFSET) +# define TMS570_SCI2_TD (TMS570_SCI2_BASE+TMS570_SCI_TD_OFFSET) +# define TMS570_SCI2_PIO0 (TMS570_SCI2_BASE+TMS570_SCI_PIO0_OFFSET) +# define TMS570_SCI2_PIO1 (TMS570_SCI2_BASE+TMS570_SCI_PIO1_OFFSET) +# define TMS570_SCI2_PIO2 (TMS570_SCI2_BASE+TMS570_SCI_PIO2_OFFSET) +# define TMS570_SCI2_PIO3 (TMS570_SCI2_BASE+TMS570_SCI_PIO3_OFFSET) +# define TMS570_SCI2_PIO4 (TMS570_SCI2_BASE+TMS570_SCI_PIO4_OFFSET) +# define TMS570_SCI2_PIO5 (TMS570_SCI2_BASE+TMS570_SCI_PIO5_OFFSET) +# define TMS570_SCI2_PIO6 (TMS570_SCI2_BASE+TMS570_SCI_PIO6_OFFSET) +# define TMS570_SCI2_PIO7 (TMS570_SCI2_BASE+TMS570_SCI_PIO7_OFFSET) +# define TMS570_SCI2_PIO8 (TMS570_SCI2_BASE+TMS570_SCI_PIO8_OFFSET) +# define TMS570_LIN2_COMPARE (TMS570_SCI2_BASE+TMS570_LIN_COMPARE_OFFSET) +# define TMS570_LIN2_RD0 (TMS570_SCI2_BASE+TMS570_LIN_RD0_OFFSET) +# define TMS570_LIN2_RD1 (TMS570_SCI2_BASE+TMS570_LIN_RD1_OFFSET) +# define TMS570_LIN2_MASK (TMS570_SCI2_BASE+TMS570_LIN_MASK_OFFSET) +# define TMS570_LIN2_ID (TMS570_SCI2_BASE+TMS570_LIN_ID_OFFSET) +# define TMS570_LIN2_TD0 (TMS570_SCI2_BASE+TMS570_LIN_TD0_OFFSET) +# define TMS570_LIN2_TD1 (TMS570_SCI2_BASE+TMS570_LIN_TD1_OFFSET) +# define TMS570_SCI2_MBRS (TMS570_SCI2_BASE+TMS570_SCI_MBRS_OFFSET) +# define TMS570_SCI2_IODFTCTRL (TMS570_SCI2_BASE+TMS570_SCI_IODFTCTRL_OFFSET) +#endif + +/* Register Bit-Field Definitions *******************************************************************/ + +/* SCI Global Control Register 0 */ +#define SCI_GCR0_ +/* SCI Global Control Register 1 */ +#define SCI_GCR1_ +/* SCI Global Control Register 2 */ +#define SCI_GCR2_ +/* SCI Set Interrupt Register */ +#define SCI_SETINT_ +/* SCI Clear Interrupt Register */ +#define SCI_CLEARINT_ +/* SCI Set Interrupt Level Register */ +#define SCI_SETINTLVL_ +/* SCI Clear Interrupt Level Register */ +#define SCI_CLEARINTLVL_ +/* SCI Flags Register */ +#define SCI_FLR_ +/* SCI Interrupt Vector Offset 0 */ +#define SCI_INTVECT0_ +/* SCI Interrupt Vector Offset 1 */ +#define SCI_INTVECT1_ +/* SCI Format Control Register */ +#define SCI_FORMAT_ +/* Baud Rate Selection Register */ +#define SCI_BRS_ +/* Receiver Emulation Data Buffer */ +#define SCI_ED_ +/* Receiver Data Buffer */ +#define SCI_RD_ +/* Transmit Data Buffer */ +#define SCI_TD_ +/* SCI Pin I/O Control Register 0 */ +#define SCI_PIO0_ +/* SCI Pin I/O Control Register 1 */ +#define SCI_PIO1_ +/* SCI Pin I/O Control Register 2 */ +#define SCI_PIO2_ +/* SCI Pin I/O Control Register 3 */ +#define SCI_PIO3_ +/* SCI Pin I/O Control Register 4 */ +#define SCI_PIO4_ +/* SCI Pin I/O Control Register 5 */ +#define SCI_PIO5_ +/* SCI Pin I/O Control Register 6 */ +#define SCI_PIO6_ +/* SCI Pin I/O Control Register 7 */ +#define SCI_PIO7_ +/* SCI Pin I/O Control Register 8 */ +#define SCI_PIO8_ +/* LIN Compare Register */ +#define LIN_COMPARE_ +/* LIN Receive Buffer 0 Register */ +#define LIN_RD0_ +/* LIN Receive Buffer 1 Register */ +#define LIN_RD1_ +/* LIN Mask Register */ +#define LIN_MASK_ +/* LIN Identification Register */ +#define LIN_ID_ +/* LIN Transmit Buffer 0 */ +#define LIN_TD0_ +/* LIN Transmit Buffer 1 */ +#define LIN_TD1_ +/* Maximum Baud Rate Selection Register */ +#define SCI_MBRS_ +/* Input/Output Error Enable Register */ +#define SCI_IODFTCTRL_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SCI_H */ diff --git a/arch/arm/src/tms570/chip/tms570_sys.h b/arch/arm/src/tms570/chip/tms570_sys.h new file mode 100644 index 00000000000..02227702e80 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_sys.h @@ -0,0 +1,613 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_sys.h + * Primary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_SYS_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* The LPO trim value may be programmed into the TI OTP: */ + +#define TMS570_TITCM_LPOTRIM_OFFSET 0x01b4 +#define TMS570_TITCM_LPOTRIM (TMS570_TITCM_BASE+TMS570_TITCM_LPOTRIM_OFFSET) +# define TMS570_TITCM_LPOTRIM_SHIFT (16) /* Bits 16-31: LPO trim value */ +# define TMS570_TITCM_LPOTRIM_MASK (0xffff << TMS570_TITCM_LPOTRIM_SHIFT) + +/* Register Offsets *********************************************************************************/ + +#define TMS570_SYS_PC1_OFFSET 0x0000 /* SYS Pin Control Register 1 */ +#define TMS570_SYS_PC2_OFFSET 0x0004 /* SYS Pin Control Register 2 */ +#define TMS570_SYS_PC3_OFFSET 0x0008 /* SYS Pin Control Register 3 */ +#define TMS570_SYS_PC4_OFFSET 0x000c /* SYS Pin Control Register 4 */ +#define TMS570_SYS_PC5_OFFSET 0x0010 /* SYS Pin Control Register 5 */ +#define TMS570_SYS_PC6_OFFSET 0x0014 /* SYS Pin Control Register 6 */ +#define TMS570_SYS_PC7_OFFSET 0x0018 /* SYS Pin Control Register 7 */ +#define TMS570_SYS_PC8_OFFSET 0x001c /* SYS Pin Control Register 8 */ +#define TMS570_SYS_PC9_OFFSET 0x0020 /* SYS Pin Control Register 9 */ +#define TMS570_SYS_CSDIS_OFFSET 0x0030 /* Clock Source Disable Register */ +#define TMS570_SYS_CSDISSET_OFFSET 0x0034 /* Clock Source Disable Set Register */ +#define TMS570_SYS_CSDISCLR_OFFSET 0x0038 /* Clock Source Disable Clear Register */ +#define TMS570_SYS_CDDIS_OFFSET 0x003c /* Clock Domain Disable Register */ +#define TMS570_SYS_CDDISSET_OFFSET 0x0040 /* Clock Domain Disable Set Register */ +#define TMS570_SYS_CDDISCLR_OFFSET 0x0044 /* Clock Domain Disable Clear Register */ +#define TMS570_SYS_GHVSRC_OFFSET 0x0048 /* GCLK, HCLK, VCLK, and VCLK2 Source Register */ +#define TMS570_SYS_VCLKASRC_OFFSET 0x004c /* Peripheral Asynchronous Clock Source Register */ +#define TMS570_SYS_RCLKSRC_OFFSET 0x0050 /* RTI Clock Source Register */ +#define TMS570_SYS_CSVSTAT_OFFSET 0x0054 /* Clock Source Valid Status Register */ +#define TMS570_SYS_MSTGCR_OFFSET 0x0058 /* Memory Self-Test Global Control Register */ +#define TMS570_SYS_MINITGCR_OFFSET 0x005c /* Memory Hardware Initialization Global Control Register */ +#define TMS570_SYS_MSIENA_OFFSET 0x0060 /* Memory Self-Test/Initialization Enable Register */ +#define TMS570_SYS_MSTFAIL_OFFSET 0x0064 /* Memory Self-Test Fail Status Register */ +#define TMS570_SYS_MSTCGSTAT_OFFSET 0x0068 /* MSTC Global Status Register */ +#define TMS570_SYS_MINISTAT_OFFSET 0x006c /* Memory Hardware Initialization Status Register */ +#define TMS570_SYS_PLLCTL1_OFFSET 0x0070 /* PLL Control Register 1 */ +#define TMS570_SYS_PLLCTL2_OFFSET 0x0074 /* PLL Control Register 2 */ +#define TMS570_SYS_PC10_OFFSET 0x0078 /* SYS Pin Control Register 10 */ +#define TMS570_SYS_DIEIDL_OFFSET 0x007c /* Die Identification Register, Lower Word */ +#define TMS570_SYS_DIEIDH_OFFSET 0x0080 /* Die Identification Register, Upper Word */ +#define TMS570_SYS_LPOMONCTL_OFFSET 0x0088 /* LPO/Clock Monitor Control Register */ +#define TMS570_SYS_CLKTEST_OFFSET 0x008c /* Clock Test Register */ +#define TMS570_SYS_DFTCTRLREG_OFFSET 0x0090 /* DFT Control Register */ +#define TMS570_SYS_DFTCTRLREG2_OFFSET 0x0094 /* DFT Control Register 2 */ +#define TMS570_SYS_GPREG1_OFFSET 0x00a0 /* General Purpose Register */ +#define TMS570_SYS_IMPFASTS_OFFSET 0x00a8 /* Imprecise Fault Status Register */ +#define TMS570_SYS_IMPFTADD_OFFSET 0x00ac /* Imprecise Fault Write Address Register */ +#define TMS570_SYS_SSIR1_OFFSET 0x00b0 /* System Software Interrupt Request 1 Register */ +#define TMS570_SYS_SSIR2_OFFSET 0x00b4 /* System Software Interrupt Request 2 Register */ +#define TMS570_SYS_SSIR3_OFFSET 0x00b8 /* System Software Interrupt Request 3 Register */ +#define TMS570_SYS_SSIR4_OFFSET 0x00bc /* System Software Interrupt Request 4 Register */ +#define TMS570_SYS_RAMGCR_OFFSET 0x00c0 /* RAM Control Register */ +#define TMS570_SYS_BMMCR1_OFFSET 0x00c4 /* Bus Matrix Module Control Register 1 */ +#define TMS570_SYS_CPURSTCR_OFFSET 0x00cc /* CPU Reset Control Register */ +#define TMS570_SYS_CLKCNTL_OFFSET 0x00d0 /* Clock Control Register */ +#define TMS570_SYS_ECPCNTL_OFFSET 0x00d4 /* ECP Control Register */ +#define TMS570_SYS_DEVCR1_OFFSET 0x00dc /* DEV Parity Control Register 1 */ +#define TMS570_SYS_ECR_OFFSET 0x00e0 /* System Exception Control Register */ +#define TMS570_SYS_ESR_OFFSET 0x00e4 /* System Exception Status Register */ +#define TMS570_SYS_TASR_OFFSET 0x00e8 /* System Test Abort Status Register */ +#define TMS570_SYS_GLBSTAT_OFFSET 0x00ec /* Global Status Register */ +#define TMS570_SYS_DEVID_OFFSET 0x00f0 /* Device Identification Register */ +#define TMS570_SYS_SSIVEC_OFFSET 0x00f4 /* Software Interrupt Vector Register */ +#define TMS570_SYS_SSIF_OFFSET 0x00f8 /* System Software Interrupt Flag Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_SYS_PC1 (TMS570_SYS_BASE+TMS570_SYS_PC1_OFFSET) +#define TMS570_SYS_PC2 (TMS570_SYS_BASE+TMS570_SYS_PC2_OFFSET) +#define TMS570_SYS_PC3 (TMS570_SYS_BASE+TMS570_SYS_PC3_OFFSET) +#define TMS570_SYS_PC4 (TMS570_SYS_BASE+TMS570_SYS_PC4_OFFSET) +#define TMS570_SYS_PC5 (TMS570_SYS_BASE+TMS570_SYS_PC5_OFFSET) +#define TMS570_SYS_PC6 (TMS570_SYS_BASE+TMS570_SYS_PC6_OFFSET) +#define TMS570_SYS_PC7 (TMS570_SYS_BASE+TMS570_SYS_PC7_OFFSET) +#define TMS570_SYS_PC8 (TMS570_SYS_BASE+TMS570_SYS_PC8_OFFSET) +#define TMS570_SYS_PC9 (TMS570_SYS_BASE+TMS570_SYS_PC9_OFFSET) +#define TMS570_SYS_CSDIS (TMS570_SYS_BASE+TMS570_SYS_CSDIS_OFFSET) +#define TMS570_SYS_CSDISSET (TMS570_SYS_BASE+TMS570_SYS_CSDISSET_OFFSET) +#define TMS570_SYS_CSDISCLR (TMS570_SYS_BASE+TMS570_SYS_CSDISCLR_OFFSET) +#define TMS570_SYS_CDDIS (TMS570_SYS_BASE+TMS570_SYS_CDDIS_OFFSET) +#define TMS570_SYS_CDDISSET (TMS570_SYS_BASE+TMS570_SYS_CDDISSET_OFFSET) +#define TMS570_SYS_CDDISCLR (TMS570_SYS_BASE+TMS570_SYS_CDDISCLR_OFFSET) +#define TMS570_SYS_GHVSRC (TMS570_SYS_BASE+TMS570_SYS_GHVSRC_OFFSET) +#define TMS570_SYS_VCLKASRC (TMS570_SYS_BASE+TMS570_SYS_VCLKASRC_OFFSET) +#define TMS570_SYS_RCLKSRC (TMS570_SYS_BASE+TMS570_SYS_RCLKSRC_OFFSET) +#define TMS570_SYS_CSVSTAT (TMS570_SYS_BASE+TMS570_SYS_CSVSTAT_OFFSET) +#define TMS570_SYS_MSTGCR (TMS570_SYS_BASE+TMS570_SYS_MSTGCR_OFFSET) +#define TMS570_SYS_MINITGCR (TMS570_SYS_BASE+TMS570_SYS_MINITGCR_OFFSET) +#define TMS570_SYS_MSIENA (TMS570_SYS_BASE+TMS570_SYS_MSIENA_OFFSET) +#define TMS570_SYS_MSTFAIL (TMS570_SYS_BASE+TMS570_SYS_MSTFAIL_OFFSET) +#define TMS570_SYS_MSTCGSTAT (TMS570_SYS_BASE+TMS570_SYS_MSTCGSTAT_OFFSET) +#define TMS570_SYS_MINISTAT (TMS570_SYS_BASE+TMS570_SYS_MINISTAT_OFFSET) +#define TMS570_SYS_PLLCTL1 (TMS570_SYS_BASE+TMS570_SYS_PLLCTL1_OFFSET) +#define TMS570_SYS_PLLCTL2 (TMS570_SYS_BASE+TMS570_SYS_PLLCTL2_OFFSET) +#define TMS570_SYS_PC10 (TMS570_SYS_BASE+TMS570_SYS_PC10_OFFSET) +#define TMS570_SYS_DIEIDL (TMS570_SYS_BASE+TMS570_SYS_DIEIDL_OFFSET) +#define TMS570_SYS_DIEIDH (TMS570_SYS_BASE+TMS570_SYS_DIEIDH_OFFSET) +#define TMS570_SYS_LPOMONCTL (TMS570_SYS_BASE+TMS570_SYS_LPOMONCTL_OFFSET) +#define TMS570_SYS_CLKTEST (TMS570_SYS_BASE+TMS570_SYS_CLKTEST_OFFSET) +#define TMS570_SYS_DFTCTRLREG (TMS570_SYS_BASE+TMS570_SYS_DFTCTRLREG_OFFSET) +#define TMS570_SYS_DFTCTRLREG2 (TMS570_SYS_BASE+TMS570_SYS_DFTCTRLREG2_OFFSET) +#define TMS570_SYS_GPREG1 (TMS570_SYS_BASE+TMS570_SYS_GPREG1_OFFSET) +#define TMS570_SYS_IMPFASTS (TMS570_SYS_BASE+TMS570_SYS_IMPFASTS_OFFSET) +#define TMS570_SYS_IMPFTADD (TMS570_SYS_BASE+TMS570_SYS_IMPFTADD_OFFSET) +#define TMS570_SYS_SSIR1 (TMS570_SYS_BASE+TMS570_SYS_SSIR1_OFFSET) +#define TMS570_SYS_SSIR2 (TMS570_SYS_BASE+TMS570_SYS_SSIR2_OFFSET) +#define TMS570_SYS_SSIR3 (TMS570_SYS_BASE+TMS570_SYS_SSIR3_OFFSET) +#define TMS570_SYS_SSIR4 (TMS570_SYS_BASE+TMS570_SYS_SSIR4_OFFSET) +#define TMS570_SYS_RAMGCR (TMS570_SYS_BASE+TMS570_SYS_RAMGCR_OFFSET) +#define TMS570_SYS_BMMCR1 (TMS570_SYS_BASE+TMS570_SYS_BMMCR1_OFFSET) +#define TMS570_SYS_CPURSTCR (TMS570_SYS_BASE+TMS570_SYS_CPURSTCR_OFFSET) +#define TMS570_SYS_CLKCNTL (TMS570_SYS_BASE+TMS570_SYS_CLKCNTL_OFFSET) +#define TMS570_SYS_ECPCNTL (TMS570_SYS_BASE+TMS570_SYS_ECPCNTL_OFFSET) +#define TMS570_SYS_DEVCR1 (TMS570_SYS_BASE+TMS570_SYS_DEVCR1_OFFSET) +#define TMS570_SYS_ECR (TMS570_SYS_BASE+TMS570_SYS_ECR_OFFSET) +#define TMS570_SYS_ESR (TMS570_SYS_BASE+TMS570_SYS_ESR_OFFSET) +#define TMS570_SYS_TASR (TMS570_SYS_BASE+TMS570_SYS_TASR_OFFSET) +#define TMS570_SYS_GLBSTAT (TMS570_SYS_BASE+TMS570_SYS_GLBSTAT_OFFSET) +#define TMS570_SYS_DEVID (TMS570_SYS_BASE+TMS570_SYS_DEVID_OFFSET) +#define TMS570_SYS_SSIVEC (TMS570_SYS_BASE+TMS570_SYS_SSIVEC_OFFSET) +#define TMS570_SYS_SSIF (TMS570_SYS_BASE+TMS570_SYS_SSIF_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* SYS Pin Control Register 1 */ + +#define SYS_PC1_ECPCLKFUN (1 << 0) /* Bit 0: ECLK function */ + +/* SYS Pin Control Register 2 */ + +#define SYS_PC2_ECPCLKDIR (1 << 0) /* Bit 0: ECLK data direction */ + +/* SYS Pin Control Register 3 */ + +#define SYS_PC3_ECPCLKDIN (1 << 0) /* Bit 0: ECLK data in */ + +/* SYS Pin Control Register 4 */ + +#define SYS_PC4_ECPCLKDOUT (1 << 0) /* Bit 0: ECLK data out write */ + +/* SYS Pin Control Register 5 */ + +#define SYS_PC5_ECPCLKSET (1 << 0) /* Bit 0: ECLK data out set */ + +/* SYS Pin Control Register 6 */ + +#define SYS_PC6_ECPCLKCLR (1 << 0) /* Bit 0: ECLK data out clear */ + +/* SYS Pin Control Register 7 */ + +#define SYS_PC7_ECPCLKODE (1 << 0) /* Bit 0: ECLK open drain enable */ + +/* SYS Pin Control Register 8 */ + +#define SYS_PC8_ECPCLKPUE (1 << 0) /* Bit 0: ECLK pull enable */ + +/* SYS Pin Control Register 9 */ + +#define SYS_PC9_ECPCLKPS (1 << 0) /* Bit 0: ECLK pull up/pull down select */ + +/* Clock Source Disable Register, Clock Source Disable Set Register, and Clock Source + * Disable Clear Register + */ + +#define SYS_CSDIS_CLKSR0OFF (1 << 0) /* Bit 0: Clock source 0 */ +#define SYS_CSDIS_CLKSR1OFF (1 << 1) /* Bit 1: Clock source 1 */ +#define SYS_CSDIS_CLKSR3OFF (1 << 3) /* Bit 3: Clock source 3 */ +#define SYS_CSDIS_CLKSR4OFF (1 << 4) /* Bit 4: Clock source 4 */ +#define SYS_CSDIS_CLKSR5OFF (1 << 5) /* Bit 5: Clock source 5 */ +#define SYS_CSDIS_CLKSROFFALL (0x3b) + +#define SYS_CSDIS_CLKSRC_OSC SYS_CSDIS_CLKSR0OFF /* Oscillator */ +#define SYS_CSDIS_CLKSRC_PLL SYS_CSDIS_CLKSR1OFF /* PLL */ +#define SYS_CSDIS_CLKSRC_EXTCLKIN SYS_CSDIS_CLKSR3OFF /* EXTCLKIN */ +#define SYS_CSDIS_CLKSRC_LFLPO SYS_CSDIS_CLKSR4OFF /* Low Frequency LPO (Low Power Oscillator) clock */ +#define SYS_CSDIS_CLKSRC_HFLPO SYS_CSDIS_CLKSR5OFF /* High Frequency LPO (Low Power Oscillator) clock */ + +/* Clock Domain Disable Register, Clock Domain Disable Set Register, and Clock Domain + * Disable Clear Register. + */ + +#define SYS_CDDIS_GCLKOFF (1 << 0) /* Bit 0: GCLK domain off */ +#define SYS_CDDIS_HCLKOFF (1 << 1) /* Bit 1: HCLK and VCLK_sys domains off */ +#define SYS_CDDIS_VCLKPOFF (1 << 2) /* Bit 2: VCLK_periph domain off */ +#define SYS_CDDIS_VCLK2OFF (1 << 3) /* Bit 3: VCLK2 domain off */ +#define SYS_CDDIS_VCLKA1OFF (1 << 4) /* Bit 4: VCLKA1 domain off */ +#define SYS_CDDIS_RTICLK1OFF (1 << 6) /* Bit 6: RTICLK1 domain off */ +#define SYS_CDDIS_VCLKEQEPOFF (1 << 9) /* Bit 9: VCLK_EQEP_OFF domain off */ + +/* GCLK, HCLK, VCLK, and VCLK2 Source Register */ + +#define SYS_CLKSRC_OSC 0 /* Alias for oscillator clock Source */ +#define SYS_CLKSRC_PLL1 1 /* Alias for Pll1 clock Source */ +#define SYS_CLKSRC_EXTERNAL1 3 /* Alias for external clock Source */ +#define SYS_CLKSRC_LPOLOW 4 /* Alias for low power oscillator low clock Source */ +#define SYS_CLKSRC_LPOHIGH 5 /* Alias for low power oscillator high clock Source */ +#define SYS_CLKSRC_PLL2 6 /* Alias for Pll2 clock Source */ +#define SYS_CLKSRC_EXTERNAL2 7 /* Alias for external 2 clock Source */ +#define SYS_CLKSRC_VCLK 9 /* Alias for synchronous VCLK1 clock Source */ + +#define SYS_GHVSRC_GHVSRC_SHIFT (0) /* Bits 0-3: GCLK, HCLK, VCLK, VCLK2 current source */ +#define SYS_GHVSRC_GHVSRC_MASK (15 << SYS_GHVSRC_GHVSRC_SHIFT) +# define SYS_GHVSRC_GHVSRC_SRC(n) ((uint32_t)(n) << SYS_GHVSRC_GHVSRC_SHIFT) +# define SYS_GHVSRC_GHVSRC_SRC0 (0 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source0 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC1 (1 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source1 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC2 (2 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source2 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC3 (3 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source3 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC4 (4 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source4 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC5 (5 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source5 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC6 (6 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source6 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC7 (7 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source7 for GCLK, HCLK, VCLK, VCLK2 */ + +# define SYS_GHVSRC_GHVSRC_SRC(n) ((uint32_t)(n) << SYS_GHVSRC_GHVSRC_SHIFT) +# define SYS_GHVSRC_GHVSRC_OSC SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_OSC) +# define SYS_GHVSRC_GHVSRC_PLL1 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_PLL1) +# define SYS_GHVSRC_GHVSRC_EXTERNAL1 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_EXTERNAL1) +# define SYS_GHVSRC_GHVSRC_LPOLOW SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_LPOLOW) +# define SYS_GHVSRC_GHVSRC_LPOHIGH SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_LPOHIGH) +# define SYS_GHVSRC_GHVSRC_PLL2 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_PLL2) +# define SYS_GHVSRC_GHVSRC_EXTERNAL2 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_EXTERNAL2) +# define SYS_GHVSRC_GHVSRC_VCLK SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_VCLK) + +#define SYS_GHVSRC_HVLPM_SHIFT (16) /* Bits 16-19: HCLK, VCLK, VCLK2 source on wakeup when GCLK is turned off */ +#define SYS_GHVSRC_HVLPM_MASK (15 << SYS_GHVSRC_HVLPM_SHIFT) +# define SYS_GHVSRC_HVLPM_SRC0 (0 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source0 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC1 (1 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source1 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC2 (2 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source2 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC3 (3 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source3 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC4 (4 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source4 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC5 (5 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source5 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC6 (6 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source6 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC7 (7 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source7 for HCLK, VCLK, VCLK2 on wakeup */ + +# define SYS_GHVSRC_HVLPM(n) ((uint32_t)(n) << SYS_GHVSRC_HVLPM_SHIFT) +# define SYS_GHVSRC_HVLPM_OSC SYS_GHVSRC_HVLPM(SYS_CLKSRC_OSC) +# define SYS_GHVSRC_HVLPM_PLL1 SYS_GHVSRC_HVLPM(SYS_CLKSRC_PLL1) +# define SYS_GHVSRC_HVLPM_EXTERNAL1 SYS_GHVSRC_HVLPM(SYS_CLKSRC_EXTERNAL1) +# define SYS_GHVSRC_HVLPM_LPOLOW SYS_GHVSRC_HVLPM(SYS_CLKSRC_LPOLOW) +# define SYS_GHVSRC_HVLPM_LPOHIGH SYS_GHVSRC_HVLPM(SYS_CLKSRC_LPOHIGH) +# define SYS_GHVSRC_HVLPM_PLL2 SYS_GHVSRC_HVLPM(SYS_CLKSRC_PLL2) +# define SYS_GHVSRC_HVLPM_EXTERNAL2 SYS_GHVSRC_HVLPM(SYS_CLKSRC_EXTERNAL2) +# define SYS_GHVSRC_HVLPM_VCLK SYS_GHVSRC_HVLPM(SYS_CLKSRC_VCLK) + +#define SYS_GHVSRC_GHVWAKE_SHIFT (24) /* Bits 24-17: GCLK, HCLK, VCLK, VCLK2 source on wakeup */ +#define SYS_GHVSRC_GHVWAKE_MASK (15 << SYS_GHVSRC_GHVWAKE_SHIFT) +# define SYS_GHVSRC_GHVWAKE_SRC0 (0 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source0 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC1 (1 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source1 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC2 (2 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source2 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC3 (3 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source3 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC4 (4 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source4 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC5 (5 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source5 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC6 (6 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source6 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC7 (7 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source7 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ + +# define SYS_GHVSRC_GHVWAKE(n) ((uint32_t)(n) << SYS_GHVSRC_GHVWAKE_SHIFT) +# define SYS_GHVSRC_GHVWAKE_OSC SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_OSC) +# define SYS_GHVSRC_GHVWAKE_PLL1 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_PLL1) +# define SYS_GHVSRC_GHVWAKE_EXTERNAL1 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_EXTERNAL1) +# define SYS_GHVSRC_GHVWAKE_LPOLOW SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_LPOLOW) +# define SYS_GHVSRC_GHVWAKE_LPOHIGH SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_LPOHIGH) +# define SYS_GHVSRC_GHVWAKE_PLL2 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_PLL2) +# define SYS_GHVSRC_GHVWAKE_EXTERNAL2 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_EXTERNAL2) +# define SYS_GHVSRC_GHVWAKE_VCLK SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_VCLK) + +/* Peripheral Asynchronous Clock Source Register */ + +#define SYS_VCLKASRC_VCLKA1S_SHIFT (0) /* Bits 0-3: Peripheral asynchronous clock1 source */ +#define SYS_VCLKASRC_VCLKA1S_MASK (15 << SYS_VCLKASRC_VCLKA1S_SHIFT) +# define SYS_VCLKASRC_VCLKA1S_SRC0 (0 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source0 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC1 (1 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source1 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC2 (2 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source2 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC3 (3 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source3 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC4 (4 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source4 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC5 (5 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source5 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC6 (6 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source6 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC7 (7 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source7 for RTICLK1 */ + +# define SYS_VCLKASRC_VCLKA1S(n) ((uint32_t)(n) << SYS_VCLKASRC_VCLKA1S_SHIFT) +# define SYS_VCLKASRC_VCLKA1S_OSC SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_OSC) +# define SYS_VCLKASRC_VCLKA1S_PLL1 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_PLL1) +# define SYS_VCLKASRC_VCLKA1S_EXTERNAL1 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_EXTERNAL1) +# define SYS_VCLKASRC_VCLKA1S_LPOLOW SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_LPOLOW) +# define SYS_VCLKASRC_VCLKA1S_LPOHIGH SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_LPOHIGH) +# define SYS_VCLKASRC_VCLKA1S_PLL2 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_PLL2) +# define SYS_VCLKASRC_VCLKA1S_EXTERNAL2 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_EXTERNAL2) +# define SYS_VCLKASRC_VCLKA1S_VCLK SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_VCLK) + +/* RTI Clock Source Register */ + +#define SYS_RCLKSRC_RTI1SRC_SHIFT (0) /* Bits 0-3: RTI clock1 source */ +#define SYS_RCLKSRC_RTI1SRC_MASK (15 << SYS_RCLKSRC_RTI1SRC_SHIFT) +# define SYS_RCLKSRC_RTI1SRC_SRC0 (0 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source0 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC1 (1 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source1 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC2 (2 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source2 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC3 (3 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source3 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC4 (4 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source4 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC5 (5 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source5 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC6 (6 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source6 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC7 (7 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source7 for RTICLK1 */ + +# define SYS_RCLKSRC_RTI1SRC(n) ((uint32_t)(n) << SYS_RCLKSRC_RTI1SRC_SHIFT) +# define SYS_RCLKSRC_RTI1SRC_OSC SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_OSC) +# define SYS_RCLKSRC_RTI1SRC_PLL1 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_PLL1) +# define SYS_RCLKSRC_RTI1SRC_EXTERNAL1 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_EXTERNAL1) +# define SYS_RCLKSRC_RTI1SRC_LPOLOW SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_LPOLOW) +# define SYS_RCLKSRC_RTI1SRC_LPOHIGH SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_LPOHIGH) +# define SYS_RCLKSRC_RTI1SRC_PLL2 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_PLL2) +# define SYS_RCLKSRC_RTI1SRC_EXTERNAL2 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_EXTERNAL2) +# define SYS_RCLKSRC_RTI1SRC_VCLK SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_VCLK) + +#define SYS_RCLKSRC_RTI1DIV_SHIFT (8) /* Bits 8-9: RTI clock 1 divider */ +#define SYS_RCLKSRC_RTI1DIV_MASK (3 << SYS_RCLKSRC_RTI1DIV_SHIFT) +# define SYS_RCLKSRC_RTI1DIV_DIV1 (0 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 1 */ +# define SYS_RCLKSRC_RTI1DIV_DIV2 (1 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 2 */ +# define SYS_RCLKSRC_RTI1DIV_DIV4 (2 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 4 */ +# define SYS_RCLKSRC_RTI1DIV_DIV8 (3 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 8 */ + +/* Clock Source Valid Status Register */ +#define SYS_CSVSTAT_ + +/* Memory Self-Test Global Control Register */ + +#define SYS_MSTGCR_CLKSR0V (1 << 0) /* Bit 0: Clock source xx valid */ +#define SYS_MSTGCR_CLKSR1V (1 << 1) /* Bit 1: Clock source xx valid */ +#define SYS_MSTGCR_CLKSR3V (1 << 3) /* Bit 3: Clock source xx valid */ +#define SYS_MSTGCR_CLKSR4V (1 << 4) /* Bit 4: Clock source xx valid */ +#define SYS_MSTGCR_CLKSR5V (1 << 5) /* Bit 5: Clock source xx valid */ +#define SYS_MSTGCR_CLKSRVALL (0x3b) + +/* Memory Hardware Initialization Global Control Register */ + +#define SYS_MINITGCR_MASK (0xff) /* Bits 0-7: Memory hardware initialization key */ +# define SYS_MINITGCR_ENABLE (0x0a) /* Enable */ +# define SYS_MINITGCR_DISABLE (0x05) /* Any other value disables */ + +/* Memory Self-Test/Initialization Enable Register */ + +#define SYS_MSIENA_ + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) || defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) + /* From TMS570LS0x32 Data Sheet */ + +# define SYS_MSIENA_RAM (1 << 0) +# define SYS_MSIENA_VIM_RAM (1 << 2) +# define SYS_MSIENA_N2HET_RAM (1 << 3) +# define SYS_MSIENA_HTU_RAM (1 << 4) +# define SYS_MSIENA_DCAN1_RAM (1 << 5) +# define SYS_MSIENA_DCAN2_RAM (1 << 6) +# define SYS_MSIENA_MIBSPI1_RAM (1 << 7) +# define SYS_MSIENA_MIBADC_RAM (1 << 8) +#endif + +/* Memory Self-Test Fail Status Register */ +#define SYS_MSTFAIL_ + +/* MSTC Global Status Register */ + +#define SYS_MSTCGSTAT_MSTDONE (1 << 0) /* Bit 0: Memory self-test done */ +#define SYS_MSTCGSTAT_MINIDONE (1 << 8) /* Bit 8: Hardware initialization of all memory done */ + +/* Memory Hardware Initialization Status Register */ +#define SYS_MINISTAT_ + +/* PLL Control Register 1 */ + +#define SYS_PLLCTL1_PLLMUL_SHIFT (0) /* Bits 0-15: PLL Multiplication Factor */ +#define SYS_PLLCTL1_PLLMUL_MASK (0xffff << SYS_PLLCTL1_PLLMUL_SHIFT) +# define SYS_PLLCTL1_PLLMUL(n) ((uint32_t)(n) << SYS_PLLCTL1_PLLMUL_SHIFT) +#define SYS_PLLCTL1_REFCLKDIV_SHIFT (16) /* Bits 16-21: Reference Clock Divider */ +#define SYS_PLLCTL1_REFCLKDIV_MASK (0x3f << SYS_PLLCTL1_REFCLKDIV_SHIFT) +# define SYS_PLLCTL1_REFCLKDIV(n) ((uint32_t)(n) << SYS_PLLCTL1_REFCLKDIV_SHIFT) +#define SYS_PLLCTL1_ROF (1 << 23) /* Bit 23: Reset on Oscillator Fail */ +#define SYS_PLLCTL1_PLLDIV_SHIFT (24) /* Bits 24-28: PLL Output Clock Divider */ +#define SYS_PLLCTL1_PLLDIV_MASK (0x1f << SYS_PLLCTL1_PLLDIV_SHIFT) +# define SYS_PLLCTL1_PLLDIV(n) ((uint32_t)(n) << SYS_PLLCTL1_PLLDIV_SHIFT) +# define SYS_PLLCTL1_PLLDIV_MAX SYS_PLLCTL1_PLLDIV_MASK +#define SYS_PLLCTL1_MASKSLIP_SHIFT (29) /* Bits 29-30: Mask detection of PLL slip */ +#define SYS_PLLCTL1_MASKSLIP_MASK (3 << SYS_PLLCTL1_MASKSLIP_SHIFT) +# define SYS_PLLCTL1_MASKSLIP_DISABLE (0 << SYS_PLLCTL1_MASKSLIP_SHIFT) /* All values but 2 disable */ +# define SYS_PLLCTL1_MASKSLIP_ENABLE (2 << SYS_PLLCTL1_MASKSLIP_SHIFT) +#define SYS_PLLCTL1_ROS (1 << 31) /* Bit 31: Reset on PLL Slip */ + +/* PLL Control Register 2 */ + +#define SYS_PLLCTL2_SPRAMOUNT_SHIFT (0) /* Bits 0-8: Spreading Amount */ +#define SYS_PLLCTL2_SPRAMOUNT_MASK (0xff << SYS_PLLCTL2_SPRAMOUNT_SHIFT) +# define SYS_PLLCTL2_SPRAMOUNT(n) ((uint32_t)(n) << SYS_PLLCTL2_SPRAMOUNT_SHIFT) +#define SYS_PLLCTL2_ODPLL_SHIFT (9) /* Bits 9-11: Internal PLL Output Divider */ +#define SYS_PLLCTL2_ODPLL_MASK (7 << SYS_PLLCTL2_ODPLL_SHIFT) +# define SYS_PLLCTL2_ODPLL(n) ((uint32_t)(n) << SYS_PLLCTL2_ODPLL_SHIFT) +#define SYS_PLLCTL2_MULMOD_SHIFT (12) /* Bits 12-20: Multiplier Correction when Frequency Modulation is enabled */ +#define SYS_PLLCTL2_MULMOD_MASK (0x1ff << SYS_PLLCTL2_MULMOD_SHIFT) +# define SYS_PLLCTL2_MULMOD(n) ((uint32_t)(n) << SYS_PLLCTL2_MULMOD_SHIFT) +#define SYS_PLLCTL2_SPRRATE_SHIFT (22) /* Bits 22-30: NS = SPREADINGRATE + 1 */ +#define SYS_PLLCTL2_SPRRATE_MASK (0x1ff << SYS_PLLCTL2_SPRRATE_SHIFT) +# define SYS_PLLCTL2_SPRRATE(n) ((uint32_t)(n) << SYS_PLLCTL2_SPRRATE_SHIFT) +#define SYS_PLLCTL2_FMENA (1 << 31) /* Bit 31: Frequency Modulation Enable */ + +/* SYS Pin Control Register 10 */ + +#define SYS_PC10_ECLCSLEW (1 << 0) /* Bit 0: ECLK slew control */ + +/* Die Identification Register, Lower Word */ +#define SYS_DIEIDL_ +/* Die Identification Register, Upper Word */ +#define SYS_DIEIDH_ +/* LPO/Clock Monitor Control Register */ + +#define SYS_LPOMONCTL_LFTRIM_SHIFT (0) /* Bits 0-4: Low frequency oscillator trim value */ +#define SYS_LPOMONCTL_LFTRIM_MASK (31 << SYS_LPOMONCTL_LFTRIM_SHIFT) +# define SYS_LPOMONCTL_20p67 (0 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 20.67% */ +# define SYS_LPOMONCTL_25p76 (1 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 25.76% */ +# define SYS_LPOMONCTL_30p84 (2 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 30.84% */ +# define SYS_LPOMONCTL_35p90 (3 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 35.90% */ +# define SYS_LPOMONCTL_40p93 (4 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 40.93% */ +# define SYS_LPOMONCTL_45p95 (5 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 45.95% */ +# define SYS_LPOMONCTL_50p97 (6 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 50.97% */ +# define SYS_LPOMONCTL_55p91 (7 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 55.91% */ +# define SYS_LPOMONCTL_60p86 (8 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 60.86% */ +# define SYS_LPOMONCTL_65p78 (9 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 65.78% */ +# define SYS_LPOMONCTL_70p75 (10 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 70.75% */ +# define SYS_LPOMONCTL_75p63 (11 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 75.63% */ +# define SYS_LPOMONCTL_80p61 (12 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 80.61% */ +# define SYS_LPOMONCTL_85p39 (13 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 85.39% */ +# define SYS_LPOMONCTL_90p23 (14 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 90.23% */ +# define SYS_LPOMONCTL_95p11 (15 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 95.11% */ +# define SYS_LPOMONCTL_100p00 (16 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 100.00% */ +# define SYS_LPOMONCTL_104p84 (17 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 104.84% */ +# define SYS_LPOMONCTL_109p51 (18 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 109.51% */ +# define SYS_LPOMONCTL_114p31 (19 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 114.31% */ +# define SYS_LPOMONCTL_119p01 (20 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 119.01% */ +# define SYS_LPOMONCTL_123p75 (21 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 123.75% */ +# define SYS_LPOMONCTL_128p62 (22 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 128.62% */ +# define SYS_LPOMONCTL_133p31 (23 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 133.31% */ +# define SYS_LPOMONCTL_138p03 (24 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 138.03% */ +# define SYS_LPOMONCTL_142p75 (25 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 142.75% */ +# define SYS_LPOMONCTL_147p32 (26 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 147.32% */ +# define SYS_LPOMONCTL_152p02 (27 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 152.02% */ +# define SYS_LPOMONCTL_156p63 (28 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 156.63% */ +# define SYS_LPOMONCTL_161p38 (29 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 161.38% */ +# define SYS_LPOMONCTL_165p90 (30 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 165.90% */ +# define SYS_LPOMONCTL_170p42 (31 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 170.42% */ +#define SYS_LPOMONCTL_HFTRIM_SHIFT (8) /* Bits 8-12: High frequency oscillator trim value */ +#define SYS_LPOMONCTL_HFTRIM_MASK (31 << SYS_LPOMONCTL_HFTRIM_SHIFT) +# define SYS_LPOMONCTL_HFTRIM_29p52 (0 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 29.52% */ +# define SYS_LPOMONCTL_HFTRIM_34p24 (1 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 34.24% */ +# define SYS_LPOMONCTL_HFTRIM_38p85 (2 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 38.85% */ +# define SYS_LPOMONCTL_HFTRIM_43p45 (3 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 43.45% */ +# define SYS_LPOMONCTL_HFTRIM_47p99 (4 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 47.99% */ +# define SYS_LPOMONCTL_HFTRIM_52p55 (5 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 52.55% */ +# define SYS_LPOMONCTL_HFTRIM_57p02 (6 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 57.02% */ +# define SYS_LPOMONCTL_HFTRIM_61p46 (7 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 61.46% */ +# define SYS_LPOMONCTL_HFTRIM_65p92 (8 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 65.92% */ +# define SYS_LPOMONCTL_HFTRIM_70p17 (9 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 70.17% */ +# define SYS_LPOMONCTL_HFTRIM_74p55 (10 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 74.55% */ +# define SYS_LPOMONCTL_HFTRIM_78p92 (11 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 78.92% */ +# define SYS_LPOMONCTL_HFTRIM_83p17 (12 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 83.17% */ +# define SYS_LPOMONCTL_HFTRIM_87p43 (13 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 87.43% */ +# define SYS_LPOMONCTL_HFTRIM_91p75 (14 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 91.75% */ +# define SYS_LPOMONCTL_HFTRIM_95p89 (15 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 95.89% */ +# define SYS_LPOMONCTL_HFTRIM_100p00 (16 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 100.00% */ +# define SYS_LPOMONCTL_HFTRIM_104p09 (17 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 104.09% */ +# define SYS_LPOMONCTL_HFTRIM_108p17 (18 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 108.17% */ +# define SYS_LPOMONCTL_HFTRIM_112p32 (19 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 112.32% */ +# define SYS_LPOMONCTL_HFTRIM_116p41 (20 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 116.41% */ +# define SYS_LPOMONCTL_HFTRIM_120p67 (21 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 120.67% */ +# define SYS_LPOMONCTL_HFTRIM_124p42 (22 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 124.42% */ +# define SYS_LPOMONCTL_HFTRIM_128p38 (23 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 128.38% */ +# define SYS_LPOMONCTL_HFTRIM_132p24 (24 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 132.24% */ +# define SYS_LPOMONCTL_HFTRIM_136p15 (25 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 136.15% */ +# define SYS_LPOMONCTL_HFTRIM_140p15 (26 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 140.15% */ +# define SYS_LPOMONCTL_HFTRIM_143p94 (27 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 143.94% */ +# define SYS_LPOMONCTL_HFTRIM_148p02 (28 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 148.02% */ +# define SYS_LPOMONCTL_HFTRIM_151p80 (29 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 151.80% */ +# define SYS_LPOMONCTL_HFTRIM_155p50 (30 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 155.50% */ +# define SYS_LPOMONCTL_HFTRIM_159p35 (31 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 159.35% */ +#define SYS_LPOMONCTL_OSCFRQCONFIGCNT (1 << 16) /* Bit 16: Configures the counter based on OSC frequency. */ +#define SYS_LPOMONCTL_BIASENABLE (1 << 24) /* Bit 24: Bias enable. */ + +/* Clock Test Register */ +#define SYS_CLKTEST_ +/* DFT Control Register */ +#define SYS_DFTCTRLREG_ +/* DFT Control Register 2 */ +#define SYS_DFTCTRLREG2_ +/* General Purpose Register */ +#define SYS_GPREG1_ +/* Imprecise Fault Status Register */ +#define SYS_IMPFASTS_ +/* Imprecise Fault Write Address Register */ +#define SYS_IMPFTADD_ +/* System Software Interrupt Request 1 Register */ +#define SYS_SSIR1_ +/* System Software Interrupt Request 2 Register */ +#define SYS_SSIR2_ +/* System Software Interrupt Request 3 Register */ +#define SYS_SSIR3_ +/* System Software Interrupt Request 4 Register */ +#define SYS_SSIR4_ +/* RAM Control Register */ +#define SYS_RAMGCR_ +/* Bus Matrix Module Control Register 1 */ +#define SYS_BMMCR1_ +/* CPU Reset Control Register */ +#define SYS_CPURSTCR_ + +/* Clock Control Register */ + +#define SYS_CLKCNTL_PENA (1 << 8) /* Bit 8: Peripheral enable bit */ +#define SYS_CLKCNTL_VCLKR_SHIFT (16) /* Bits 16-19: VBUS clock ratio */ +#define SYS_CLKCNTL_VCLKR_MASK (15 << SYS_CLKCNTL_VCLKR_SHIFT) +# define SYS_CLKCNTL_VCLKR_DIV1 (0 << SYS_CLKCNTL_VCLKR_SHIFT) +# define SYS_CLKCNTL_VCLKR_DIV2 (1 << SYS_CLKCNTL_VCLKR_SHIFT) +#define SYS_CLKCNTL_VCLKR2_SHIFT (24) /* Bits 24-27: VBUS clock2 ratio */ +#define SYS_CLKCNTL_VCLKR2_MASK (15 << SYS_CLKCNTL_VCLKR2_SHIFT) +# define SYS_CLKCNTL_VCLKR2_DIV1 (0 << SYS_CLKCNTL_VCLKR2_SHIFT) +# define SYS_CLKCNTL_VCLKR2_DIV2 (1 << SYS_CLKCNTL_VCLKR2_SHIFT) + +/* ECP Control Register */ + +#define SYS_ECPCNTL_ECPDIV_SHIFT (0) /* Bits 0-15: ECP divider value */ +#define SYS_ECPCNTL_ECPDIV_MASK (0xffff << SYS_ECPCNTL_ECPDIV_SHIFT) +# define SYS_ECPCNTL_ECPDIV(n) ((uint32_t)(n) << SYS_ECPCNTL_ECPDIV_SHIFT) +#define SYS_ECPCNTL_ECPINSEL_SHIFT (16) /* Bits 16-17: Select ECP input clock source */ +#define SYS_ECPCNTL_ECPINSEL_MASK (3 << SYS_ECPCNTL_ECPINSEL_SHIFT) +# define SYS_ECPCNTL_ECPINSEL_LOW (0 << SYS_ECPCNTL_ECPINSEL_SHIFT) /* Tied Low */ +# define SYS_ECPCNTL_ECPINSEL_HCLK (1 << SYS_ECPCNTL_ECPINSEL_SHIFT) /* HCLK */ +# define SYS_ECPCNTL_ECPINSEL_EXTCLK (2 << SYS_ECPCNTL_ECPINSEL_SHIFT) /* External clock */ +#define SYS_ECPCNTL_ECPCOS (1 << 23) /* Bit 23: ECP continue on suspend */ +#define SYS_ECPCNTL_ECPSSEL (1 << 24) /* Bit 24: Select VCLK os OSCIN as for ECLK */ + +/* DEV Parity Control Register 1 */ +#define SYS_DEVCR1_ +/* System Exception Control Register */ +#define SYS_ECR_ +/* System Exception Status Register */ + +#define SYS_ESR_MPMODE (1 << 0) /* Bit 0: Current memory protection unit (MPU) mode */ +#define SYS_ESR_EXTRST (1 << 3) /* Bit 3: External reset flag */ +#define SYS_ESR_SWRST (1 << 4) /* Bit 4: Software reset flag */ +#define SYS_ESR_CPURST (1 << 5) /* Bit 5: CPU reset flag */ +#define SYS_ESR_WDRST (1 << 13) /* Bit 13: Watchdog reset flag */ +#define SYS_ESR_OSCRST (1 << 14) /* Bit 14: Reset caused by an oscillator failure or PLL cycle slip */ +#define SYS_ESR_PORST (1 << 15) /* Bit 15: Power-up reset */ + +#define SYS_ESR_RSTALL (0x0000e038) + +/* System Test Abort Status Register */ +#define SYS_TASR_ +/* Global Status Register */ +#define SYS_GLBSTAT_ +/* Device Identification Register */ +#define SYS_DEVID_ +/* Software Interrupt Vector Register */ +#define SYS_SSIVEC_ +/* System Software Interrupt Flag Register */ +#define SYS_SSIF_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS_H */ diff --git a/arch/arm/src/tms570/chip/tms570_sys2.h b/arch/arm/src/tms570/chip/tms570_sys2.h new file mode 100644 index 00000000000..9edb33cd396 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_sys2.h @@ -0,0 +1,93 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_sys2.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * 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_TMS570_CHIP_TMS570_SYS2_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS2_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_SYS2_STCCLKDIV_OFFSET 0x0008 /* CPU Logic BIST Clock Divider */ +#define TMS570_SYS2_CLKSLIP_OFFSET 0x0070 /* Clock Slip Register */ +#define TMS570_SYS2_EFC_CTLREG_OFFSET 0x00ec /* EFUSE Controller Control Register */ +#define TMS570_SYS2_DIEDL_REG0_OFFSET 0x00f0 /* Die Identification Register Lower Word */ +#define TMS570_SYS2_DIEDH_REG1_OFFSET 0x00f4 /* Die Identification Register Upper Word */ +#define TMS570_SYS2_DIEDL_REG2_OFFSET 0x00f8 /* Die Identification Register Lower Word */ +#define TMS570_SYS2_DIEDH_REG3_OFFSET 0x00fc /* Die Identification Register Upper Word */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_SYS2_STCCLKDIV (TMS570_SYS2_BASE+TMS570_SYS2_STCCLKDIV_OFFSET) +#define TMS570_SYS2_CLKSLIP (TMS570_SYS2_BASE+TMS570_SYS2_CLKSLIP_OFFSET) +#define TMS570_SYS2_EFC_CTLREG (TMS570_SYS2_BASE+TMS570_SYS2_EFC_CTLREG_OFFSET) +#define TMS570_SYS2_DIEDL_REG0 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDL_REG0_OFFSET) +#define TMS570_SYS2_DIEDH_REG1 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDH_REG1_OFFSET) +#define TMS570_SYS2_DIEDL_REG2 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDL_REG2_OFFSET) +#define TMS570_SYS2_DIEDH_REG3 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDH_REG3_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* CPU Logic BIST Clock Divider */ +#define SYS2_STCCLKDIV_ +/* Clock Slip Register */ +#define SYS2_CLKSLIP_ +/* EFUSE Controller Control Register */ +#define SYS2_EFC_CTLREG_ +/* Die Identification Register Lower Word */ +#define SYS2_DIEDL_REG0_ +/* Die Identification Register Upper Word */ +#define SYS2_DIEDH_REG1_ +/* Die Identification Register Lower Word */ +#define SYS2_DIEDL_REG2_ +/* Die Identification Register Upper Word */ +#define SYS2_DIEDH_REG3_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS2_H */ diff --git a/arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h b/arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h new file mode 100644 index 00000000000..df12323497d --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h @@ -0,0 +1,131 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_TMS570_CHIP_TMS570LS04X03X_MEMORYMAP_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_MEMORYMAP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Memory Map Overview */ + +#define TMS570_FLASH_BASE 0x00000000 /* 0x00000000-0x0005ffff: Program FLASH */ + /* 0x00060000-0x07ffffff: Reserved */ +#define TMS570_RAM_BASE 0x08000000 /* 0x08000000-0x08007fff: RAM */ + /* 0x08008000-0x1fffffff: Reserved */ +#define TMS570_MIRROR_BASE 0x20000000 /* 0x20000000-0x2005ffff: Program FLASH mirror */ + /* 0x20060000-0xefffffff: Reserved */ +#define TMS570_BUS2_BASE 0xf0000000 /* 0xf0000000-0xf07fffff: Flash Module BUS2 Interface */ + /* 0xf0800000-0xfbffffff: Reserved */ +#define TMS570_PERIPH2_BASE 0xfc000000 /* 0xfc000000-0xfcffffff: Peripherals - Frame 2 */ + /* 0xfd000000-0xfdffffff: Reserved */ +#define TMS570_CRC_BASE 0xfe000000 /* 0xfe000000-0xfeffffff: CRC */ +#define TMS570_PERIPH1_BASE 0xff000000 /* 0xff000000-0xff7fffff: Peripherals - Frame 1 */ +#define TMS570_SYSTEM_BASE 0xfff80000 /* 0xff800000-0xffffffff: System Modules */ + +/* Flash Bus2 Interface: OTP, ECC, EEPROM Bank */ + +#define TMS570_CUSTTCM_BASE 0xf0000000 /* 0xf0000000-0xf000dfff: Customer OTP, TCM FLASH bank */ +#define TMS570_CUSTEEPROM_BASE 0xf000e000 /* 0xf000e000-0xf000ffff: Customer OTP, EEPROM bank */ +#define TMS570_CUSTECC_BASE 0xf0040000 /* 0xf0040000-0xf00403ff: Customer OTP-ECC, TCM FLASH bank */ +#define TMS570_CUSTECCEEPROM_BASE 0xf0040000 /* 0xf0041c00-0xf0041fff: Customer OTP-ECC, EEPROM bank */ + +#define TMS570_TITCM_BASE 0xf0080000 /* 0xf0080000-0xf008dfff: TI OTP, TCM FLASH bank */ +#define TMS570_TIEEPROM_BASE 0xf008e000 /* 0xf008e000-0xf008ffff: TI OTP, EEPROM bank */ +#define TMS570_TIECC_BASE 0xf00c0000 /* 0xf00c0000-0xf00c03ff: TI OTP-ECC, TCM FLASH bank */ +#define TMS570_TIECCEEPROM_BASE 0xf00c1c00 /* 0xf00c1c00-0xf00c1fff: TI OTP-ECC, EEPROM bank */ + +#define TMS570_EEC_BASE 0xf0100000 /* 0xf0100000-0xf013ffff: EEPROM Bank - EEC */ +#define TMS570_EEPROM_BASE 0xf0200000 /* 0xf0200000-0xf03fffff: EEPROM Bank */ +#define TMS570_FDATA_BASE 0xf0400000 /* 0xf0400000-0xf04fffff: FLASH Data Space - ECC */ + +/* Debug Components */ + +#define TMS570_CORESIGHT_BASE 0xffa00000 /* 0xffa00000-0xffa00fff: CoreSight Debug ROM */ +#define TMS570_CORTEXR4_BASE 0xffa01000 /* 0xffa01000-0xffa01fff: Cortex-R4 Debug */ + +/* Peripheral Memories */ + +#define TMS570_MIBSPI1RAM_BASE 0xff0e0000 /* 0xff0e0000-0xff0fffff: MIBSPI1 RAM */ +#define TMS570_DCAN2RAM_BASE 0xff1c0000 /* 0xff1c0000-0xff1dffff: DCAN2 RAM */ +#define TMS570_DCAN1RAM_BASE 0xff1e0000 /* 0xff1c0000-0xff1fffff: DCAN1 RAM */ +#define TMS570_MIBADCRAM_BASE 0xff3e0000 /* 0xff3e0000-0xff3fffff: MIBADC RAM */ +#define TMS570_MIBADCLUT_BASE 0xff3e0000 /* 0xff3e0000-0xff3fffff: MIBADC Lookup Table */ +#define TMS570_N2HETRAM_BASE 0xff460000 /* 0xff460000-0xff47ffff: N2HET RAM */ +#define TMS570_HETTURAM_BASE 0xff4e0000 /* 0xff4e0000-0xff4fffff: HET TU RAM */ + +/* Peripheral Control Registers */ + +#define TMS570_HTU_BASE 0xfff7a400 /* 0xfff7a400-0xfff7a4ff: HTU */ +#define TMS570_N2HET_BASE 0xfff7b800 /* 0xfff7b800-0xfff7b8ff: N2HET */ +#define TMS570_GIO_BASE 0xfff7bc00 /* 0xfff7bc00-0xfff7bcff: GIO */ +#define TMS570_MIBADC_BASE 0xfff7bc00 /* 0xfff7c000-0xfff7c1ff: MIBADC */ +#define TMS570_DCAN1_BASE 0xfff7dc00 /* 0xfff7dc00-0xfff7ddff: DCAN1 */ +#define TMS570_DCAN2_BASE 0xfff7de00 /* 0xfff7de00-0xfff7dfff: DCAN2 */ +#define TMS570_SCI1_BASE 0xfff7e400 /* 0xfff7e400-0xfff7e4ff: SCI1/LIN1 */ +#define TMS570_MIBSPI1_BASE 0xfff7f400 /* 0xfff7f400-0xfff7f5ff: MibSPI1 */ +#define TMS570_SPI2_BASE 0xfff7f600 /* 0xfff7f600-0xfff7f7ff: SPI2 */ +#define TMS570_SPI3_BASE 0xfff7f800 /* 0xfff7f800-0xfff7f9ff: SPI3 */ +#define TMS570_EQEP_BASE 0xfff79900 /* 0xfff79900-0xfff799ff: EQEP */ +#define TMS570_EQEPM_BASE 0xfcf79900 /* 0xfcf79900-0xfcf799ff: EQEP (Mirrored) */ + +/* System Modules Control Registers and Memories */ + +#define TMS570_VIMRAM_BASE 0xfff82000 /* 0xfff82000-0xfff82fff: VIM RAM */ +#define TMS570_FWRAP_BASE 0xfff87000 /* 0xfff87000-0xfff87fff: Flash Wrapper */ +#define TMS570_EFFC_BASE 0xfff8c000 /* 0xfff8c000-0xfff8cfff: eFuse Farm Controller */ +#define TMS570_PCR_BASE 0xffffe000 /* 0xffffe000-0xffffe0ff: PCR registers */ +#define TMS570_SYS2_BASE 0xffffe100 /* 0xffffe100-0xffffe1ff: System Module - Frame 2 */ +#define TMS570_PBIST_BASE 0xffffe400 /* 0xffffe400-0xffffe5ff: PBIST */ +#define TMS570_STC_BASE 0xffffe600 /* 0xffffe600-0xffffe6ff: STC */ +#define TMS570_IOMM_BASE 0xffffea00 /* 0xffffea00-0xffffeBff: IOMM Multiplexing */ +#define TMS570_DCC_BASE 0xffffec00 /* 0xffffec00-0xffffeCff: DCC */ +#define TMS570_ESM_BASE 0xfffff500 /* 0xfffff500-0xfffff5ff: ESM */ +#define TMS570_CCMR4_BASE 0xfffff600 /* 0xfffff600-0xfffff6ff: CCM-R4 */ +#define TMS570_RAMECCE_BASE 0xfffff800 /* 0xfffff800-0xfffff8ff: RAM ECC even */ +#define TMS570_RAMECCO_BASE 0xfffff900 /* 0xfffff900-0xfffff9ff: RAM ECC odd */ +#define TMS570_RTIDWWD_BASE 0xfffffc00 /* 0xfffffc00-0xfffffcff: RTI + DWWD */ +#define TMS570_VIMPAR_BASE 0xfffffd00 /* 0xfffffd00-0xfffffdff: VIM Parity */ +#define TMS570_VIM_BASE 0xfffffe00 /* 0xfffffe00-0xfffffeff: VIM */ +#define TMS570_SYS_BASE 0xffffff00 /* 0xffffff00-0xffffffff: System Module - Frame 1 */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_MEMORYMAP_H */ diff --git a/arch/arm/src/tms570/tms570_boot.c b/arch/arm/src/tms570/tms570_boot.c new file mode 100644 index 00000000000..593c2432131 --- /dev/null +++ b/arch/arm/src/tms570/tms570_boot.c @@ -0,0 +1,321 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_boot.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This is primarily original code. However, some logic in this file was + * inspired/leveraged from TI's Project0 which has a compatible BSD license + * and credit should be given in any case: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * 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 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 + +#include +#include +#include + +#include + +#include "chip.h" +#include "arm.h" +#include "cache.h" +#include "fpu.h" +#include "sctlr.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/tms570_sys.h" +#include "chip/tms570_esm.h" +#include "tms570_clockconfig.h" +#include "tms570_boot.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ARMV7R_MEMINIT +# error CONFIG_ARMV7R_MEMINIT is required by this architecture. +#endif + +#ifndef CONFIG_ARCH_LOWVECTORS +# error CONFIG_ARCH_LOWVECTORS is required by this architecture. +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_event_export + * + * Description: + * Enable CPU Event Export by setting the X bit in the PMCR. In general, + * this bit enables the exporting of events to another debug device, such + * as a trace macrocell, over an event bus. + * + * For the TMS570, this allows the CPU to signal any single-bit or double + * -bit errors detected by its ECC logic for accesses to program flash or + * data RAM. + * + ****************************************************************************/ + +static inline void tms570_event_export(void) +{ + uint32_t pmcr = cp15_rdpmcr(); + pmcr |= PCMR_X; + cp15_wrpmcr(pmcr); +} + +/**************************************************************************** + * Name: tms570_enable_ramecc + * + * Description: + * This function enables the CPU's ECC logic for accesses to B0TCM and + * B1TCM. + * + ****************************************************************************/ + +static inline void tms570_enable_ramecc(void) +{ + uint32_t actlr = cp15_rdactlr(); + actlr |= 0x0c000000; + cp15_wractlr(actlr); +} + +/**************************************************************************** + * Name: tms570_memory_initialize + * + * Description: + * Perform memroy initialization of selected RAMs + * + * This function uses the system module's hardware for auto-initialization + * of memories and their associated protection schemes. + * + ****************************************************************************/ + +static void tms570_memory_initialize(uint32_t ramset) +{ + /* Enable Memory Hardware Initialization */ + + putreg32(SYS_MINITGCR_ENABLE, TMS570_SYS_MINITGCR); + + /* Enable Memory Hardware Initialization for selected RAM's */ + + putreg32(ramset, TMS570_SYS_MSIENA); + + /* Wait until Memory Hardware Initialization complete */ + + while((getreg32(TMS570_SYS_MSTCGSTAT) & SYS_MSTCGSTAT_MINIDONE) == 0); + + /* Disable Memory Hardware Initialization */ + + putreg32(SYS_MINITGCR_DISABLE, TMS570_SYS_MINITGCR); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + * Boot Sequence + * + * 1. The __start entry point in armv7-r/arm_head.S is invoked upon power- + * on reset. + * 2. __start prepares CPU for code execution. + * 3a. If CONFIG_ARMV7R_MEMINIT is not defined, then __start will prepare + * memory resources by calling arm_data_initialize() and will then + * call this function. + * 3b. Otherwise, this function will be called without having initialized + * memory resources! We need to be very careful in this case. Here, + * this function will call tms570_boardinitialize() which, among other + * things, much initialize SDRAM memory. Upon return, this function + * will call arm_data_initialize() to initialize the memory resources + * 4. This function will initialize all TMS570-specific resources and + * return to __start. + * 4. _start will then branch to os_start() to start the operating system. + * + ****************************************************************************/ + +void arm_boot(void) +{ + /* Enable CPU Event Export. + * + * This allows the CPU to signal any single-bit or double-bit errors + * detected by its ECC logic for accesses to program flash or data RAM. + */ + + tms570_event_export(); + + /* Read from the system exception status register to identify the cause of + * the CPU reset. + * + * REVISIT: This logic is not used in the current design. But if you + * need to know the cause of the reset, here is where you would want + * to do that. + */ + + DEBUGASSERT((getreg(TMS570_SYS_ESR) & SYS_ESR_PORST) != 0); + + /* Clear all reset status flags on successful power on reset */ + + putreg32(SYS_ESR_RSTALL, TMS570_SYS_ESR); + + /* Check if there were ESM group3 errors during power-up. + * + * These could occur during eFuse auto-load or during reads from flash OTP + * during power-up. Device operation is not reliable and not recommended + * in this case. + * + * An ESM group3 error only drives the nERROR pin low. An external circuit + * that monitors the nERROR pin must take the appropriate action to ensure + * that the system is placed in a safe state, as determined by the + * application. + */ + + ASSERT(getreg32(TMS570_ESM_SR3) == 0); + + /* Initialize clocking to settings provided by board-specific logic */ + + tms570_clockconfig(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Run a diagnostic check on the memory self-test controller. */ +# warning Missing logic + + /* Run PBIST on CPU RAM. */ +# warning Missing logic + + /* Disable PBIST clocks and disable memory self-test mode */ +# warning Missing logic +#endif /* CONFIG_TMS570_SELFTEST */ + + /* Initialize CPU RAM. */ + + tms570_memory_initialize(SYS_MSIENA_RAM); + + /* Enable ECC checking for TCRAM accesses. */ + + tms570_enable_ramecc(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Perform PBIST on all dual-port memories */ +#warning Missing logic + + /* Test the CPU ECC mechanism for RAM accesses. */ +#warning Missing logic + +#endif /* CONFIG_TMS570_SELFTEST */ + + /* Release the MibSPI1 modules from local reset. */ +#warning Missing logic + + /* Initialize all on-chip SRAMs except for MibSPIx RAMs. + * + * The MibSPIx modules have their own auto-initialization mechanism which + * is triggered as soon as the modules are brought out of local reset. + * + * The system module auto-init will hang on the MibSPI RAM if the module + * is still in local reset. + */ + + tms570_memory_initialize(SYS_MSIENA_VIM_RAM +#ifdef CONFIG_TMS570_N2HET + | SYS_MSIENA_N2HET_RAM | SYS_MSIENA_HTU_RAM +#endif +#ifdef CONFIG_TMS570_DCAN1 + | SYS_MSIENA_DCAN1_RAM +#endif +#ifdef CONFIG_TMS570_DCAN2 + | SYS_MSIENA_DCAN2_RAM +#endif +#ifdef CONFIG_TMS570_MIBASPI1 + | SYS_MSIENA_MIBADC_RAM +#endif + ); + +#ifdef CONFIG_ARCH_FPU + /* Initialize the FPU */ + + arm_fpuconfig(); +#endif + +#ifdef CONFIG_ARMV7R_MEMINIT + /* Initialize the .bss and .data sections as well as RAM functions + * now after RAM has been initialized. + * + * NOTE that if SDRAM were supported, this call might have to be + * performed after returning from tms570_board_initialize() + */ + + arm_data_initialize(); +#endif + + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (GPIOs, LEDs, etc). + * + * NOTE: We must use caution prior to this point to make sure that + * the logic does not access any global variables that might lie + * in SDRAM. + */ + + tms570_board_initialize(); + + /* Perform common, low-level chip initialization (might do nothing) */ + + tms570_lowsetup(); + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization if we are going to use the serial + * driver. + */ + + up_earlyserialinit(); +#endif +} diff --git a/arch/arm/src/tms570/tms570_boot.h b/arch/arm/src/tms570/tms570_boot.h new file mode 100644 index 00000000000..a674095d11a --- /dev/null +++ b/arch/arm/src/tms570/tms570_boot.h @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/arm/src/samv7/tms570_start.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_SAMV7_SAM_START_H +#define __ARCH_ARM_SRC_SAMV7_SAM_START_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the linker + * script. _ebss lies at the end of the BSS region. The idle task stack starts at + * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is + * the thread that the system boots on and, eventually, becomes the IDLE, do + * nothing task that runs only when there is nothing else to run. The heap + * continues from there until the end of memory. g_idle_topstack is a read-only + * variable the provides this computed address. + */ + +EXTERN const uintptr_t g_idle_topstack; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: tms570_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void tms570_lowsetup(void); + +/************************************************************************************ + * Name: tms570_boardinitialize + * + * Description: + * All TMS570 architectures must provide the following entry point. This function + * is called near the beginning of _start. This function is called after clocking + * has been configured but before caches have been enabled and before any devices + * have been initialized. .data/.bss memory may or may not have been initialized + * (see the "special precautions" below). + * + * This function must perform low level initialization including + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (GPIOs, LEDs, etc). + * - Setup of the console UART. This UART done early so that the serial console + * is available for debugging very early in the boot sequence. + * + * Special precautions must be taken if .data/.bss lie in SRAM. in that case, + * the boot logic cannot initialize .data or .bss. The function must then: + * + * - Take precautions to assume that logic does not access any global data that + * might lie in SDRAM. + * - Call the function arm_data_initialize() as soon as SDRAM has been + * properly configured for use. + * + ************************************************************************************/ + +void tms570_board_initialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_START_H */ diff --git a/arch/arm/src/tms570/tms570_clockconfig.c b/arch/arm/src/tms570/tms570_clockconfig.c new file mode 100644 index 00000000000..ca40dc1a177 --- /dev/null +++ b/arch/arm/src/tms570/tms570_clockconfig.c @@ -0,0 +1,483 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_clockconfig.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this file was inspired/leveraged from TI's Project0 which + * has a compatible BSD license: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * 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 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 + +#include + +#include + +#include "up_arch.h" + +#include "chip/tms570_sys.h" +#include "chip/tms570_pcr.h" +#include "chip/tms570_flash.h" +#include "tms570_clockconfig.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_pll_setup + * + * Description: + * Configure PLL control registers. The PLL takes (127 + 1024 NR) + * oscillator cycles to acquire lock. This initialization sequence + * performs all the actions that are not required to be done at full + * application speed while the PLL locks. + * + ****************************************************************************/ + +static void tms570_pll_setup(void) +{ + uint32_t regval; + + /* Configure PLL control registers */ + + /* Setup pll control register 1 + * + * REFCLKDIV controls input clock divider: + * + * NR = REFCLKDIV+1 + * Fintclk = Fclkin / NR + * + * PLLMUL controls multipler on divided input clock (Fintclk): + * + * Non-modulated: + * NF = (PLLMUL + 256) / 256 + * Modulated: + * NF = (PLLMUL + MULMOD + 256) / 256 + * + * Foutputclk = Fintclk x NF (150MHz - 550MHz) + * + * ODPLL controls internal PLL output divider: + * + * OD = ODPLL+1 + * Fpostodclk = Foutputclock / OD + * + * Final divisor, R, controls PLL output: + * + * R = PLLDIV + 1 + * Fpllclock = Fpostodclk / R + * + * Or: + * + * Fpllclock = = (Fclkin / NR) x NF / OD / R + * + * For example, if the clock source is a 16MHz crystal, then + * + * Fclkin = 16,000,000 + * NR = 6 (REFCLKDIV=5) + * NF = 120 (PLLMUL = 119 * 256) + * OD = 1 (ODPLL = 0) + * R = 32 (PLLDIV=31) + * + * Then: + * + * Fintclk = 16 MHz / 6 = 2.667 MHz + * Foutputclock = 2.667 MHz * 120 = 320 MHz + * Fpostodclock = 320 MHz / 2 = 160 MHz + * Fpllclock = 160 MHz / 2 = 80 MHz + * + * NOTE: That R is temporary set to the maximum (32) here. + */ + + regval = SYS_PLLCTL1_PLLMUL((BOARD_PLL_NF - 1) << 8) | + SYS_PLLCTL1_REFCLKDIV(BOARD_PLL_NR - 1) | + SYS_PLLCTL1_PLLDIV_MAX | + SYS_PLLCTL1_MASKSLIP_DISABLE; + putreg32(regval, TMS570_SYS_PLLCTL1); + + /* Setup pll control register 2 */ + + regval = SYS_PLLCTL2_SPRAMOUNT(61) | + SYS_PLLCTL2_ODPLL(BOARD_PLL_OD - 1) | + SYS_PLLCTL2_MULMOD(7) | + SYS_PLLCTL2_SPRRATE(255); + putreg32(regval, TMS570_SYS_PLLCTL2); + + /* Enable PLL(s) to start up or Lock. + * + * On wakeup, only clock sources 0, 4, and 5 are enabled: Oscillator, Low + * and high Frequency LPO. Clear bit 1 to enable the PLL. Only the + * external clock remains disabled. + */ + + regval = SYS_CSDIS_CLKSRC_EXTCLKIN; + putreg32(regval, TMS570_SYS_CSDIS); +} + +/**************************************************************************** + * Name: tms570_peripheral_initialize + * + * Description: + * Release peripherals from reset and enable clocks to all peripherals. + * + ****************************************************************************/ + +static void tms570_peripheral_initialize(void) +{ + uint32_t regval; + uint32_t clkcntl; + + /* Disable Peripherals by clearing the PENA bit in the CLKCNTRL register + * before peripheral powerup + */ + + clkcntl = getreg32(TMS570_SYS_CLKCNTL); + clkcntl &= ~SYS_CLKCNTL_PENA; + putreg32(clkcntl, TMS570_SYS_CLKCNTL); + + /* Release peripherals from reset and enable clocks to all peripherals. + * Power-up all peripherals by clearing the power down bit for each + * quadrant of each peripheral. + * + * REVISIT: Should we only enable peripherals that are configured? + */ + + regval = PCR_PSPWERDWN0_PS0_QALL | PCR_PSPWERDWN0_PS1_QALL | + PCR_PSPWERDWN0_PS2_QALL | PCR_PSPWERDWN0_PS3_QALL | + PCR_PSPWERDWN0_PS4_QALL | PCR_PSPWERDWN0_PS5_QALL | + PCR_PSPWERDWN0_PS6_QALL | PCR_PSPWERDWN0_PS7_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR0); + + regval = PCR_PSPWERDWN1_PS8_QALL | PCR_PSPWERDWN1_PS9_QALL | + PCR_PSPWERDWN1_PS10_QALL | PCR_PSPWERDWN1_PS11_QALL | + PCR_PSPWERDWN1_PS12_QALL | PCR_PSPWERDWN1_PS13_QALL | + PCR_PSPWERDWN1_PS14_QALL | PCR_PSPWERDWN1_PS15_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR1); + + regval = PCR_PSPWERDWN2_PS16_QALL | PCR_PSPWERDWN2_PS17_QALL | + PCR_PSPWERDWN2_PS18_QALL | PCR_PSPWERDWN2_PS19_QALL | + PCR_PSPWERDWN2_PS20_QALL | PCR_PSPWERDWN2_PS21_QALL | + PCR_PSPWERDWN2_PS22_QALL | PCR_PSPWERDWN2_PS23_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR2); + + regval = PCR_PSPWERDWN3_PS24_QALL | PCR_PSPWERDWN3_PS25_QALL | + PCR_PSPWERDWN3_PS26_QALL | PCR_PSPWERDWN3_PS27_QALL | + PCR_PSPWERDWN3_PS28_QALL | PCR_PSPWERDWN3_PS29_QALL | + PCR_PSPWERDWN3_PS30_QALL | PCR_PSPWERDWN3_PS31_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR3); + + /* Enable Peripherals */ + + clkcntl |= SYS_CLKCNTL_PENA; + putreg32(clkcntl, TMS570_SYS_CLKCNTL); +} + +/**************************************************************************** + * Name: tms570_lpo_trim + * + * Description: + * Configure the LPO such that HF LPO is as close to 10MHz as possible. + * + ****************************************************************************/ + +static void tms570_lpo_trim(void) +{ + uint32_t regval; + uint32_t lotrim; + + /* The LPO trim value may be available in TI OTP */ + + lotrim = (getreg32(TMS570_TITCM_LPOTRIM) & TMS570_TITCM_LPOTRIM_MASK) << + TMS570_TITCM_LPOTRIM_SHIFT; + + /* Use if the LPO trim value TI OTP if programmed. Otherwise, use a + * default value. + */ + + if (lotrim != 0xffff) + { + regval = SYS_LPOMONCTL_BIASENABLE | lotrim; + } + else + { + regval = SYS_LPOMONCTL_BIASENABLE | + SYS_LPOMONCTL_HFTRIM_100p00 | + SYS_LPOMONCTL_60p86; + } + + putreg32(regval, TMS570_SYS_LPOMONCTL); +} + +/**************************************************************************** + * Name: tms570_flash_setup + * + * Description: + * Set up flash address and data wait states based on the target CPU clock + * frequency The number of address and data wait states for the target CPU + * clock frequency are specified in the specific part's datasheet. + * + ****************************************************************************/ + +static void tms570_flash_setup(void) +{ + uint32_t regval; + + /* Setup flash read mode, address wait states and data wait states + * + * ENPIPE=1, Bit 0, Enable pipeline mode. + * ASWSTEN=0/1, Bit 1, Address Setup Wait State is enabled/disabled. + * RWAIT=BOARD_RWAIT, Bits 8-11, Wait states added to FLASH read access + */ + + regval = FLASH_FRDCNTL_ENPIPE | FLASH_FRDCNTL_RWAIT(BOARD_RWAIT); +#if defined(BOARD_ASWAIT) && BOARD_ASWAIT > 0 + regval |= FLASH_FRDCNTL_ASWSTEN; +#endif + putreg32(regval, TMS570_FLASH_FRDCNTL); + + /* Setup flash access wait states for bank 7 + * + * AUTOSTART_GRACE=2, Bits 0-7, Auto-suspend Startup Grace Period + * AUTOSUSPEN=0, Bit 8, Auto suspend is disabled. + * EWAIT=4, Bits 16-19, EEPROM wait states + */ + + putreg32(FLASH_FSMWRENA_ENABLE, TMS570_FLASH_FSMWRENA); + regval = FLASH_EEPROMCFG_GRACE(2) | FLASH_EEPROMCFG_EWAIT(BOARD_EWAIT); + putreg32(regval, TMS570_FLASH_EEPROMCFG); + putreg32(FLASH_FSMWRENA_DISABLE, TMS570_FLASH_FSMWRENA); + + /* Setup flash bank power modes */ + + regval = FLASH_FBFALLBACK_BANKPWR0_ACTIV | + FLASH_FBFALLBACK_BANKPWR1_SLEEP | + FLASH_FBFALLBACK_BANKPWR7_ACTIV; + putreg32(regval, TMS570_FLASH_FBFALLBACK); +} + +/**************************************************************************** + * Name: tms570_clocksrc_configure + * + * Description: + * Finalize PLL configuration, enable and configure clocks sources. + * + ****************************************************************************/ + +static void tms570_clocksrc_configure(void) +{ + uint32_t regval; + uint32_t csvstat; + uint32_t csdis; + + /* Disable / Enable clock domains. Writing a '1' to the CDDIS register turns + * the clock off. + * + * GCLK Bit 0 On + * HCLK/VCLK_sys Bit 1 On + * VCLK_periph Bit 2 On + * VCLK2 Bit 3 On + * VCLKA1 Bit 4 On + * RTICLK1 Bit 6 On + * TCLK_EQEP Bit 9 On + */ + + putreg32(0, TMS570_SYS_CDDIS); + + /* Work Around for Errata SYS#46: Errata Description: Clock Source + * Switching Not Qualified with Clock Source Enable And Clock Source Valid + * Workaround: Always check the CSDIS register to make sure the clock source + * is turned on and check the CSVSTAT register to make sure the clock source + * is valid. Then write to GHVSRC to switch the clock. + */ + + do + { + /* Get the set of valid clocks */ + + csvstat = getreg32(TMS570_SYS_CSVSTAT) & SYS_MSTGCR_CLKSRVALL; + + /* Get the (inverted) state of each clock. Inverted so that '1' means + * ON not OFF. + */ + + csdis = (getreg32(TMS570_SYS_CSDIS) ^ SYS_CSDIS_CLKSROFFALL) & + SYS_CSDIS_CLKSROFFALL; + } + while ((csvstat & csdis) != csdis); + + + /* Now the PLLs are locked and the PLL outputs can be sped up. The R- + * divider was programmed to be 0xF. Now this divider is changed to + * programmed value + */ + + regval = getreg32(TMS570_SYS_PLLCTL1); + regval &= ~SYS_PLLCTL1_PLLDIV_MASK; + regval |= SYS_PLLCTL1_PLLDIV(BOARD_PLL_R - 1); + putreg32(regval, TMS570_SYS_PLLCTL1); + + /* Map device clock domains to desired sources and configure top-level + * dividers. All clock domains were working off the default clock sources + * until this point. + * + * Setup GCLK, HCLK and VCLK clock source for normal operation, power down + * mode and after wakeup + */ + + regval = SYS_GHVSRC_GHVSRC_PLL1 | SYS_GHVSRC_HVLPM_PLL1 | + SYS_GHVSRC_GHVWAKE_PLL1; + putreg32(regval, TMS570_SYS_GHVSRC); + + /* Setup synchronous peripheral clock dividers for VCLK1, VCLK2, VCLK3 */ + + regval = getreg32(TMS570_SYS_CLKCNTL); + regval &= ~(SYS_CLKCNTL_VCLKR2_MASK | SYS_CLKCNTL_VCLKR_MASK); + regval |= SYS_CLKCNTL_VCLKR2_DIV1 | SYS_CLKCNTL_VCLKR_DIV1; + putreg32(regval, TMS570_SYS_CLKCNTL); + + /* Setup RTICLK1 and RTICLK2 clocks */ + + regval = SYS_RCLKSRC_RTI1SRC_VCLK | SYS_RCLKSRC_RTI1DIV_DIV2; + putreg32(regval, TMS570_SYS_RCLKSRC); + + /* Setup asynchronous peripheral clock sources for AVCLK1 */ + + putreg32(SYS_VCLKASRC_VCLKA1S_VCLK, TMS570_SYS_VCLKASRC); +} + +/**************************************************************************** + * Name: tms570_eclk_configure + * + * Description: + * Configure the External Clock (ECLK) pin. + * + ****************************************************************************/ + +static void tms570_eclk_configure(void) +{ + uint32_t regval; + + /* Configure ECLK pins + * + * PC1 0=ECLK is in GIO mode + * PC4 0=ECLK pin is driven to logic low + * PC2 1=ECLK pin is an output + * PC7 0=CLK pin is configured in push/pull mode + * PC8 0=ECLK pull enable is active + * PC9 1=ECLK pull up is selected, when pull up/pull down logic is enabled + */ + + putreg32(0, TMS570_SYS_PC1); + putreg32(0, TMS570_SYS_PC4); + putreg32(SYS_PC2_ECPCLKDIR, TMS570_SYS_PC2); + putreg32(0, TMS570_SYS_PC7); + putreg32(0, TMS570_SYS_PC8); + putreg32(SYS_PC9_ECPCLKPS, TMS570_SYS_PC9); + + /* Setup ECLK: + * + * ECPDIV=7 Bits 0-15, ECP divider value = 8 + * ECPINSEL=0 Bits 16-17, Select ECP input clock source is tied low + * ECPCOS=0 Bit 23, ECLK output is disabled in suspend mode + * ECPINSEL=0 Bit 24, VCLK is selected as the ECP clock source + */ + + regval = SYS_ECPCNTL_ECPDIV(8-1) | SYS_ECPCNTL_ECPINSEL_LOW; + putreg32(regval, TMS570_SYS_ECPCNTL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_clockconfig + * + * Description: + * Called to initialize TMS570 clocking. This does whatever setup is + * needed to put the SoC in a usable state. This includes, but is not + * limited to, the initialization of clocking using the settings in the + * board.h header file. + * + ****************************************************************************/ + +void tms570_clockconfig(void) +{ + /* Configure PLL control registers and enable PLLs. */ + + tms570_pll_setup(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Run eFuse controller start-up checks and start eFuse controller ECC + * self-test. This includes a check for the eFuse controller error + * outputs to be stuck-at-zero. + */ + +# warning Missing Logic +#endif /* CONFIG_TMS570_SELFTEST */ + + /* Enable clocks to peripherals and release peripheral reset */ + + tms570_peripheral_initialize(); + + /* Configure device-level multiplexing and I/O multiplexing */ +#warning Missing Logic + +#ifdef CONFIG_TMS570_SELFTEST + /* Wait for eFuse controller self-test to complete and check results */ +# warning Missing Logic + +#endif + + /* Set up flash address and data wait states. */ + + tms570_flash_setup(); + + /* Configure the LPO such that HF LPO is as close to 10MHz as possible */ + + tms570_lpo_trim(); + + /* Finalize PLL configuration, enable and configure clocks sources. */ + + tms570_clocksrc_configure(); + + /* Configure ECLK */ + + tms570_eclk_configure(); +} diff --git a/arch/arm/src/tms570/tms570_clockconfig.h b/arch/arm/src/tms570/tms570_clockconfig.h new file mode 100644 index 00000000000..b7c1c664f50 --- /dev/null +++ b/arch/arm/src/tms570/tms570_clockconfig.h @@ -0,0 +1,94 @@ +/************************************************************************************ + * arch/arm/src/tms570/tms570_clockconfig.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_TMS570_TMS570_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_TMS570_TMS570_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: tms570_clockconfig + * + * Description: + * Called to initialize TMS570 clocking. This does whatever setup is needed to + * put the SoC in a usable state. This includes, but is not limited to, the + * initialization of clocking using the settings in the board.h header file. + * + ************************************************************************************/ + +void tms570_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_CLOCKCONFIG_H */ diff --git a/arch/arm/src/tms570/tms570_irq.c b/arch/arm/src/tms570/tms570_irq.c new file mode 100644 index 00000000000..31ac5585d95 --- /dev/null +++ b/arch/arm/src/tms570/tms570_irq.c @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_irq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This is the address of current interrupt saved state data. Used for + * context switching. Only value during interrupt handling. + */ + +volatile uint32_t *current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Disable all interrupts. */ +#warning Missing logic + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Set all interrupts to the default priority */ +#warning Missing logic + + /* currents_regs is non-NULL only while processing an interrupt */ + + current_regs = NULL; + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_TMS570_GPIO_IRQ + tms570_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + irqenable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ +#warning Missing logic +} +#endif diff --git a/arch/arm/src/tms570/tms570_timerisr.c b/arch/arm/src/tms570/tms570_timerisr.c new file mode 100644 index 00000000000..bd3553b1e96 --- /dev/null +++ b/arch/arm/src/tms570/tms570_timerisr.c @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_timerisr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/