From 072890c1bf5426ad586beba714db33fbad3effae Mon Sep 17 00:00:00 2001 From: Takuya Miyashita Date: Mon, 3 Jun 2024 14:28:13 +0900 Subject: [PATCH] arch/arm/src/armv7-m/arm_vectors.c : Add the address alignment. Add the address alignment to keep the constraint of ARMv7-M architecture same as RAM vector. ARMv7-M architecture describes the vector table address alignment as following. The Vector table must be naturally aligned to a power of two whose alignment value is greater than or equal to (Number of Exceptions supported x 4), with a minimum alignment of 128 bytes. I wonder why the implementation of arm_vectors.c does not follow this constraint of address alignment about ARMv7-M architecture. Although RAM vector is taken care about it. I think, as the result it was done by linker script on each board. At our system, NuttX will be started by bootloader. To fix the address of entry point(__start) I set the address of entry point to beginning of binary, so the beginning of binary is not a vector table. At this case, keeping the address alignment constraint of arm_vectors.c is needed. --- arch/arm/src/armv7-m/arm_ramvec_initialize.c | 41 +---------------- arch/arm/src/armv7-m/arm_vectors.c | 8 ++-- arch/arm/src/armv7-m/ram_vectors.h | 47 +++++++++++++++++++- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/arch/arm/src/armv7-m/arm_ramvec_initialize.c b/arch/arm/src/armv7-m/arm_ramvec_initialize.c index 7bc69714e0..16510a9f7f 100644 --- a/arch/arm/src/armv7-m/arm_ramvec_initialize.c +++ b/arch/arm/src/armv7-m/arm_ramvec_initialize.c @@ -43,45 +43,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* Vector Table Offset Register (VECTAB). This mask seems to vary among - * ARMv7-M implementations. It may need to be redefined in some - * architecture-specific header file. By default, the base address of the - * new vector table must be aligned to the size of the vector table extended - * to the next larger power of 2. - */ - -#ifndef NVIC_VECTAB_TBLOFF_MASK -# if ARMV7M_VECTAB_SIZE > 512 -# define NVIC_VECTAB_TBLOFF_MASK (0xfffff000) -# elif ARMV7M_VECTAB_SIZE > 256 -# define NVIC_VECTAB_TBLOFF_MASK (0xfffff800) -# elif ARMV7M_VECTAB_SIZE > 128 -# define NVIC_VECTAB_TBLOFF_MASK (0xfffffc00) -# elif ARMV7M_VECTAB_SIZE > 64 -# define NVIC_VECTAB_TBLOFF_MASK (0xfffffe00) -# elif ARMV7M_VECTAB_SIZE > 32 -# define NVIC_VECTAB_TBLOFF_MASK (0xffffff00) -# else -# define NVIC_VECTAB_TBLOFF_MASK (0xffffff80) -# endif -#endif - -/* Alignment ****************************************************************/ - -/* Per the ARMv7M Architecture reference manual, the NVIC vector table - * requires 7-bit address alignment (i.e, bits 0-6 of the address of the - * vector table must be zero). In this case alignment to a 128 byte address - * boundary is sufficient. - * - * Some parts, such as the LPC17xx/LPC40xx family, require alignment to a 256 - * byte address boundary. Any other unusual alignment requirements for the - * vector can be specified for a given architecture be redefining - * NVIC_VECTAB_TBLOFF_MASK in the chip-specific chip.h header file for the - * appropriate mask. - */ - -#define RAMVEC_ALIGN ((~NVIC_VECTAB_TBLOFF_MASK & 0xffff) + 1) - /**************************************************************************** * Public Data ****************************************************************************/ @@ -99,7 +60,7 @@ */ up_vector_t g_ram_vectors[ARMV7M_VECTAB_SIZE] - locate_data(".ram_vectors") aligned_data(RAMVEC_ALIGN); + locate_data(".ram_vectors") aligned_data(VECTOR_ALIGN); /**************************************************************************** * Public Functions diff --git a/arch/arm/src/armv7-m/arm_vectors.c b/arch/arm/src/armv7-m/arm_vectors.c index 31e213cfaa..b5459ebd1d 100644 --- a/arch/arm/src/armv7-m/arm_vectors.c +++ b/arch/arm/src/armv7-m/arm_vectors.c @@ -40,6 +40,7 @@ #include "chip.h" #include "arm_internal.h" +#include "ram_vectors.h" /**************************************************************************** * Pre-processor Definitions @@ -47,10 +48,6 @@ #define IDLE_STACK (_ebss + CONFIG_IDLETHREAD_STACKSIZE) -#ifndef ARMV7M_PERIPHERAL_INTERRUPTS -# error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -76,7 +73,8 @@ extern void exception_common(void); * Note that the [ ... ] designated initializer is a GCC extension. */ -const void * const _vectors[] locate_data(".vectors") = +const void * const _vectors[] locate_data(".vectors") + aligned_data(VECTOR_ALIGN) = { /* Initial stack */ diff --git a/arch/arm/src/armv7-m/ram_vectors.h b/arch/arm/src/armv7-m/ram_vectors.h index b837a52ef0..1198337146 100644 --- a/arch/arm/src/armv7-m/ram_vectors.h +++ b/arch/arm/src/armv7-m/ram_vectors.h @@ -31,12 +31,14 @@ #include "arm_internal.h" #include "chip.h" -#ifdef CONFIG_ARCH_RAMVECTORS - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#ifndef ARMV7M_PERIPHERAL_INTERRUPTS +# error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported +#endif + /* This is the size of the vector table (in 4-byte entries). This size * includes the (1) the peripheral interrupts, (2) space for 15 Cortex-M * exceptions, and (3) IDLE stack pointer which lies at the beginning of the @@ -45,6 +47,47 @@ #define ARMV7M_VECTAB_SIZE (ARMV7M_PERIPHERAL_INTERRUPTS + 16) +/* Vector Table Offset Register (VECTAB). This mask seems to vary among + * ARMv7-M implementations. It may need to be redefined in some + * architecture-specific header file. By default, the base address of the + * new vector table must be aligned to the size of the vector table extended + * to the next larger power of 2. + */ + +#ifndef NVIC_VECTAB_TBLOFF_MASK +# if ARMV7M_VECTAB_SIZE > 512 +# define NVIC_VECTAB_TBLOFF_MASK (0xfffff000) +# elif ARMV7M_VECTAB_SIZE > 256 +# define NVIC_VECTAB_TBLOFF_MASK (0xfffff800) +# elif ARMV7M_VECTAB_SIZE > 128 +# define NVIC_VECTAB_TBLOFF_MASK (0xfffffc00) +# elif ARMV7M_VECTAB_SIZE > 64 +# define NVIC_VECTAB_TBLOFF_MASK (0xfffffe00) +# elif ARMV7M_VECTAB_SIZE > 32 +# define NVIC_VECTAB_TBLOFF_MASK (0xffffff00) +# else +# define NVIC_VECTAB_TBLOFF_MASK (0xffffff80) +# endif +#endif + +/* Alignment ****************************************************************/ + +/* Per the ARMv7M Architecture reference manual, the NVIC vector table + * requires 7-bit address alignment (i.e, bits 0-6 of the address of the + * vector table must be zero). In this case alignment to a 128 byte address + * boundary is sufficient. + * + * Some parts, such as the LPC17xx/LPC40xx family, require alignment to a 256 + * byte address boundary. Any other unusual alignment requirements for the + * vector can be specified for a given architecture be redefining + * NVIC_VECTAB_TBLOFF_MASK in the chip-specific chip.h header file for the + * appropriate mask. + */ + +#define VECTOR_ALIGN ((~NVIC_VECTAB_TBLOFF_MASK & 0xffff) + 1) + +#ifdef CONFIG_ARCH_RAMVECTORS + /**************************************************************************** * Public Data ****************************************************************************/