From 7aea220ebfe54cfee4ffa7d4a9e20561f2e76bda Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 24 Aug 2014 14:12:45 -0600 Subject: [PATCH] After cached related fix, the ELF example is now functional --- arch/Kconfig | 4 + arch/arm/Kconfig | 2 + arch/arm/src/a1x/Make.defs | 2 +- arch/arm/src/armv7-a/Kconfig | 3 +- arch/arm/src/armv7-a/arch_coherent_dcache.c | 94 +++++++++++++++++++++ arch/arm/src/sama5/Make.defs | 2 +- binfmt/elf.c | 2 +- binfmt/libelf/libelf_bind.c | 11 ++- configs/sama5d4-ek/README.txt | 31 +++++++ include/nuttx/binfmt/elf.h | 17 ++-- 10 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 arch/arm/src/armv7-a/arch_coherent_dcache.c diff --git a/arch/Kconfig b/arch/Kconfig index a3537ece69..0cb83efcf0 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -130,6 +130,10 @@ config ARCH_L2CACHE bool default n +config ARCH_HAVE_COHERENT_DCACHE + bool + default n + config CUSTOM_STACK bool default n diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0cb3c587ed..31007c7d34 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -212,12 +212,14 @@ config ARCH_CORTEXA5 default n select ARCH_HAVE_IRQPRIO select ARCH_HAVE_MMU + select ARCH_HAVE_COHERENT_DCACHE if ELF config ARCH_CORTEXA8 bool default n select ARCH_HAVE_IRQPRIO select ARCH_HAVE_MMU + select ARCH_HAVE_COHERENT_DCACHE if ELF config ARCH_FAMILY string diff --git a/arch/arm/src/a1x/Make.defs b/arch/arm/src/a1x/Make.defs index 4c3755352b..17eb916421 100644 --- a/arch/arm/src/a1x/Make.defs +++ b/arch/arm/src/a1x/Make.defs @@ -87,7 +87,7 @@ CMN_CSRCS += arm_addrenv.c endif ifeq ($(CONFIG_ELF),y) -CMN_CSRCS += arm_elf.c +CMN_CSRCS += arm_elf.c arch_coherent_dcache.c endif ifeq ($(CONFIG_ARCH_FPU),y) diff --git a/arch/arm/src/armv7-a/Kconfig b/arch/arm/src/armv7-a/Kconfig index dc85421b5d..fb82ad13be 100644 --- a/arch/arm/src/armv7-a/Kconfig +++ b/arch/arm/src/armv7-a/Kconfig @@ -9,7 +9,8 @@ config ARMV7A_HAVE_L2CC bool default n ---help--- - Selected by the configuration tool if the architecutre supports any kind of L2 cache. + Selected by the configuration tool if the architecutre supports any + kind of L2 cache. config ARMV7A_HAVE_L2CC_PL310 bool diff --git a/arch/arm/src/armv7-a/arch_coherent_dcache.c b/arch/arm/src/armv7-a/arch_coherent_dcache.c new file mode 100644 index 0000000000..4ab5acf494 --- /dev/null +++ b/arch/arm/src/armv7-a/arch_coherent_dcache.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/arm/src/armv7/arch_undefinedinsn.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "cp15_cacheops.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * addr - virtual start address of region + * len - Size of the address region in bytes + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arch_coherent_dcache(uintptr_t addr, size_t len) +{ + /* Perform the operation on the L1 cache */ + + cp15_coherent_dcache(addr, addr+len); + +#ifdef CONFIG_ARCH_L2CACHE + /* If we have an L2 cache, then there more things that need to done */ + +# warning This is insufficient +#endif +} diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs index c588864c24..4adc5bdd3e 100644 --- a/arch/arm/src/sama5/Make.defs +++ b/arch/arm/src/sama5/Make.defs @@ -89,7 +89,7 @@ CMN_CSRCS += arm_addrenv.c endif ifeq ($(CONFIG_ELF),y) -CMN_CSRCS += arm_elf.c +CMN_CSRCS += arm_elf.c arch_coherent_dcache.c endif ifeq ($(CONFIG_ARCH_FPU),y) diff --git a/binfmt/elf.c b/binfmt/elf.c index eb0adc7020..cff3463a7f 100644 --- a/binfmt/elf.c +++ b/binfmt/elf.c @@ -257,7 +257,7 @@ static int elf_loadbinary(struct binary_s *binp) #endif elf_dumpbuffer("Entry code", (FAR const uint8_t*)binp->entrypt, - MIN(loadinfo.elfsize - loadinfo.ehdr.e_entry, 512)); + MIN(loadinfo.textsize - loadinfo.ehdr.e_entry, 512)); elf_uninit(&loadinfo); return OK; diff --git a/binfmt/libelf/libelf_bind.c b/binfmt/libelf/libelf_bind.c index 4d3d27f041..6ce660ef5b 100644 --- a/binfmt/libelf/libelf_bind.c +++ b/binfmt/libelf/libelf_bind.c @@ -1,7 +1,7 @@ /**************************************************************************** * binfmt/libelf/libelf_bind.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -323,10 +323,13 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo, } } - /* Flush the instruction cache before starting the newly loaded module */ +#ifdef CONFIG_ARCH_HAVE_COHERENT_DCACHE + /* Ensure that the I and D caches are coherent before starting the newly + * loaded module by cleaning the D cache (i.e., flushing the D cache + * contents to memory and invalidating the I cache. + */ -#ifdef CONFIG_ELF_ICACHE - arch_flushicache((FAR void*)loadinfo->textalloc, loadinfo->textsize); + arch_coherent_dcache(loadinfo->textalloc, loadinfo->textsize); #endif return ret; diff --git a/configs/sama5d4-ek/README.txt b/configs/sama5d4-ek/README.txt index b992c0cd63..9e5b58460b 100644 --- a/configs/sama5d4-ek/README.txt +++ b/configs/sama5d4-ek/README.txt @@ -3525,6 +3525,7 @@ Configurations dramboot: This is a little program to help debug of code in DRAM. See the description below and the section above entitled "Creating and Using DRAMBOOT" for more information + elf: Demonstrates execution of ELF file from a file system. nsh: This is an NuttShell (NSH) configuration that supports extensive functionality as possible (unlike the minimal ramtest configuration). See the detailed description below for a summary of the feature @@ -3653,6 +3654,36 @@ Configurations putting DRAMBOOT on a microSD card (as boot.bin). The RomBOOT loader does boot that image without issue. + elf: + + Demonstrates execution of ELF file from a file system using + apps/examples/elf. This is a very simple configuration so there is not + really much that needs to be said. + + NOTES: + + 1. This configuration uses the the USART3 for the serial console + which is available at the "DBGU" RS-232 connector (J24). That + is easily changed by reconfiguring to (1) enable a different + serial peripheral, and (2) selecting that serial peripheral as + the console device. + + 2. By default, this configuration is set up to build on Windows + under either a Cygwin or MSYS environment using a recent, Windows- + native, generic ARM EABI GCC toolchain (such as the CodeSourcery + toolchain). Both the build environment and the toolchain + selection can easily be changed by reconfiguring: + + CONFIG_HOST_WINDOWS=y : Windows operating system + CONFIG_WINDOWS_CYGWIN=y : POSIX environment under windows + CONFIG_ARMV7A_TOOLCHAIN_CODESOURCERYW=y : CodeSourcery for Windows + + If you are running on Linux, make *certain* that you have + CONFIG_HOST_LINUX=y *before* the first make or you will create a + corrupt configuration that may not be easy to recover from. See + the warning in the section "Information Common to All Configurations" + for further information. + nsh: This configuration directory provide the NuttShell (NSH). This is a diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h index 71c7aa2821..9561135dcf 100644 --- a/include/nuttx/binfmt/elf.h +++ b/include/nuttx/binfmt/elf.h @@ -315,22 +315,25 @@ int arch_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, uintptr_t addr); /**************************************************************************** - * Name: arch_flushicache + * Name: arch_coherent_dcache * * Description: - * Flush the instruction cache. + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. * * Input Parameters: - * addr - Start address to flush - * len - Number of bytes to flush + * addr - virtual start address of region + * len - Size of the address region in bytes * * Returned Value: - * True if the architecture supports this ELF file. + * None * ****************************************************************************/ -#ifdef CONFIG_ELF_ICACHE -bool arch_flushicache(FAR void *addr, size_t len); +#ifdef CONFIG_ARCH_HAVE_COHERENT_DCACHE +void arch_coherent_dcache(uintptr_t addr, size_t len); #endif #undef EXTERN