Read about our upcoming Code of Conduct on this issue

Commit 85bd8c47 authored by alex@thinkpad's avatar alex@thinkpad
Browse files

Patch manager: reworked mechanism for re-applying cache patches when needed

* arm-mcr.h: clean_d_cache and flush_i_cache are now private (sync_caches is the high-level function to be used)
* replaced all calls to clean_d_cache/flush_i_cache with sync_caches
* should fix issues with randomly "disappearing" cache patches
* to be tested for performance issues etc

--HG--
branch : patchmgr
parent deeeced6ccd7
......@@ -126,7 +126,7 @@ static inline void _flush_caches()
}
/* write back all data into RAM and mark as invalid in data cache */
static inline void clean_d_cache()
static inline void _clean_d_cache()
{
/* assume 8KB data cache */
/* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0092b/ch04s03s04.html */
......@@ -151,7 +151,7 @@ static inline void clean_d_cache()
}
/* mark all entries in I cache as invalid */
static inline void flush_i_cache()
static inline void _flush_i_cache()
{
asm(
"mov r0, #0\n"
......@@ -235,16 +235,29 @@ sei( uint32_t old_irq )
}
/* ensure data is written into RAM and the instruction cache is empty so everything will get fetched again */
static inline void _sync_caches()
{
uint32_t old = cli();
_clean_d_cache();
_flush_i_cache();
sei(old);
}
/* also reapply cache patches, if needed */
static inline void sync_caches()
{
uint32_t old = cli();
clean_d_cache();
flush_i_cache();
/* this function is only present on main ML (not installer / reboot shim / minimal / etc) */
extern int __attribute__((weak)) _reapply_cache_patches ();
_reapply_cache_patches();
extern int __attribute__((weak)) _patch_sync_caches(int also_data);
if (_patch_sync_caches)
{
_patch_sync_caches(1);
}
else
{
_sync_caches();
}
sei(old);
}
......
......@@ -134,7 +134,7 @@ void* edmac_copy_rectangle_cbr_start(void* dst, void* src, int src_width, int sr
/* see FIO_WriteFile for more info */
if (src == CACHEABLE(src))
{
clean_d_cache();
sync_caches();
}
take_semaphore(edmac_memcpy_sem, 0);
......
......@@ -550,8 +550,8 @@ int FIO_WriteFile( FILE* stream, const void* ptr, size_t count )
if (ptr == CACHEABLE(ptr))
{
/* write back all data to RAM */
/* overhead is minimal (see selfcheck.mo for benchmark) */
clean_d_cache();
/* overhead is minimal (see selftest.mo for benchmark) */
sync_caches();
}
return _FIO_WriteFile(stream, ptr, count);
......
......@@ -86,7 +86,6 @@ static union logging_hook_code logging_hooks[MAX_LOGGING_HOOKS];
static char last_error[70];
static void check_cache_lock_still_needed();
static int patch_sync_cache(int also_data);
/* re-apply the ROM (cache) patches */
/* call this after you have flushed the caches, for example */
......@@ -114,7 +113,8 @@ static void cache_require(int lock)
}
}
static int patch_sync_cache(int also_data)
/* should be called with interrupts cleared */
int _patch_sync_caches(int also_data)
{
#ifdef CONFIG_QEMU
return 0;
......@@ -133,12 +133,12 @@ static int patch_sync_cache(int also_data)
if (also_data)
{
dbg_printf("Syncing caches...\n");
sync_caches();
_sync_caches();
}
else
{
dbg_printf("Flushing ICache...\n");
flush_i_cache();
_flush_i_cache();
}
if (locked)
......@@ -347,7 +347,7 @@ static int patch_memory_work(
* but we need to clear the cache and re-apply any existing ROM patches */
if (is_instruction && !IS_ROM_PTR(addr))
{
err = patch_sync_cache(0);
err = _patch_sync_caches(0);
}
num_patches++;
......@@ -513,7 +513,7 @@ int unpatch_memory(uintptr_t _addr)
}
else if (patches[p].is_instruction)
{
err = patch_sync_cache(0);
err = _patch_sync_caches(0);
}
check_cache_lock_still_needed();
......@@ -981,7 +981,7 @@ int patch_hook_function(uintptr_t addr, uint32_t orig_instr, patch_hook_function
}};
/* since we have modified some code in RAM, sync the caches */
patch_sync_cache(1);
sync_caches();
/* patch the original instruction to jump to the logging code */
err = patch_instruction(addr, orig_instr, B_INSTR(addr, hook), description);
......
......@@ -156,4 +156,7 @@ int patch_hook_function(uintptr_t addr, uint32_t orig_instr, patch_hook_function
/* to undo, use unpatch_memory(addr) */
/* cache sync helper */
int _patch_sync_caches(int also_data);
#endif
......@@ -3682,7 +3682,7 @@ BMP_LOCK(
bvram_mirror_clear(); // may remain filled with playback zebras
)
clean_d_cache(); // to avoid display artifacts
sync_caches(); // to avoid display artifacts
info_led_off();
overlays_playback_running = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment