diff --git a/arch/arm/src/armv7-r/arm_head.S b/arch/arm/src/armv7-r/arm_head.S index 854f38e1eb5..078b1b58d38 100644 --- a/arch/arm/src/armv7-r/arm_head.S +++ b/arch/arm/src/armv7-r/arm_head.S @@ -98,6 +98,19 @@ .global os_start /* Start the operating system */ .global arm_data_initialize /* Perform C data initialization */ + .global _sbss /* Start of .bss in RAM */ + .global _ebss /* End+1 of .bss in RAM */ +#ifdef CONFIG_BOOT_RUNFROMFLASH + .global _eronly /* Where .data defaults are stored in FLASH */ + .global _sdata /* Where .data needs to reside in SDRAM */ + .global _edata +#endif +#ifdef CONFIG_ARCH_RAMFUNCS + .global _framfuncs /* Where RAM functions are stored in FLASH */ + .global _sramfuncs /* Where RAM functions needs to reside in RAM */ + .global _eramfuncs +#endif + /* Exported symbols */ .global __start /* Power-up/Reset entry point */ @@ -412,9 +425,44 @@ arm_data_initialize: blt 2b #endif - /* And return to the caller */ +#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 + */ + + adr r3, .Lfuncinit + ldmia r3, {r0, r1, r2} + +3: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt 3b + +#ifndef CPU_DCACHE_DISABLE + /* Flush the copied RAM functions into physical RAM so that will + * be available when fetched into the I-Cache. + * + * Note that this is a branch, not a call and so will return + * directly to the caller without returning here. + */ + + adr r3, ..Lramfunc + ldmia r3, {r0, r1} + ldr r3, =arch_clean_dcache + b r3 +#else + /* Otherwise return to the caller */ bx lr +#endif +#else + /* Return to the caller */ + + bx lr +#endif /* .text Data: * @@ -446,6 +494,15 @@ arm_data_initialize: .long _sdata /* Where .data needs to reside in SDRAM */ .long _edata #endif + +#ifdef CONFIG_ARCH_RAMFUNCS + .type .Lfuncinit, %object +.Lfuncinit: + .long _framfuncs /* Where RAM functions are stored in FLASH */ +.Lramfuncs: + .long _sramfuncs /* Where RAM functions needs to reside in RAM */ + .long _eramfuncs +#endif .size arm_data_initialize, . - arm_data_initialize /*************************************************************************** diff --git a/arch/arm/src/armv7-r/sctlr.h b/arch/arm/src/armv7-r/sctlr.h index 572596aa17d..76ab8081df1 100644 --- a/arch/arm/src/armv7-r/sctlr.h +++ b/arch/arm/src/armv7-r/sctlr.h @@ -463,6 +463,33 @@ static inline void cp15_wrsctlr(unsigned int sctlr) ); } +/* Read/write the implementation defined Auxiliary Control Regster (ACTLR) */ + +static inline unsigned int cp15_rdactlr(void) +{ + unsigned int actlr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c1, c0, 1\n" + : "=r" (actlr) + : + : "memory" + ); + + return actlr; +} + +static inline void cp15_wractlr(unsigned int actlr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c1, c0, 1\n" + : + : "r" (actlr) + : "memory" + ); +} + /* Read/write the Performance Monitor Control Register (PMCR) */ static inline unsigned int cp15_rdpmcr(void) diff --git a/arch/arm/src/tms570/chip/tms570_sys.h b/arch/arm/src/tms570/chip/tms570_sys.h index 4c16d955db0..855b9ea7da0 100644 --- a/arch/arm/src/tms570/chip/tms570_sys.h +++ b/arch/arm/src/tms570/chip/tms570_sys.h @@ -209,14 +209,38 @@ #define SYS_CSVSTAT_ /* Memory Self-Test Global Control Register */ #define SYS_MSTGCR_ + /* Memory Hardware Initialization Global Control Register */ -#define SYS_MINITGCR_ + +#define SYS_MINITGCR_MASK (0xff) /* Bits 0-7: Memory hardware initialization key */ +# define SYS_MINITGCR_ENABLE (0x0a) /* Enable */ +# define SYS_MINITGCR_DISABLE (0x05) /* Any other value disables */ + /* Memory Self-Test/Initialization Enable Register */ + #define SYS_MSIENA_ + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) || defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) + /* From TMS570LS0x32 Data Sheet */ + +# define SYS_MSIENA_RAM (1 << 0) +# define SYS_MSIENA_VIM_RAM (1 << 2) +# define SYS_MSIENA_N2HET_RAM (1 << 3) +# define SYS_MSIENA_HTU_RAM (1 << 4) +# define SYS_MSIENA_DCAN1_RAM (1 << 5) +# define SYS_MSIENA_DCAN2_RAM (1 << 6) +# define SYS_MSIENA_MIBSPI1_RAM (1 << 7) +# define SYS_MSIENA_MIBADC_RAM (1 << 8) +#endif + /* Memory Self-Test Fail Status Register */ #define SYS_MSTFAIL_ + /* MSTC Global Status Register */ -#define SYS_MSTCGSTAT_ + +#define SYS_MSTCGSTAT_MSTDONE (1 << 0) /* Bit 0: Memory self-test done */ +#define SYS_MSTCGSTAT_MINIDONE (1 << 8) /* Bit 8: Hardware initialization of all memory done */ + /* Memory Hardware Initialization Status Register */ #define SYS_MINISTAT_ /* PLL Control Register 1 */ diff --git a/arch/arm/src/tms570/tms570_boot.c b/arch/arm/src/tms570/tms570_boot.c index c0b795a9f0f..173b34eea40 100644 --- a/arch/arm/src/tms570/tms570_boot.c +++ b/arch/arm/src/tms570/tms570_boot.c @@ -60,6 +60,7 @@ #include "up_internal.h" #include "up_arch.h" +#include "chip/tms570_sys.h" #include "chip/tms570_esm.h" #include "tms570_clockconfig.h" #include "tms570_boot.h" @@ -72,104 +73,18 @@ # error CONFIG_ARMV7R_MEMINIT is required by this architecture. #endif -#define HIGH_VECTOR_ADDRESS 0xffff0000 +#ifndef CONFIG_ARCH_LOWVECTORS +# error CONFIG_ARCH_LOWVECTORS is required by this architecture. +#endif /**************************************************************************** * Public Data ****************************************************************************/ -/* Symbols defined via the linker script */ - -extern uint32_t _vector_start; /* Beginning of vector block */ -extern uint32_t _vector_end; /* End+1 of vector block */ - /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: tms570_vectorsize - * - * Description: - * Return the size of the vector data - * - ****************************************************************************/ - -static inline size_t tms570_vectorsize(void) -{ - uintptr_t src; - uintptr_t end; - - src = (uintptr_t)&_vector_start; - end = (uintptr_t)&_vector_end; - - return (size_t)(end - src); -} - -/**************************************************************************** - * Name: tms570_copyvectorblock - * - * Description: - * Copy the interrupt block to its final destination. Vectors are already - * positioned at the beginning of the text region and only need to be - * copied in the case where we are using high vectors or where the beginning - * of the text region cannot be remapped to address zero. - * - ****************************************************************************/ - -#if !defined(CONFIG_ARCH_LOWVECTORS) -static void tms570_copyvectorblock(void) -{ - uint32_t *src; - uint32_t *end; - uint32_t *dest; - - /* Copy the vectors into ISRAM at the address that will be mapped to the vector - * address: - * - * _vector_start - Start sourcea ddress of the vector table - * _vector_end - End+1 source address of the vector table - * HIGH_VECTOR_ADDRESS - Destinatino ddress of vector table in RAM - */ - - src = (uint32_t *)&_vector_start; - end = (uint32_t *)&_vector_end; - dest = (uint32_t *)HIGH_VECTOR_ADDRESS; - - while (src < end) - { - *dest++ = *src++; - } - - /* Flush the DCache to assure that the vector data is in physical in RAM */ - - arch_clean_dcache((uintptr_t)HIGH_VECTOR_ADDRESS, - (uintptr_t)HIGH_VECTOR_ADDRESS + tms570_vectorsize()); -} - -#else -/* Don't copy the vectors */ - -# define tms570_copyvectorblock() -#endif - -/**************************************************************************** - * Name: tms570_wdtdisable - * - * Description: - * Disable the watchdog timer. - * - ****************************************************************************/ - -#ifndef CONFIG_TMS570_WDT -static inline void tms570_wdtdisable(void) -{ -#warning Missing logic -} -#else -# define tms570_wdtdisable() -#endif - /**************************************************************************** * Name: tms570_event_export * @@ -191,6 +106,52 @@ static inline void tms570_event_export(void) cp15_wrpmcr(pmcr); } +/**************************************************************************** + * Name: tms570_enable_ramecc + * + * Description: + * This function enables the CPU's ECC logic for accesses to B0TCM and + * B1TCM. + * + ****************************************************************************/ + +static inline void tms570_enable_ramecc(void) +{ + uint32_t actlr = cp15_rdactlr(); + actlr |= 0x0c000000; + cp15_wractlr(actlr); +} + +/**************************************************************************** + * Name: tms570_memory_initialize + * + * Description: + * Perform memroy initialization of selected RAMs + * + * This function uses the system module's hardware for auto-initialization + * of memories and their associated protection schemes. + * + ****************************************************************************/ + +static void tms570_memory_initialize(uint32_t ramset) +{ + /* Enable Memory Hardware Initialization */ + + putreg32(SYS_MINITGCR_ENABLE, TMS570_SYS_MINITGCR); + + /* Enable Memory Hardware Initialization for selected RAM's */ + + putreg32(ramset, TMS570_SYS_MSIENA); + + /* Wait until Memory Hardware Initialization complete */ + + while((getreg32(TMS570_SYS_MSTCGSTAT) & SYS_MSTCGSTAT_MINIDONE) == 0); + + /* Disable Memory Hardware Initialization */ + + putreg32(SYS_MINITGCR_DISABLE, TMS570_SYS_MINITGCR); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -265,38 +226,53 @@ void arm_boot(void) ASSERT(getreg32(TMS570_ESM_SR3) == 0); - /* Disable the watchdog timer */ - - tms570_wdtdisable(); - /* Initialize clocking to settings provided by board-specific logic */ tms570_clockconfig(); -#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 +#ifdef CONFIG_TMS570_BIST + /* Run a diagnostic check on the memory self-test controller. */ +# warning Missing logic + + /* Run PBIST on CPU RAM. */ +# warning Missing logic + + /* Disable PBIST clocks and disable memory self-test mode */ +# warning Missing logic +#endif /* CONFIG_TMS570_BIST */ + + /* Initialize CPU RAM. */ + + tms570_memory_initialize(SYS_MSIENA_RAM); + + /* Enable ECC checking for TCRAM accesses. */ + + tms570_enable_ramecc(); + +#ifdef CONFIG_TMS570_BIST + /* Perform PBIST on all dual-port memories */ +#warning Missing logic + + /* Test the CPU ECC mechanism for RAM accesses. */ +#warning Missing logic + +#endif /* CONFIG_TMS570_BIST */ + + /* Release the MibSPI1 modules from local reset. */ +#warning Missing logic + + /* Initialize all on-chip SRAMs except for MibSPIx RAMs. + * + * The MibSPIx modules have their own auto-initialization mechanism which + * is triggered as soon as the modules are brought out of local reset. + * + * The system module auto-init will hang on the MibSPI RAM if the module + * is still in local reset. */ - 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. - */ - - arch_clean_dcache((uintptr_t)&_sramfuncs, (uintptr_t)&_eramfuncs) -#endif - - /* Setup up vector block. _vector_start and _vector_end are exported from - * arm_vector.S - */ - - tms570_copyvectorblock(); + tms570_memory_initialize(SYS_MSIENA_VIM_RAM | SYS_MSIENA_N2HET_RAM | + SYS_MSIENA_HTU_RAM | SYS_MSIENA_DCAN1_RAM | + SYS_MSIENA_DCAN2_RAM | SYS_MSIENA_MIBADC_RAM); #ifdef CONFIG_ARCH_FPU /* Initialize the FPU */ @@ -304,6 +280,17 @@ void arm_boot(void) arm_fpuconfig(); #endif +#ifdef CONFIG_ARMV7R_MEMINIT + /* If .data and .bss reside in SDRAM, then initialize the data sections + * now after RAM has been initialized. + * + * NOTE that is SDRAM were supported, this call might have to be + * performed after returning from tms570_board_initialize() + */ + + arm_data_initialize(); +#endif + /* Perform board-specific initialization, This must include: * * - Initialization of board-specific memory resources (e.g., SDRAM) @@ -316,14 +303,6 @@ void arm_boot(void) tms570_board_initialize(); -#ifdef CONFIG_ARMV7R_MEMINIT - /* If .data and .bss reside in SDRAM, then initialize the data sections - * now after RAM has been initialized. - */ - - arm_data_initialize(); -#endif - /* Perform common, low-level chip initialization (might do nothing) */ tms570_lowsetup();