Hi David! On Mon, 27 Nov 2023 at 17:23, David Brown <david.brown@xxxxxxxxxxxx> wrote: > > On 27/11/2023 16:16, Ed Robbins via Gcc-help wrote: > > Hello, > > I am using gcc-arm-none-eabi with a cortex M7 device, with caches > > (data/instruction) enabled. Nested function calls result in a usage fault > > because there is no clear cache call for this platform. > > > > I am not sure I understand you here. Are you talking about trying to > use gcc nested function extensions, implemented by trampolines (small > function stubs on the stack)? If so, then the simple answer is - don't > do that. It's a /really/ bad idea. As far as I understand it, these > are a left-over from the way nested functions were originally > implemented in other gcc languages (Pascal, Ada, Modula-2), which now > handle things differently and far more efficiently. Trampolines were a > convenient way to implement nested functions some 30 years ago, before > caches were the norm, before anyone thought about security, before > processors had prefetching, and before people realised what an > appallingly bad idea self-modifying code is. > > If you want to use nested functions, use a language that supports nested > functions, such as Ada, or use C++ with lambdas (which are a bit like > nested functions only much better). I am aware of the alternative languages and the implementation limitations, but I didn't ask if it is a good idea or not! > > > Is there a way to provide the required functions without rebuilding gcc? I > > have been looking at the source and, as far as I can tell, there is not. > > I can think of at least four ways : > > 1. The SDK for your microcontroller, provided by the manufacturer, will > have headers with cache clear functions. > > 2. The ARM CMSIS headers - also available from your manufacturer - has > intrinsic functions, including cache clear functions. > > 3. gcc has a generic "__buitin__clear_cache" function : > <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005f_005f_005fclear_005fcache> > > 4. gcc supports the "ARM C Language Extensions", which include cache > control intrinsics: > > <https://gcc.gnu.org/onlinedocs/gcc/ARM-C-Language-Extensions-_0028ACLE_0029.html> > <https://developer.arm.com/documentation/ihi0053/latest/> > I'm aware of how to perform a cache invalidate/clean, but that isn't the question. > > > > > But there also doesn't look to be a clean way to implement this: It appears > > that this is done on an operating system basis, and when running bare metal > > it is not clear where the code would live. > > There is no "clean" way to handle the appropriate cache invalidation, > because there is no clean way to get the addresses you need for > invalidating the instruction cache. Yes, there is, and that is what my question is about. The gcc documentation on trampolines [1] details this to some extent. It says that the target should define CLEAR_INSN_CACHE(beg, end) and it will be called with the correct addresses when the trampoline is initialised. Looking at the gcc source, arm.cc calls maybe_emit_call_builtin___clear_cache with the correct addresses when it initialises the trampoline, and maybe_emit_call_builtin___clear_cache calls __clear_cache if CLEAR_INSN_CACHE is defined. The question is about where to place this clear cache definition for a "none" target. (Cleanly invalidating the > instruction cache for other purposes, such as during firmware upgrades, > is no problem.) Yes, we do this already during firmware upgrades. Best regards, Ed [1] https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html