From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lj1-x22c.google.com (mail-lj1-x22c.google.com [IPv6:2a00:1450:4864:20::22c]) by sourceware.org (Postfix) with ESMTPS id 809383858D32 for ; Tue, 5 Dec 2023 17:11:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 809383858D32 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=googlemail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=googlemail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 809383858D32 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::22c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701796270; cv=none; b=JRboLqsvvLgLFvQQ8XcrT0zJe1Pff0p1kYH+ciDKDBRb0vmSM7RQjycAjepK8KzPAZg+XW7JnYkVhiakbPK2cijCAQ3sTm7mlKOcWO9dfRogNUyvT+8dF0ExIX9gXWJLPDzTmuUQOpJzlHlUjx59m6Lh+X8S+WdIcNqBOIxRsEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701796270; c=relaxed/simple; bh=ibtVjYPMFa7Gf9jYFLcgZjpYR6Y/tWpacHEnSE3vkpA=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=KZ/Zj3/PmIle4wNG72U2V54LVxYEGXndtxZJbTSBnvrG4QxvB79nYW8mRLKZxvSGo/liyXtWjZSZoeMO9hx580UYulJnbm/Hep/9Hk4vN3HqBCj2+TQqlEm2+kHWvgnxwoM02YDpnTEtWpsvMi+kfEz9Tn7DPMUSk7MebxviBEc= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lj1-x22c.google.com with SMTP id 38308e7fff4ca-2c9ef682264so44993661fa.3 for ; Tue, 05 Dec 2023 09:11:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20230601; t=1701796266; x=1702401066; darn=gcc.gnu.org; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=CYeScrJ/cmgpXx+mZqR6AA9rLynuthEHgx/DTSw7ILk=; b=CKD1UunrLrWhExPmpBUTEj8fLegZA3unPxQloXgy7GLQ4TV2qGsZegxL43Lhy7kImM +7Z9vVOFoL2xIXVYoXUbYBTxIoCyc1KzmyCUWy3HHJMuKQwvb8DPUwwh5DULeoDe3Z48 l/dqEhEy97LqeCjq7ZZRxBokRGIPwcBOhIoZP+2DnBtzrXkSLGywmgtgJBet4bEyj8mL dgM9c3QaTvLNMj8ZNc8EtBLSyLbPcV4ULZ4bjVSZjR4Vw+X7vyA42CE82jpPvFWC7ILw XH8lUDQ0HyoB9nawBj0XQdHU1WXKbi26sq6UficGY7UgM7hcAAP5UvGzeed9YpPieojg FcdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701796266; x=1702401066; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=CYeScrJ/cmgpXx+mZqR6AA9rLynuthEHgx/DTSw7ILk=; b=YJhaJvpy5ghXmIi1E1G9KIDuYQmpnZBRUm7j4gySo8gpNSzLk3FpwwCi00llktctBg nQ2vxvwCrrjWq/sPArbVVBmd7T4f5tfmqnAZhjdaxDlUcVp24kPrUz4hd5n2Uj9WmayF qZwR7CIXD9koaGcYxiSyKE3/A1UQvvfNZQt5NkfqUilbSZLVOlrRHsKUtTdVghIHJDL+ c/RX8zndCRJVNmEIdvZVzN4I82fWxY6DvDsYgPD2aMdSYPIbUWA9E9HRd42P1QxgPcAb Mz9VCMKtrix4Wb76j0rHEhFdzNAx0EP+M74rUP4hyXy/mei9LnnfKy+7XYeYrQWvdpeH CmtA== X-Gm-Message-State: AOJu0Yxzj6Djv5mkXejzud5gdFlG47e+yR8lJAuwGZvKJGnfkbkUvpSi U46IAxrRZZge0dJ2JPIWbwDr/rmpP3atNU6RGIAf8jHUkFQ= X-Google-Smtp-Source: AGHT+IGmGXSqEZAaoMo6+vApyw67opt9z3YKjOFlJMNhkLiqdpsa4GLYv7G/vjhGSF9NdcbQfR5juDG7v/l71D9FDmg= X-Received: by 2002:a2e:8202:0:b0:2c9:f774:2399 with SMTP id w2-20020a2e8202000000b002c9f7742399mr2091942ljg.7.1701796264105; Tue, 05 Dec 2023 09:11:04 -0800 (PST) MIME-Version: 1.0 References: <8342aeef-4eef-231b-bf45-416660954fdb@marco.de> In-Reply-To: Reply-To: edd.robbins@gmail.com From: Ed Robbins Date: Tue, 5 Dec 2023 17:10:52 +0000 Message-ID: Subject: Re: arm-none-eabi, nested function trampolines and caching To: David Brown Cc: Matthias Pfaller , gcc-help@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-6.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,FREEMAIL_REPLYTO,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Tue, 28 Nov 2023 at 18:00, David Brown wrote: > > On 28/11/2023 10:51, Ed Robbins via Gcc-help wrote: > > On Tue, 28 Nov 2023 at 07:21, Matthias Pfaller wrote: > >> > >> On 2023-11-27 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 have lots of code with nested functions. When switching to gcc-12 I got random > >> crashes on my cortex-m7 targets. In order to get that working again I had to patch > >> gcc/config/arm/arm.h: > >> > > > Can I ask (either or both of you) why you are using are using nested > functions like this? This is possibly the first time I have heard of > anyone using them, certainly the first time in embedded development. > Even when I programmed in Pascal, where nested functions are part of the > language, I did not use them more than a couple of times. > > What benefit do you see in nested functions in C, compared to having > separate functions? Have you considered moving to C++ and using > lambdas, which are more flexible, standard, and can be very much more > efficient? > > This is, of course, straying from the topicality of this mailing list. > But I am curious, and I doubt if I am the only one who is. > > David > In the simplest case you may want to do something like: struct sometype* find_thing_with_value(struct list *things, uint32_t value) { bool match(void *thing) { return ((struct sometype*)thing)->field == value; } return (struct sometype*)list_find(things, &match); } In general though dependency inversion can be quite powerful. We use nested functions that do not access local variables fairly frequently in our codebase, mostly as a scoping mechanism. We would like to be able to access locals, and are aware of the implications, but only very recently decided to address the issue. I think that rather than switch to C++ lambdas we would be more inclined to move to clang blocks and stick with C. But there is no impetus for either move: Nested functions are just fine for what we need to do, and the syntax is very clean. We have thoughts about a HLL shift but it wouldn't be to C++. Security implications are not an issue for us because there is no way for an outsider to communicate with the devices, let alone get a stack overflow and code execution. I think that it would be sensible if there was a -mflush_func option for ARM targets, as for MIPS, which would resolve the caching issues that require a patched gcc build in this case. Thanks to Matthias for guidance. I have ended up implementing this a bit differently, as in the patch below, as it's then totally self-contained. I've tested by rebuilding the toolchain using the script from [1] and it is working well. Best regards, Ed [1] https://github.com/FreddieChopin/bleeding-edge-toolchain/tree/master >From 569177e29cdc777e84e5e8cf633ebef761e82f83 Mon Sep 17 00:00:00 2001 From: Ed Robbins Date: Tue, 5 Dec 2023 16:56:36 +0000 Subject: [PATCH] Define CLEAR_INSN_CACHE in arm.h and implement for v7em targets --- gcc/config/arm/arm.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index f479540812a..666d98611bc 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2518,4 +2518,37 @@ const char *arm_be8_option (int argc, const char **argv); representation for SHF_ARM_PURECODE in GCC. */ #define SECTION_ARM_PURECODE SECTION_MACH_DEP +#ifndef CLEAR_INSN_CACHE +/* When defined CLEAR_INSN_CACHE is called by __clear_cache in libgcc/libgcc2.c + It needs to always be _defined_, otherwise maybe_emit_call_builtin___clear_cache + from gcc/builtins.cc will not generate a call to __clear_cache, however we + only want it _implemented_ for the multilib version of libgcc.a built for + v7em targets. */ +#ifdef __ARM_ARCH_7EM__ +#define CLEAR_INSN_CACHE(BEG, END) \ + { \ + const void *scb_base = (const void*)0xe000e000; \ + const unsigned dccmvac_offset = 0x268; \ + const unsigned icimvau_offset = 0x258; \ + const unsigned cache_line_size = 32; \ + void *addr = (void*)((unsigned)BEG & ~(cache_line_size - 1)); \ + void *end = (void*)((unsigned)(END + cache_line_size - 1) & ~(cache_line_size - 1)); \ + __asm__ __volatile__("dsb" : : : "memory"); \ + while (addr < end) { \ + *(unsigned**)(scb_base + dccmvac_offset) = addr; \ + addr += cache_line_size; \ + } \ + __asm__ __volatile__("dsb; isb" : : : "memory"); \ + addr = (void*)((unsigned)BEG & ~(cache_line_size - 1)); \ + while (addr < end) { \ + *(unsigned**)(scb_base + icimvau_offset) = addr; \ + addr += cache_line_size; \ + } \ + __asm__ __volatile__("dsb; isb" : : : "memory"); \ + } +#else +#define CLEAR_INSN_CACHE(BEG, END) ; +#endif +#endif + #endif /* ! GCC_ARM_H */ -- 2.34.1