summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-07-29 17:54:56 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-07-29 17:54:56 -0600
commit7571ee015859395fd74f2001b86cf82e57c293c8 (patch)
tree60d45b038252f4b7f080fc8d2993675a4c291d1e
parent6c9ec4933e27d479b84110b1f6f866a631300896 (diff)
downloadnuttx-7571ee015859395fd74f2001b86cf82e57c293c8.tar.gz
nuttx-7571ee015859395fd74f2001b86cf82e57c293c8.tar.bz2
nuttx-7571ee015859395fd74f2001b86cf82e57c293c8.zip
Changes to ARMv7-A boot logic to handle the case where we execute out of NOR FLASH
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_head.S143
-rw-r--r--nuttx/arch/arm/src/armv7-a/sctlr.h4
-rw-r--r--nuttx/configs/sama5d3x-ek/Kconfig14
-rw-r--r--nuttx/configs/sama5d3x-ek/README.txt14
-rw-r--r--nuttx/configs/sama5d3x-ek/ostest/defconfig4
-rw-r--r--nuttx/configs/sama5d3x-ek/src/Makefile4
-rw-r--r--nuttx/configs/sama5d3x-ek/src/nor_main.c26
7 files changed, 139 insertions, 70 deletions
diff --git a/nuttx/arch/arm/src/armv7-a/arm_head.S b/nuttx/arch/arm/src/armv7-a/arm_head.S
index 8007d6f60..5eebbdb48 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_head.S
+++ b/nuttx/arch/arm/src/armv7-a/arm_head.S
@@ -189,22 +189,6 @@
* containing both.
*/
-/* REVISIT: This works now of the low vector case only because the RAM
- * sizes that we have been dealing with are less then 1MB so that both the
- * page table and the vector table are in the same 1MB RAM block. But
- * this will certainly break later. Hence, the annoying warning.
- */
-
-#ifdef CONFIG_ARCH_LOWVECTORS
-# warning REVISIT
-#endif
-
-//#ifndef CONFIG_ARCH_LOWVECTORS
- .macro mksection, section, pgtable
- bic \section, \pgtable, #0x000ff000
- .endm
-//#endif
-
/* This macro will modify r0, r1, r2 and r14 */
#ifdef CONFIG_DEBUG
@@ -266,9 +250,9 @@ __start:
*/
#ifndef CONFIG_IDENTITY_TEXTMAP
- mksection r0, r4 /* r0=phys. base section */
+ ldr r0, .LCptextbase /* r0=phys. base address of .text section */
ldr r1, .LCtextflags /* R1=.text section MMU flags */
- add r3, r1, r0 /* r3=flags + base */
+ orr r3, r1, r0 /* r3=flags + base */
str r3, [r4, r0, lsr #18] /* identity mapping */
#endif
@@ -313,16 +297,6 @@ __start:
#else /* CONFIG_PAGING */
- /* Create identity mapping for first MB of the .text section if we have
- * no already done so.
- */
-
-#ifdef CONFIG_IDENTITY_TEXTMAP
- mksection r0, r4 /* r0=phys. base section */
- ldr r1, .LCtextflags /* R1=.text section MMU flags */
- add r3, r1, r0 /* r3=flags + base */
-#endif
-
/* Create a virtual single section mapping for the first MB of the .text
* address space. Now, we have the first 1MB mapping to both physical and
* virtual addresses. The rest of the .text mapping will be completed in
@@ -332,14 +306,41 @@ __start:
* r4 = Address of the base of the L1 table
*/
- ldr r2, .LCvpgtable /* r2=virt. page table */
- mksection r0, r2 /* r0=virt. base section */
- str r3, [r4, r0, lsr #18] /* identity mapping */
+#ifdef CONFIG_IDENTITY_TEXTMAP
+ ldr r0, .LCptextbase /* r0=phys. base address of .text section */
+ ldr r1, .LCtextflags /* R1=.text section MMU flags */
+ orr r3, r1, r0 /* r3=flags + base */
+#endif
+
+ ldr r0, .LCvtextbase /* r0=virtual base address of .text section */
+ str r3, [r4, r0, lsr #18] /* Save the L1 entry using vaddress as an index */
/* NOTE: No .data/.bss access should be attempted. This temporary mapping
* can only be assumed to cover the initial .text region.
*/
+#ifdef CONFIG_BOOT_RUNFROMFLASH
+ /* If we are executing from FLASH, then we will need an additional mapping
+ * for the page table itself (otherwise, we will crash when we try to modify
+ * the page table after turning the MMU on.
+ *
+ * Here we expect to have:
+ * r4 = Address of the base of the L1 table
+ *
+ * REVISIT: We might need this second mapping under certain conditions
+ * when executing from RAM too. When the RAM region is larger than 1MB
+ * and the page table is in the high end of RAM, then the single mapping
+ * above will not be sufficient.
+ */
+
+ ldr r0, .LCprambase /* r0=phys. base address of the primary RAM region */
+ ldr r1, .LCramflags /* R1=MMU flags use with the primary RAM region */
+ orr r3, r1, r0 /* r3=flags + base */
+
+ ldr r0, .LCvrambase /* r0=virtual base address of .text section */
+ str r3, [r4, r0, lsr #18] /* Save the L1 entry using vaddress as an index */
+
+#endif /* CONFIG_BOOT_RUNFROMFLASH */
#endif /* CONFIG_PAGING */
#endif /* CONFIG_ARCH_ROMPGTABLE */
@@ -520,14 +521,30 @@ __start:
* PC_Relative Data
****************************************************************************/
- /* Most addresses are virtual address */
-
+ /* The virtual start address of the second phase boot logic */
+
.type .LCvstart, %object
.LCvstart:
.long .Lvstart
.size .LCvstart, . -.LCvstart
#ifndef CONFIG_ARCH_ROMPGTABLE
+ /* The aligned, physical base address of the .text section */
+
+ .type .LCptextbase, %object
+.LCptextbase:
+ .long NUTTX_TEXT_PADDR & 0xfff00000
+ .size .LCptextbase, . -.LCptextbase
+
+ /* The aligned, virtual base address of the .text section */
+
+ .type .LCvtextbase, %object
+.LCvtextbase:
+ .long NUTTX_TEXT_VADDR & 0xfff00000
+ .size .LCvtextbase, . -.LCvtextbase
+
+ /* The MMU flags used with the .text mapping */
+
.type .LCtextflags, %object
.LCtextflags:
#ifdef CONFIG_BOOT_RUNFROMFLASH
@@ -536,14 +553,44 @@ __start:
.long MMU_MEMFLAGS /* MMU flags for text section in RAM */
#endif
.size .LCtextflags, . -.LCtextflags
+
+#if !defined(CONFIG_PAGING)
+#ifdef CONFIG_BOOT_RUNFROMFLASH
+ /* The physical base address of the primary RAM region */
+
+ .type .LCprambase, %object
+.LCprambase:
+ .long NUTTX_RAM_PADDR & 0xfff00000
+ .size .LCprambase, . -.LCprambase
+
+ /* The virtual base address of the primary RAM region */
+
+ .type .LCvrambase, %object
+.LCvrambase:
+ .long NUTTX_RAM_VADDR & 0xfff00000
+ .size .LCvrambase, . -.LCvrambase
+
+ /* The MMU flags used with the primary RAM region */
+
+ .type .LCramflags, %object
+.LCramflags:
+ .long MMU_MEMFLAGS /* MMU flags for RAM section */
+ .size .LCramflags, . -.LCramflags
+#endif
+#endif
+
#endif
+ /* The physical base address of the page table */
+
.type .LCppgtable, %object
.LCppgtable:
.long PGTABLE_BASE_PADDR /* Physical start of page table */
.size .LCppgtable, . -.LCppgtable
#ifndef CONFIG_ARCH_ROMPGTABLE
+ /* The virtual base address of the page table */
+
.type .LCvpgtable, %object
.LCvpgtable:
.long PGTABLE_BASE_VADDR /* Virtual start of page table */
@@ -609,11 +656,10 @@ __start:
#ifndef CONFIG_ARCH_ROMPGTABLE
#ifndef CONFIG_IDENTITY_TEXTMAP
- ldr r4, .LCvpgtable /* r4=virtual page table */
- ldr r1, .LCppgtable /* r1=phys. page table */
- mksection r3, r1 /* r2=phys. base addr */
+ ldr r4, .LCvpgtable /* r4=virtual page table base address */
+ ldr r3, .LCvtextbase /* r0=virtual base address of .text section */
mov r0, #0 /* flags + base = 0 */
- str r0, [r4, r3, lsr #18] /* Undo identity mapping */
+ str r3, [r4, r3, lsr #18] /* identity mapping */
#endif
#if defined(CONFIG_PAGING)
@@ -640,7 +686,7 @@ __start:
#ifdef CONFIG_IDENTITY_TEXTMAP
ldr r4, .LCvpgtable /* r4=virtual page table */
#endif
- ldr r3, .LCnuttxptext /* r3=Aligned Nuttx start address (physical) */
+ ldr r3, .LCptextbase /* r3=Aligned Nuttx start address (physical) */
/* Now setup the page tables for our normal mapped execution region.
* We round NUTTX_TEXT_VADDR down to the nearest megabyte boundary.
@@ -676,7 +722,7 @@ __start:
/* Get R3 = Value of RAM L1 page table entry */
- ldr r3, .LCnuttxpram /* r3=Aligned Nuttx RAM address (physical) */
+ ldr r3, .LCprambase /* r3=Aligned Nuttx RAM address (physical) */
ldr r1, .LCramflags /* R1=.bss/.data section MMU flags */
add r3, r3, r1 /* r3=flags + base */
@@ -759,25 +805,6 @@ __start:
.long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4
.size .Linitparms, . -.Linitparms
-#if !defined(CONFIG_PAGING)
- .type .LCnuttxptext, %object
-.LCnuttxptext:
- .long NUTTX_TEXT_PADDR & 0xfff00000
- .size .LCnuttxptext, . -.LCnuttxptext
-
-#ifdef CONFIG_BOOT_RUNFROMFLASH
- .type .LCramflags, %object
-.LCramflags:
- .long MMU_MEMFLAGS /* MMU flags for RAM section */
- .size .LCramflags, . -.LCramflags
-
- .type .LCnuttxpram, %object
-.LCnuttxpram:
- .long NUTTX_RAM_PADDR & 0xfff00000
- .size .LCnuttxpram, . -.LCnuttxpram
-#endif
-#endif
-
#ifdef CONFIG_PAGING
.type .Ldataspan, %object
diff --git a/nuttx/arch/arm/src/armv7-a/sctlr.h b/nuttx/arch/arm/src/armv7-a/sctlr.h
index 07959ef45..c0a53dbb9 100644
--- a/nuttx/arch/arm/src/armv7-a/sctlr.h
+++ b/nuttx/arch/arm/src/armv7-a/sctlr.h
@@ -285,7 +285,7 @@ static inline unsigned int cp15_rdsctlr(void)
unsigned int sctlr;
__asm__ __volatile__
(
- "\tmrc p15, 0, %0, c1, c0, 0"
+ "\tmrc p15, 0, %0, c1, c0, 0\n"
: "=r" (sctlr)
:
: "memory"
@@ -298,7 +298,7 @@ static inline void cp15_wrsctlr(unsigned int sctlr)
{
__asm__ __volatile__
(
- "\tmcr p15, 0, $0, c1, c0, 0\n"
+ "\tmcr p15, 0, %0, c1, c0, 0\n"
"\tnop\n"
"\tnop\n"
"\tnop\n"
diff --git a/nuttx/configs/sama5d3x-ek/Kconfig b/nuttx/configs/sama5d3x-ek/Kconfig
index 58f94967e..5f977fe16 100644
--- a/nuttx/configs/sama5d3x-ek/Kconfig
+++ b/nuttx/configs/sama5d3x-ek/Kconfig
@@ -11,6 +11,18 @@ config SAMA5_NOR_MAIN
depends on SAMA5_BOOT_ISRAM
---help---
nor_main is a tiny program that runs in ISRAM. nor_main will enable
- NOR flash then jump to the program in NOR flash
+ NOR flash then either (1) jump to the program in NOR flash or (2)
+ wait for you to break in with GDB to debug the NOR program.
+
+config SAMA5_NOR_START
+ bool "Start NOR program"
+ default n
+ depends on SAMA5_NOR_MAIN
+ ---help---
+ The default behavior of the NOR boot program is to initialize the
+ NOR FLASH at CS0, then patiently wait for you to break into the
+ program with GDB. An alternative behvior is enabled with this
+ option: If SAMA5_NOR_START is defined, then it will not wait but
+ will, instead, immediately start the program in NOR FLASH.
endif
diff --git a/nuttx/configs/sama5d3x-ek/README.txt b/nuttx/configs/sama5d3x-ek/README.txt
index e20c0b221..98c716ae9 100644
--- a/nuttx/configs/sama5d3x-ek/README.txt
+++ b/nuttx/configs/sama5d3x-ek/README.txt
@@ -699,6 +699,20 @@ Configurations
STATUS:
2013-7-28: This configuration was verified functional.
+ norboot:
+ This is a little program to help debug of code in NOR flash. It
+ does the following:
+
+ - It enables and configures NOR FLASH, then
+ - Waits for you to break in with GDB.
+
+ At that point, you can set the PC and begin executing from NOR FLASH
+ under debug control.
+
+ NOTES:
+ 1. This program derives from the hello configuration. All of the
+ notes there apply to this configuration as well.
+
ostest:
This configuration directory, performs a simple OS test using
examples/ostest.
diff --git a/nuttx/configs/sama5d3x-ek/ostest/defconfig b/nuttx/configs/sama5d3x-ek/ostest/defconfig
index 929087221..5d1010ad1 100644
--- a/nuttx/configs/sama5d3x-ek/ostest/defconfig
+++ b/nuttx/configs/sama5d3x-ek/ostest/defconfig
@@ -228,8 +228,8 @@ CONFIG_BOOT_RUNFROMFLASH=y
CONFIG_RAM_START=0x00304000
CONFIG_RAM_VSTART=0x00304000
CONFIG_RAM_SIZE=114688
-CONFIG_FLASH_START=0x1000000
-CONFIG_FLASH_VSTART=0x1000000
+CONFIG_FLASH_START=0x10000000
+CONFIG_FLASH_VSTART=0x10000000
CONFIG_FLASH_SIZE=134217728
#
diff --git a/nuttx/configs/sama5d3x-ek/src/Makefile b/nuttx/configs/sama5d3x-ek/src/Makefile
index 940bdbb5c..1ae5ae4cf 100644
--- a/nuttx/configs/sama5d3x-ek/src/Makefile
+++ b/nuttx/configs/sama5d3x-ek/src/Makefile
@@ -73,11 +73,11 @@ ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src
ifeq ($(WINTOOL),y)
CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}"
CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}"
- CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/armv7-m}"
+ CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/armv7-a}"
else
CFLAGS += -I$(ARCH_SRCDIR)/chip
CFLAGS += -I$(ARCH_SRCDIR)/common
- CFLAGS += -I$(ARCH_SRCDIR)/armv7-m
+ CFLAGS += -I$(ARCH_SRCDIR)/armv7-a
endif
all: libboard$(LIBEXT)
diff --git a/nuttx/configs/sama5d3x-ek/src/nor_main.c b/nuttx/configs/sama5d3x-ek/src/nor_main.c
index 3c90b8a77..96d881dfb 100644
--- a/nuttx/configs/sama5d3x-ek/src/nor_main.c
+++ b/nuttx/configs/sama5d3x-ek/src/nor_main.c
@@ -43,6 +43,7 @@
#include <debug.h>
#include "up_arch.h"
+#include "sctlr.h"
#include "sam_periphclks.h"
#include "chip/sam_hsmc.h"
@@ -114,18 +115,33 @@ int nor_main(int argc, char *argv)
HSMC_MODE_TDFCYCLES(1);
putreg32(regval, SAM_HSMC_MODE(HSMC_CS0));
+ /* Disable the caches and the MMU. Disabling the MMU should be safe here
+ * because there is a 1-to-1 identity mapping between the physical and
+ * virtual addressing.
+ */
+
+#if 0 /* Causes a crash */
+ printf("Disabling the caches and the MMU\n");
+ regval = cp15_rdsctlr();
+ regval &= ~(SCTLR_M | SCTLR_C | SCTLR_I);
+ cp15_wrsctlr(regval);
+#endif
+
+#ifdef SAMA5_NOR_START
/* Then jump into NOR flash */
-#if 1
- printf("Waiting for GDB halt\n");
- fflush(stdout);
- for (;;);
-#else
printf("Jumping to NOR flash on CS0\n");
fflush(stdout);
usleep(500*1000);
NOR_ENTRY();
+#else
+ /* Or just wait patiently for the user to break in with GDB. */
+
+ printf("Waiting for GDB halt\n");
+ fflush(stdout);
+ for (;;);
#endif
+
return 0; /* NOR_ENTRY() should not return */
}