You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/02/20 03:24:17 UTC

[incubator-nuttx] branch master updated: arm: ARMv6-M vector table offset register support

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new d0002b2  arm: ARMv6-M vector table offset register support
d0002b2 is described below

commit d0002b24c7070bf36a71fbad3d6e5fbd299aa7d3
Author: Yuichi Nakamura <y....@gmail.com>
AuthorDate: Fri Feb 19 23:28:27 2021 +0900

    arm: ARMv6-M vector table offset register support
---
 arch/arm/src/armv6-m/arm_ramvec_attach.c     |  95 ++++++++++++++++++++
 arch/arm/src/armv6-m/arm_ramvec_initialize.c | 126 +++++++++++++++++++++++++++
 arch/arm/src/armv6-m/nvic.h                  |   2 +
 arch/arm/src/armv6-m/ram_vectors.h           |  98 +++++++++++++++++++++
 4 files changed, 321 insertions(+)

diff --git a/arch/arm/src/armv6-m/arm_ramvec_attach.c b/arch/arm/src/armv6-m/arm_ramvec_attach.c
new file mode 100644
index 0000000..145c120
--- /dev/null
+++ b/arch/arm/src/armv6-m/arm_ramvec_attach.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_ramvec_attach.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include "ram_vectors.h"
+
+#ifdef CONFIG_ARCH_RAMVECTORS
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/* Common exception entrypoint */
+
+void exception_common(void);
+
+/****************************************************************************
+ * Name: arm_ramvec_attach
+ *
+ * Description:
+ *   Configure the ram vector table so that IRQ number 'irq' will be
+ *   dispatched by hardware to 'vector'
+ *
+ ****************************************************************************/
+
+int arm_ramvec_attach(int irq, up_vector_t vector)
+{
+  int ret = -EINVAL;
+
+  irqinfo("%s IRQ%d\n", vector ? "Attaching" : "Detaching", irq);
+
+  if ((unsigned)irq < ARMV6M_VECTAB_SIZE)
+    {
+      irqstate_t flags;
+
+      /* If the new vector is NULL, then the vector is being detached. In
+       * this case, disable the itnerrupt and direct any interrupts to the
+       * common exception handler.
+       */
+
+      flags = enter_critical_section();
+      if (vector == NULL)
+        {
+          /* Disable the interrupt if we can before detaching it.  We might
+           * not be able to do this for all interrupts.
+           */
+
+          up_disable_irq(irq);
+
+          /* Detaching the vector really means re-attaching it to the
+           * common exception handler.
+           */
+
+           vector = exception_common;
+        }
+
+      /* Save the new vector in the vector table */
+
+      g_ram_vectors[irq] = vector;
+      leave_critical_section(flags);
+      ret = OK;
+    }
+
+  return ret;
+}
+
+#endif /* CONFIG_ARCH_RAMVECTORS */
diff --git a/arch/arm/src/armv6-m/arm_ramvec_initialize.c b/arch/arm/src/armv6-m/arm_ramvec_initialize.c
new file mode 100644
index 0000000..7e03715
--- /dev/null
+++ b/arch/arm/src/armv6-m/arm_ramvec_initialize.c
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_ramvec_initialize.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "nvic.h"
+#include "ram_vectors.h"
+
+#include "chip.h"
+#include "arm_arch.h"
+#include "arm_internal.h"
+
+#ifdef CONFIG_ARCH_RAMVECTORS
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Vector Table Offset Register (VECTAB).  This mask seems to vary among
+ * ARMv6-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
+#  define NVIC_VECTAB_TBLOFF_MASK     (0xffffff00)
+#endif
+
+/* Alignment ****************************************************************/
+
+#define RAMVEC_ALIGN ((~NVIC_VECTAB_TBLOFF_MASK & 0xffff) + 1)
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* If CONFIG_ARCH_RAMVECTORS is defined, then the ARM logic must provide
+ * ARM-specific implementations of arm_ramvec_initialize(), irq_attach(), and
+ * irq_dispatch.  In this case, it is also assumed that the ARM vector
+ * table resides in RAM, has the name g_ram_vectors, and has been
+ * properly positioned and aligned in memory by the linker script.
+ */
+
+up_vector_t g_ram_vectors[ARMV6M_VECTAB_SIZE]
+  __attribute__ ((section (".ram_vectors"), aligned (RAMVEC_ALIGN)));
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_ramvec_initialize
+ *
+ * Description:
+ *   Copy vectors to RAM an configure the NVIC to use the RAM vectors.
+ *
+ ****************************************************************************/
+
+void arm_ramvec_initialize(void)
+{
+  const up_vector_t *src;
+  up_vector_t *dest;
+  int i;
+
+  /* The vector table must be aligned */
+
+  DEBUGASSERT(((uint32_t)g_ram_vectors & ~NVIC_VECTAB_TBLOFF_MASK) == 0);
+
+  /* Copy the ROM vector table at address zero to RAM vector table.
+   *
+   * This must be done BEFORE the MPU is enable if the MPU is being used to
+   * protect against NULL pointer references.
+   */
+
+  src  = (const CODE up_vector_t *)getreg32(ARMV6M_SYSCON_VECTAB);
+  dest = g_ram_vectors;
+
+  irqinfo("src=%p dest=%p\n", src, dest);
+
+  for (i = 0; i < ARMV6M_VECTAB_SIZE; i++)
+    {
+      *dest++ = *src++;
+    }
+
+  /* Now configure the NVIC to use the new vector table. */
+
+  putreg32((uint32_t)g_ram_vectors, ARMV6M_SYSCON_VECTAB);
+
+  /* The number bits required to align the RAM vector table seem to vary
+   * from part-to-part.  The following assertion will catch the case where
+   * the table alignment is insufficient.
+   */
+
+  irqinfo("NVIC_VECTAB=%08" PRIx32 "\n", getreg32(ARMV6M_SYSCON_VECTAB));
+  DEBUGASSERT(getreg32(ARMV6M_SYSCON_VECTAB) == (uint32_t)g_ram_vectors);
+}
+
+#endif /* CONFIG_ARCH_RAMVECTORS */
diff --git a/arch/arm/src/armv6-m/nvic.h b/arch/arm/src/armv6-m/nvic.h
index 2755353..cfd1935 100644
--- a/arch/arm/src/armv6-m/nvic.h
+++ b/arch/arm/src/armv6-m/nvic.h
@@ -63,6 +63,7 @@
 
 #define ARMV6M_SYSCON_CPUID_OFFSET     0x0000  /* CPUID Register */
 #define ARMV6M_SYSCON_ICSR_OFFSET      0x0004  /* Interrupt control and state register  */
+#define ARMV6M_SYSCON_VECTAB_OFFSET    0x0008  /* Vector table offset register */
 #define ARMV6M_SYSCON_AIRCR_OFFSET     0x000c  /* Application interrupt and reset control register */
 #define ARMV6M_SYSCON_SCR_OFFSET       0x0010  /* System control register */
 #define ARMV6M_SYSCON_CCR_OFFSET       0x0014  /* Configuration and control register */
@@ -98,6 +99,7 @@
 
 #define ARMV6M_SYSCON_CPUID            (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_CPUID_OFFSET)
 #define ARMV6M_SYSCON_ICSR             (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_ICSR_OFFSET)
+#define ARMV6M_SYSCON_VECTAB           (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_VECTAB_OFFSET)
 #define ARMV6M_SYSCON_AIRCR            (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_AIRCR_OFFSET)
 #define ARMV6M_SYSCON_SCR              (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_SCR_OFFSET)
 #define ARMV6M_SYSCON_CCR              (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_CCR_OFFSET)
diff --git a/arch/arm/src/armv6-m/ram_vectors.h b/arch/arm/src/armv6-m/ram_vectors.h
new file mode 100644
index 0000000..9e19046
--- /dev/null
+++ b/arch/arm/src/armv6-m/ram_vectors.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/ram_vectors.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_ARMV6_M_RAM_VECTORS_H
+#define __ARCH_ARM_SRC_ARMV6_M_RAM_VECTORS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <arch/irq.h>
+
+#include "arm_internal.h"
+#include "chip.h"
+
+#ifdef CONFIG_ARCH_RAMVECTORS
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* This is the size of the vector table (in 4-byte entries).  This size
+ * includes the (1) the peripheral interrupts, (2) space for 15 Cortex-M
+ * exceptions, and (3) IDLE stack pointer which lies at the beginning of the
+ * table.
+ */
+
+#define ARMV6M_VECTAB_SIZE (32 + 16)
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* If CONFIG_ARCH_RAMVECTORS is defined, then the ARM logic must provide
+ * ARM-specific implementations of irq_initialize(), irq_attach(), and
+ * irq_dispatch.  In this case, it is also assumed that the ARM vector
+ * table resides in RAM, has the name g_ram_vectors, and has been
+ * properly positioned and aligned in memory by the linker script.
+ */
+
+extern up_vector_t g_ram_vectors[ARMV6M_VECTAB_SIZE]
+  __attribute__ ((section (".ram_vectors"), aligned (128)));
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_ramvec_initialize
+ *
+ * Description:
+ *   Copy vectors to RAM an configure the NVIC to use the RAM vectors.
+ *
+ ****************************************************************************/
+
+void arm_ramvec_initialize(void);
+
+/****************************************************************************
+ * Name: exception_common
+ *
+ * Description:
+ *   This is the default, common vector handling entrypoint.
+ *
+ ****************************************************************************/
+
+void exception_common(void);
+
+/****************************************************************************
+ * Name: arm_ramvec_attach
+ *
+ * Description:
+ *   Configure the ram vector table so that IRQ number 'irq' will be
+ *   dipatched by hardware to 'vector'
+ *
+ ****************************************************************************/
+
+int arm_ramvec_attach(int irq, up_vector_t vector);
+
+#endif /* CONFIG_ARCH_RAMVECTORS */
+#endif /* __ARCH_ARM_SRC_ARMV6_M_RAM_VECTORS_H */