
I apologize for being so late with this question.
York Sun <yorksun <at> freescale.com> writes:
When we need the copied code/data in the main memory, we can flush the cache now. It uses the existing function flush_cache. Syntax is
flush_cache <addr> <size>
The addr and size are given in hexadecimal. Like memory command, there is no sanity check for the parameters.
Are there symptoms for a specific system failure you can provide?
My problem is that when a stand alone application, which is copied from NOR flash to DDR, is started with the "go" command, it sometimes experiences a program check (illegal instruction) after a block of 32 zero bytes "appears" in memory.
I'm using a U-Boot for a custom Freescale P1022-based board, currently based on the old 2010.12 U-Boot as patched by Freescale in their SDK_V1_0_20110429_ltib.iso. Unfortunately, upgrading to a more recent version of U-Boot is not possible at this time, no more recent version is available from Freescale and I don't have the resources to verify all their patches apply correctly to a release directly from DENX.
I've used Codewarrior to observe the block of zeros in memory once the program check has happened, and I've verified that before the stand alone application begins execution, there are no zeros. Figuring it is likely that I have an error in my stand alone application code that corrupts the stack or writes based on an un-initialized pointer, I've tried using the CW watchpoint to catch where the zeros are written, but enabling the watchpoint seems to avoid the problem.
Based on later discussion on this thread, I've tried adding "flush_dcache(); invalidate_icache();" to cmd_boot.c:do_go(), just before control is passed to the stand alone app. Based on my ad hoc testing with this change, I don't get the program check exception.
I believe this result helps make the case that caching behavior is at the root of my problem, but since I was not able to isolate the actual cause of that problem, I can't be sure I've really got the solution.
(By the way, I would not leave the "flush_dcache(); invalidate_icache();" in do_go(), I merely found that for demonstrating a possible solution, this change easier than switching to a stand alone app that starts with bootm, or similar)
Any help or comments are very welcome.
Thanks, Jim
Signed-off-by: York Sun <yorksun <at> freescale.com>
common/cmd_cache.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/common/cmd_cache.c b/common/cmd_cache.c index 5512f92..93b7337 100644 --- a/common/cmd_cache.c +++ b/common/cmd_cache.c @@ -94,6 +94,29 @@ int do_dcache(cmd_tbl_t *cmdtp, int flag, int argc, char *
const argv[])
return 0; }
+void __weak flush_cache(ulong addr, ulong size) +{
- puts("No arch specific flush_cache available!\n");
- /* please define arch specific flush_cache */
+}
+int do_flush_cache(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- ulong addr, size;
- switch (argc) {
- case 3:
addr = simple_strtoul(argv[1], NULL, 16);
size = simple_strtoul(argv[2], NULL, 16);
flush_cache(addr, size);
break;
- default:
return cmd_usage(cmdtp);
- }
- return 0;
+}
static int parse_argv(const char *s) { if (strcmp(s, "flush") == 0) @@ -120,3 +143,10 @@ U_BOOT_CMD( "[on, off, flush]\n" " - enable, disable, or flush data (writethrough) cache" );
+U_BOOT_CMD(
- flush_cache, 3, 0, do_flush_cache,
- "flush cache for a range",
- "<addr> <size>\n"
- " - flush cache for specificed range"
+);