summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-26 14:53:19 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-26 14:53:19 -0600
commit9cfae56f922ee209ab1147a95cdefbbc7abc43c2 (patch)
tree2372d74249b25a374f3a56749b460dbda5055289 /nuttx
parent9d42a5757f9c020c358b54d5bdf359819a6c4f1d (diff)
downloadnuttx-9cfae56f922ee209ab1147a95cdefbbc7abc43c2.tar.gz
nuttx-9cfae56f922ee209ab1147a95cdefbbc7abc43c2.tar.bz2
nuttx-9cfae56f922ee209ab1147a95cdefbbc7abc43c2.zip
Add up_addrenv_coherent which will be called before address environment switches
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_addrenv.c50
-rw-r--r--nuttx/arch/z80/src/z180/z180_mmu.c23
-rw-r--r--nuttx/binfmt/libelf/libelf_bind.c17
-rw-r--r--nuttx/include/nuttx/arch.h20
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: