Changes to ARMv7-A boot logic to handle the case where we execute out of NOR FLASH
This commit is contained in:
parent
1728594259
commit
5351598323
@ -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,7 +553,35 @@ __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:
|
||||
@ -544,6 +589,8 @@ __start:
|
||||
.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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
#
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user