mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
Add up_addrenv_coherent which will be called before address environment switches
This commit is contained in:
parent
519e9c85e9
commit
0db7da1858
4 changed files with 108 additions and 2 deletions
|
@ -661,6 +661,56 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* 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
|
* Name: up_addrenv_clone
|
||||||
*
|
*
|
||||||
|
|
|
@ -457,6 +457,29 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* 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
|
* Name: up_addrenv_clone
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
/* 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
|
* loaded module by cleaning the D cache (i.e., flushing the D cache
|
||||||
* contents to memory and invalidating the I 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->textalloc, loadinfo->textsize);
|
||||||
|
up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
|
||||||
/* Restore the original address environment */
|
/* Restore the original address environment */
|
||||||
|
|
||||||
status = elf_addrenv_restore(loadinfo);
|
status = elf_addrenv_restore(loadinfo);
|
||||||
|
@ -333,6 +336,16 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
||||||
ret = status;
|
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
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -858,6 +858,26 @@ int up_addrenv_select(FAR const group_addrenv_t *addrenv,
|
||||||
int up_addrenv_restore(FAR const save_addrenv_t *oldenv);
|
int up_addrenv_restore(FAR const save_addrenv_t *oldenv);
|
||||||
#endif
|
#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
|
* Name: up_addrenv_clone
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue