diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-08-26 14:53:19 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-08-26 14:53:19 -0600 |
commit | 9cfae56f922ee209ab1147a95cdefbbc7abc43c2 (patch) | |
tree | 2372d74249b25a374f3a56749b460dbda5055289 | |
parent | 9d42a5757f9c020c358b54d5bdf359819a6c4f1d (diff) | |
download | px4-nuttx-9cfae56f922ee209ab1147a95cdefbbc7abc43c2.tar.gz px4-nuttx-9cfae56f922ee209ab1147a95cdefbbc7abc43c2.tar.bz2 px4-nuttx-9cfae56f922ee209ab1147a95cdefbbc7abc43c2.zip |
Add up_addrenv_coherent which will be called before address environment switches
-rw-r--r-- | nuttx/arch/arm/src/armv7-a/arm_addrenv.c | 50 | ||||
-rw-r--r-- | nuttx/arch/z80/src/z180/z180_mmu.c | 23 | ||||
-rw-r--r-- | nuttx/binfmt/libelf/libelf_bind.c | 17 | ||||
-rw-r--r-- | nuttx/include/nuttx/arch.h | 20 |
4 files changed, 108 insertions, 2 deletions
diff --git a/nuttx/arch/arm/src/armv7-a/arm_addrenv.c b/nuttx/arch/arm/src/armv7-a/arm_addrenv.c index a9e680619..83d4f3856 100644 --- a/nuttx/arch/arm/src/armv7-a/arm_addrenv.c +++ b/nuttx/arch/arm/src/armv7-a/arm_addrenv.c @@ -662,6 +662,56 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv) } /**************************************************************************** + * Name: up_addrenv_coherent + * + * Description: + * Flush D-Cache and invalidate I-Cache in preparation for a change in + * address environments. This should immediately precede a call to + * up_addrenv_select(); + * + * Input Parameters: + * addrenv - Describes the address environment to be made coherent. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_coherent(FAR const group_addrenv_t *addrenv) +{ + uintptr_t vaddr; + int i; + + bvdbg("addrenv=%p\n", addrenv); + DEBUGASSERT(addrenv); + + /* Invalidate I-Cache */ + + cp15_invalidate_icache(); + + /* Clean D-Cache in each region. */ + +#warning REVISIT... causes crashes +#if 0 + arch_clean_dcache(CONFIG_ARCH_TEXT_VBASE, + CONFIG_ARCH_TEXT_VBASE + + CONFIG_ARCH_TEXT_NPAGES * MM_PGSIZE - 1); + + arch_clean_dcache(CONFIG_ARCH_DATA_VBASE, + CONFIG_ARCH_DATA_VBASE + + CONFIG_ARCH_DATA_NPAGES * MM_PGSIZE - 1); + +#if 0 /* Not yet implemented */ + arch_clean_dcache(CONFIG_ARCH_HEAP_VBASE, + CONFIG_ARCH_HEAP_VBASE + + CONFIG_ARCH_HEAP_NPAGES * MM_PGSIZE - 1); +#endif +#endif + + return OK; +} + +/**************************************************************************** * Name: up_addrenv_clone * * Description: diff --git a/nuttx/arch/z80/src/z180/z180_mmu.c b/nuttx/arch/z80/src/z180/z180_mmu.c index 3aeb64468..e1373851d 100644 --- a/nuttx/arch/z80/src/z180/z180_mmu.c +++ b/nuttx/arch/z80/src/z180/z180_mmu.c @@ -458,6 +458,29 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv) } /**************************************************************************** + * Name: up_addrenv_coherent + * + * Description: + * Flush D-Cache and invalidate I-Cache in preparation for a change in + * address environments. This should immediately precede a call to + * up_addrenv_select(); + * + * Input Parameters: + * addrenv - Describes the address environment to be made coherent. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_coherent(FAR const group_addrenv_t *addrenv) +{ + /* There are no caches */ + + return OK; +} + +/**************************************************************************** * Name: up_addrenv_clone * * Description: diff --git a/nuttx/binfmt/libelf/libelf_bind.c b/nuttx/binfmt/libelf/libelf_bind.c index da2dcd4ce..608f65ef7 100644 --- a/nuttx/binfmt/libelf/libelf_bind.c +++ b/nuttx/binfmt/libelf/libelf_bind.c @@ -312,16 +312,19 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo, } } -#ifdef CONFIG_ARCH_HAVE_COHERENT_DCACHE +#if defined(CONFIG_ARCH_ADDRENV) /* 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). */ +#if 0 /* REVISIT... has some problems */ + (void)up_addrenv_coherent(&loadinfo->addrenv); +#else up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize); + up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize); #endif -#ifdef CONFIG_ARCH_ADDRENV /* Restore the original address environment */ status = elf_addrenv_restore(loadinfo); @@ -333,6 +336,16 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo, ret = status; } } + +#elif defined(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). + */ + + up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize); + up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize); + #endif return ret; diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h index 483ee8e94..d4b076821 100644 --- a/nuttx/include/nuttx/arch.h +++ b/nuttx/include/nuttx/arch.h @@ -859,6 +859,26 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv); #endif /**************************************************************************** + * Name: up_addrenv_coherent + * + * Description: + * Flush D-Cache and invalidate I-Cache in preparation for a change in + * address environments. This should immediately precede a call to + * up_addrenv_select(); + * + * Input Parameters: + * addrenv - Describes the address environment to be made coherent. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_ADDRENV +int up_addrenv_coherent(FAR const group_addrenv_t *addrenv); +#endif + +/**************************************************************************** * Name: up_addrenv_clone * * Description: |