From 2efc4d6396a324487560e84d73fbb3fd1d706807 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Apr 2014 16:08:18 -0600 Subject: [PATCH] SAMA5: On some hardware, reconfiguring the PLL while executing out of NOR FLASH causes crashes. This was fixed by David Sidrane by implementing RAM functions. The killer code is copied and executed from ISRAM and the crash is avoided. --- ChangeLog | 6 +++++- arch/arm/src/common/up_internal.h | 2 +- arch/arm/src/sama5/Kconfig | 1 + arch/arm/src/sama5/sam_boot.c | 24 +++++++++++++++++++++ arch/arm/src/sama5/sam_clockconfig.c | 27 ++++++++++++++++++++++-- configs/sama5d3x-ek/scripts/nor-isram.ld | 12 +++++++++-- 6 files changed, 66 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5962f47bbb..cf1dd50aa4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7130,4 +7130,8 @@ just set the VBAR register to address of the vectors in SDRAM. * arch/arm/src/sama5/sam_clockconfig.c: BMS Fixed to match what the HW does. From David Sidrane (2014-4-3). - + * arch/arm/src/sama5/Kconfig, sam_boot.c, andsam_clockconfig.c: On some + hardware, reconfiguring the PLL while executing out of NOR FLASH causes + crashes. This was fixed by David Sidrane by implementing RAM functions. + The killer code is copied and executed from ISRAM and the crash is + avoided (2014-4-3). diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h index 672da467ae..615af320e5 100644 --- a/arch/arm/src/common/up_internal.h +++ b/arch/arm/src/common/up_internal.h @@ -263,7 +263,7 @@ extern uint32_t _ebss; /* End+1 of .bss */ extern const uint32_t _framfuncs; /* Copy source address in FLASH */ extern uint32_t _sramfuncs; /* Copy destination start address in RAM */ -extern uint32_t _eramfuncs; /* Copy destination start address in RAM */ +extern uint32_t _eramfuncs; /* Copy destination end address in RAM */ #endif /* CONFIG_ARCH_RAMFUNCS */ #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index e31197b4b6..9dd32662d2 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/arch/arm/src/sama5/Kconfig @@ -3568,6 +3568,7 @@ config SAMA5_BOOT_SDRAM config SAMA5_BOOT_CS0FLASH bool "Running in external FLASH CS0" depends on SAMA5_EBICS0_NOR + select ARCH_RAMFUNCS config SAMA5_BOOT_CS0SRAM bool "Running in external FLASH CS0" diff --git a/arch/arm/src/sama5/sam_boot.c b/arch/arm/src/sama5/sam_boot.c index e41a382389..ef06e7a9a0 100644 --- a/arch/arm/src/sama5/sam_boot.c +++ b/arch/arm/src/sama5/sam_boot.c @@ -648,6 +648,11 @@ static inline void sam_wdtdisable(void) void up_boot(void) { +#ifdef CONFIG_ARCH_RAMFUNCS + const uint32_t *src; + uint32_t *dest; +#endif + #ifndef CONFIG_ARCH_ROMPGTABLE /* __start provided the basic MMU mappings for SRAM. Now provide mappings * for all IO regions (Including the vector region). @@ -663,6 +668,25 @@ void up_boot(void) #endif /* CONFIG_ARCH_ROMPGTABLE */ +#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 + */ + + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } + + /* Flush the copied RAM functions into physical RAM so that will + * be available when fetched into the I-Cache. + */ + + cp15_clean_dcache(&_sramfuncs, &_eramfuncs) +#endif + /* Setup up vector block. _vector_start and _vector_end are exported from * arm_vector.S */ diff --git a/arch/arm/src/sama5/sam_clockconfig.c b/arch/arm/src/sama5/sam_clockconfig.c index 29363a5768..657edd6b34 100644 --- a/arch/arm/src/sama5/sam_clockconfig.c +++ b/arch/arm/src/sama5/sam_clockconfig.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/sama5/sam_clockconfig.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -56,11 +56,34 @@ * Pre-processor Definitions ****************************************************************************/ +/* Do we need to setup the POLL? Yes if we are booting from ISRAM or NOR + * FLASH on CS0. + */ + #undef NEED_PLLSETUP #if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) # define NEED_PLLSETUP 1 #endif +/* Problems have been seen when reconfiguring the PLL while executing out + * of NOR FLASH on CS0. In that case, we required RAM function support. The + * critical functions will be copied from NOR into ISRAM for execution. This + * prevents any strange behavior from the NOR while we reconfigure the PLL. + */ + +#if defined(CONFIG_SAMA5_BOOT_CS0FLASH) && !defined(CONFIG_ARCH_RAMFUNCS) +# error "CONFIG_ARCH_RAMFUNCS must be defined for this logic" +#endif + +#ifndef CONFIG_ARCH_RAMFUNCS +# undef __ramfunc__ +# define __ramfunc__ +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + /**************************************************************************** * Private Types ****************************************************************************/ @@ -533,7 +556,7 @@ static inline void sam_usbclockconfig(void) * ****************************************************************************/ -void sam_clockconfig(void) +void __ramfunc__ sam_clockconfig(void) { #ifdef CONFIG_SAMA5_BOOT_CS0FLASH bool config = false; diff --git a/configs/sama5d3x-ek/scripts/nor-isram.ld b/configs/sama5d3x-ek/scripts/nor-isram.ld index ef6c05e7f4..c8681562e2 100644 --- a/configs/sama5d3x-ek/scripts/nor-isram.ld +++ b/configs/sama5d3x-ek/scripts/nor-isram.ld @@ -1,7 +1,7 @@ /**************************************************************************** * configs/sama5d3x-ek/scripts/nor-isram.ld * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ MEMORY { norflash (W!RX) : ORIGIN = 0x10000000, LENGTH = 128M - isram (WR) : ORIGIN = 0x00304000, LENGTH = 128K - 16K + isram (WRX) : ORIGIN = 0x00304000, LENGTH = 128K - 16K } OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") @@ -111,6 +111,14 @@ SECTIONS _ebss = ABSOLUTE(.); } > isram + .ramfunc ALIGN(4): { + _sramfuncs = ABSOLUTE(.); + *(.ramfunc .ramfunc.*) + _eramfuncs = ABSOLUTE(.); + } > isram AT > norflash + + _framfuncs = LOADADDR(.ramfunc); + /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) }