* [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
@ 2026-06-13 20:41 Alexander Sverdlin
2026-06-14 13:54 ` Paul Kocialkowski
2026-06-16 14:11 ` Andre Przywara
0 siblings, 2 replies; 8+ messages in thread
From: Alexander Sverdlin @ 2026-06-13 20:41 UTC (permalink / raw)
To: u-boot
Cc: Alexander Sverdlin, Tom Rini, Jernej Skrabec, André Przywara,
Paul Kocialkowski, Cody Eksal
Currently some ARM-based platforms reserve TF-A memory in their own ways:
- Mediatek gets BL31 region via SMC call in ft_system_setup()
- K3 uses CONFIG_K3_ATF_LOAD_ADDR, effectively in ft_system_setup()
And others like Allwinner simply forget to do it, which results in Linux
overwriting TF-A and crashing.
Unfortunately seems that the things are not much better on TF-A side and
there is no universal way to get the reserved memory region across
platforms. But there is at least a most common way in TF-A, namely
reserving memory range in the FDT, in particular:
- Allwinner ("tf-a@40000000" node)
- ARM FPGA ("tf-a@80000000" node)
- Xilinx ("tf-a" node)
While this patch aims to improve the situation for Allwinner platforms,
it's deliberately adding more generic code to pave the potential way of
unification for other platforms.
Note that fdtdec_add_reserved_memory() has a check for an already existing
carveout with exactly matching boundaries and will not create a duplicate
even if the name doesn't match. It would not however detect an already
existing bigger carveout fully containing the one requested.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
The patch has been developed to faciliate Allwinner A133 SoC support, where
most of the work currently happens on TF-A [1] and Linux [2] sides, but
I wanted to send this patch upfront to get the first feedback and because
already supported H616 SoC would already benefit from the patch.
[1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/49754
[2] https://lore.kernel.org/all/20260605070923.3045073-1-alexander.sverdlin@gmail.com/
[3] https://lore.kernel.org/all/b428d57ba5464f1226daf099877f4c25fa4fc191.camel@gmail.com/
arch/arm/lib/bootm-fdt.c | 55 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
index 2671f9a0ebf..19d917943c1 100644
--- a/arch/arm/lib/bootm-fdt.c
+++ b/arch/arm/lib/bootm-fdt.c
@@ -14,7 +14,9 @@
* Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
*/
+#include <dm/ofnode.h>
#include <fdt_support.h>
+#include <linux/ioport.h>
#ifdef CONFIG_ARMV7_NONSEC
#include <asm/armv7.h>
#endif
@@ -24,6 +26,52 @@
DECLARE_GLOBAL_DATA_PTR;
+static int tfa_copy_reserved_memory(void *new_blob)
+{
+#ifdef CONFIG_OF_CONTROL
+ ofnode node, subnode;
+
+ /*
+ * TF-A for several platforms inserts its memory region as
+ * reserved-memory node
+ */
+ node = ofnode_path("/reserved-memory");
+ if (!ofnode_valid(node))
+ return 0;
+
+ ofnode_for_each_subnode(subnode, node) {
+ struct fdt_memory carveout;
+ struct resource res;
+ const char *name;
+ int ret;
+
+ name = ofnode_get_name(subnode);
+ if (!name)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ /* only handle TF-A reservations */
+ if (strncmp(name, "tf-a", 4))
+ continue;
+
+ /* check if this subnode has a reg property */
+ ret = ofnode_read_resource(subnode, 0, &res);
+ if (ret)
+ continue;
+
+ carveout.start = res.start,
+ carveout.end = res.end,
+
+ ret = fdtdec_add_reserved_memory(new_blob, "tf-a", &carveout,
+ NULL, 0, NULL,
+ FDTDEC_RESERVED_MEMORY_NO_MAP);
+ if (ret < 0)
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
#ifdef CONFIG_FMAN_ENET
__weak int fdt_update_ethernet_dt(void *blob)
{
@@ -56,6 +104,13 @@ int arch_fixup_fdt(void *blob)
return ret;
#endif
+ ret = tfa_copy_reserved_memory(blob);
+ if (ret) {
+ printf("ERROR: transfer of TF-A nodes to new fdt failed: %s\n",
+ fdt_strerror(ret));
+ return ret;
+ }
+
#ifdef CONFIG_ARMV8_SPIN_TABLE
ret = spin_table_update_dt(blob);
if (ret)
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-13 20:41 [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux Alexander Sverdlin
@ 2026-06-14 13:54 ` Paul Kocialkowski
2026-06-14 18:57 ` Alexander Sverdlin
2026-06-16 14:11 ` Andre Przywara
1 sibling, 1 reply; 8+ messages in thread
From: Paul Kocialkowski @ 2026-06-14 13:54 UTC (permalink / raw)
To: Alexander Sverdlin
Cc: u-boot, Tom Rini, Jernej Skrabec, André Przywara, Cody Eksal
[-- Attachment #1: Type: text/plain, Size: 6149 bytes --]
Hi,
Le Sat 13 Jun 26, 22:41, Alexander Sverdlin a écrit :
> Currently some ARM-based platforms reserve TF-A memory in their own ways:
> - Mediatek gets BL31 region via SMC call in ft_system_setup()
> - K3 uses CONFIG_K3_ATF_LOAD_ADDR, effectively in ft_system_setup()
>
> And others like Allwinner simply forget to do it, which results in Linux
> overwriting TF-A and crashing.
To be fair we've been adding the reserved memory regions statically in
the Linux device-trees to mitigate the issue.
But another thing we do overwrite current is the cpu idle states, which
are added by fdt_add_cpu_idle_states in tf-a. These are only set when the
SCP firmware is available (which is checked at run-time) and they are
never propagated to the final device-tree. Including the definitions
statically would result in cpu idle calls done even without the SCP
firmware, which would probably fail (although maybe some states can
still be supported).
Also note that the usual way to deal with this is to not load any
device-tree when booting the kernel, which will implicitly let U-Boot
use its current device-tree for Linux (with the modifications brought by
tf-a).
But of course I agree that it is very desirable to "forward" the
device-tree modifications to the kernel device-tree so we are not stuck
with whatever device-tree U-Boot was built with.
> Unfortunately seems that the things are not much better on TF-A side and
> there is no universal way to get the reserved memory region across
> platforms. But there is at least a most common way in TF-A, namely
> reserving memory range in the FDT, in particular:
> - Allwinner ("tf-a@40000000" node)
> - ARM FPGA ("tf-a@80000000" node)
> - Xilinx ("tf-a" node)
RaspberryPi seems to be using "atf@0". Generally speaking the property
is a free-form argument to fdt_add_reserved_memory in tf-a and I don't
think we can have a common way to match them.
Introducing a Kconfig property for the prefix would be a satisfying
solution in my opinion.
> While this patch aims to improve the situation for Allwinner platforms,
> it's deliberately adding more generic code to pave the potential way of
> unification for other platforms.
>
> Note that fdtdec_add_reserved_memory() has a check for an already existing
> carveout with exactly matching boundaries and will not create a duplicate
> even if the name doesn't match. It would not however detect an already
> existing bigger carveout fully containing the one requested.
>
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> ---
> The patch has been developed to faciliate Allwinner A133 SoC support, where
> most of the work currently happens on TF-A [1] and Linux [2] sides, but
> I wanted to send this patch upfront to get the first feedback and because
> already supported H616 SoC would already benefit from the patch.
Thanks for looking at this!
Like I said, I guess the same needs to be done for the cpuidle psci
nodes.
> [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/49754
> [2] https://lore.kernel.org/all/20260605070923.3045073-1-alexander.sverdlin@gmail.com/
> [3] https://lore.kernel.org/all/b428d57ba5464f1226daf099877f4c25fa4fc191.camel@gmail.com/
>
> arch/arm/lib/bootm-fdt.c | 55 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
> index 2671f9a0ebf..19d917943c1 100644
> --- a/arch/arm/lib/bootm-fdt.c
> +++ b/arch/arm/lib/bootm-fdt.c
> @@ -14,7 +14,9 @@
> * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
> */
>
> +#include <dm/ofnode.h>
> #include <fdt_support.h>
> +#include <linux/ioport.h>
> #ifdef CONFIG_ARMV7_NONSEC
> #include <asm/armv7.h>
> #endif
> @@ -24,6 +26,52 @@
>
> DECLARE_GLOBAL_DATA_PTR;
>
> +static int tfa_copy_reserved_memory(void *new_blob)
I would keep a fdt-related prefix to the name, so something like:
fdt_update_tfa_reserved_memory or
fdt_update_bl31_reserved_memory
> +{
> +#ifdef CONFIG_OF_CONTROL
> + ofnode node, subnode;
> +
> + /*
> + * TF-A for several platforms inserts its memory region as
> + * reserved-memory node
This will always be the case, I don't think we need a comment about it.
> + */
> + node = ofnode_path("/reserved-memory");
> + if (!ofnode_valid(node))
> + return 0;
> +
> + ofnode_for_each_subnode(subnode, node) {
> + struct fdt_memory carveout;
> + struct resource res;
> + const char *name;
> + int ret;
> +
> + name = ofnode_get_name(subnode);
> + if (!name)
> + return -FDT_ERR_BADSTRUCTURE;
> +
> + /* only handle TF-A reservations */
Please capitalize the first letter and end with a dot (same for all
comments).
> + if (strncmp(name, "tf-a", 4))
> + continue;
> +
> + /* check if this subnode has a reg property */
> + ret = ofnode_read_resource(subnode, 0, &res);
> + if (ret)
> + continue;
> +
> + carveout.start = res.start,
> + carveout.end = res.end,
> +
> + ret = fdtdec_add_reserved_memory(new_blob, "tf-a", &carveout,
> + NULL, 0, NULL,
> + FDTDEC_RESERVED_MEMORY_NO_MAP);
> + if (ret < 0)
> + return ret;
Looks good otherwise.
> + }
> +#endif
> +
> + return 0;
> +}
> +
> #ifdef CONFIG_FMAN_ENET
> __weak int fdt_update_ethernet_dt(void *blob)
> {
> @@ -56,6 +104,13 @@ int arch_fixup_fdt(void *blob)
> return ret;
> #endif
>
> + ret = tfa_copy_reserved_memory(blob);
> + if (ret) {
> + printf("ERROR: transfer of TF-A nodes to new fdt failed: %s\n",
> + fdt_strerror(ret));
This is very unlikely, not sure it is worth an error message.
Other calls in the same function are silent.
> + return ret;
> + }
> +
> #ifdef CONFIG_ARMV8_SPIN_TABLE
> ret = spin_table_update_dt(blob);
> if (ret)
> --
> 2.54.0
>
All the best,
Paul
--
Paul Kocialkowski,
Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/
Expert in multimedia, graphics and embedded hardware support with Linux.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-14 13:54 ` Paul Kocialkowski
@ 2026-06-14 18:57 ` Alexander Sverdlin
2026-06-14 21:06 ` Paul Kocialkowski
2026-06-16 14:10 ` Andre Przywara
0 siblings, 2 replies; 8+ messages in thread
From: Alexander Sverdlin @ 2026-06-14 18:57 UTC (permalink / raw)
To: Paul Kocialkowski
Cc: u-boot, Tom Rini, Jernej Skrabec, André Przywara, Cody Eksal
Hi Paul,
On Sun, 2026-06-14 at 15:54 +0200, Paul Kocialkowski wrote:
> > Currently some ARM-based platforms reserve TF-A memory in their own ways:
> > - Mediatek gets BL31 region via SMC call in ft_system_setup()
> > - K3 uses CONFIG_K3_ATF_LOAD_ADDR, effectively in ft_system_setup()
> >
> > And others like Allwinner simply forget to do it, which results in Linux
> > overwriting TF-A and crashing.
>
> To be fair we've been adding the reserved memory regions statically in
> the Linux device-trees to mitigate the issue.
once for H616, but it could be the only SoC among ARM64 platforms doing
this and discouraged for A133:
https://lore.kernel.org/all/b428d57ba5464f1226daf099877f4c25fa4fc191.camel@gmail.com/
> But another thing we do overwrite current is the cpu idle states, which
> are added by fdt_add_cpu_idle_states in tf-a. These are only set when the
> SCP firmware is available (which is checked at run-time) and they are
> never propagated to the final device-tree. Including the definitions
> statically would result in cpu idle calls done even without the SCP
> firmware, which would probably fail (although maybe some states can
> still be supported).
Do you refer to some unmerged code? Didn't find it in the current TF-A
sources...
> Also note that the usual way to deal with this is to not load any
> device-tree when booting the kernel, which will implicitly let U-Boot
> use its current device-tree for Linux (with the modifications brought by
> tf-a).
?!
We definitely want to load the very device tree coming in the FIT image
and pass it to the kernel from this FIT image. Sometimes people would
have several DTs to chose from. The thing in U-Boot is basically to
get U-Boot up and running. OF_UPSTREAM is rather to reduce the traffic
on the U-Boot mailing list and maintainers effort, but in most of the
cases we shall expect this DT to be not from the kernel we actually load.
> But of course I agree that it is very desirable to "forward" the
> device-tree modifications to the kernel device-tree so we are not stuck
> with whatever device-tree U-Boot was built with.
>
> > Unfortunately seems that the things are not much better on TF-A side and
> > there is no universal way to get the reserved memory region across
> > platforms. But there is at least a most common way in TF-A, namely
> > reserving memory range in the FDT, in particular:
> > - Allwinner ("tf-a@40000000" node)
> > - ARM FPGA ("tf-a@80000000" node)
> > - Xilinx ("tf-a" node)
>
> RaspberryPi seems to be using "atf@0". Generally speaking the property
> is a free-form argument to fdt_add_reserved_memory in tf-a and I don't
> think we can have a common way to match them.
>
> Introducing a Kconfig property for the prefix would be a satisfying
> solution in my opinion.
This was a very conservative patch solving the A133 case, but actually
I don't see anything wrong with just copying all the reserved areas from
the U-Boot live tree to the device tree we are going to pass to the
kernel. Maybe fdtdec_add_reserved_memory() needs to be taught to detect
overlapping ranges and extend them properly, or maybe yet another function
has to be created for this purpose, to avoid duplicated reserved-memory
nodes by all means, but would also solve the PSCI cpuidle issue, as well
as potentially Raspi case of TF-A side and simplify TI K3 on U-Boot side.
> > While this patch aims to improve the situation for Allwinner platforms,
> > it's deliberately adding more generic code to pave the potential way of
> > unification for other platforms.
> >
> > Note that fdtdec_add_reserved_memory() has a check for an already existing
> > carveout with exactly matching boundaries and will not create a duplicate
> > even if the name doesn't match. It would not however detect an already
> > existing bigger carveout fully containing the one requested.
> >
> > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > ---
> > The patch has been developed to faciliate Allwinner A133 SoC support, where
> > most of the work currently happens on TF-A [1] and Linux [2] sides, but
> > I wanted to send this patch upfront to get the first feedback and because
> > already supported H616 SoC would already benefit from the patch.
>
> Thanks for looking at this!
>
> Like I said, I guess the same needs to be done for the cpuidle psci
> nodes.
See above, maybe there is a way to carefully copy all /reserved-memory nodes?
Maybe this full copy shall be configurable, but with a proper overlapping-aware
implementation maybe even a Kconfig option is not required...
--
Alexander Sverdlin.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-14 18:57 ` Alexander Sverdlin
@ 2026-06-14 21:06 ` Paul Kocialkowski
2026-06-14 22:08 ` Alexander Sverdlin
2026-06-16 14:10 ` Andre Przywara
1 sibling, 1 reply; 8+ messages in thread
From: Paul Kocialkowski @ 2026-06-14 21:06 UTC (permalink / raw)
To: Alexander Sverdlin
Cc: u-boot, Tom Rini, Jernej Skrabec, André Przywara, Cody Eksal
[-- Attachment #1: Type: text/plain, Size: 6088 bytes --]
Hi Alexander,
Le Sun 14 Jun 26, 20:57, Alexander Sverdlin a écrit :
> Hi Paul,
>
> On Sun, 2026-06-14 at 15:54 +0200, Paul Kocialkowski wrote:
> > > Currently some ARM-based platforms reserve TF-A memory in their own ways:
> > > - Mediatek gets BL31 region via SMC call in ft_system_setup()
> > > - K3 uses CONFIG_K3_ATF_LOAD_ADDR, effectively in ft_system_setup()
> > >
> > > And others like Allwinner simply forget to do it, which results in Linux
> > > overwriting TF-A and crashing.
> >
> > To be fair we've been adding the reserved memory regions statically in
> > the Linux device-trees to mitigate the issue.
>
> once for H616, but it could be the only SoC among ARM64 platforms doing
> this and discouraged for A133:
> https://lore.kernel.org/all/b428d57ba5464f1226daf099877f4c25fa4fc191.camel@gmail.com/
Yes of course it would be better to have a proper solution for this.
I was only mentioning this for context.
> > But another thing we do overwrite current is the cpu idle states, which
> > are added by fdt_add_cpu_idle_states in tf-a. These are only set when the
> > SCP firmware is available (which is checked at run-time) and they are
> > never propagated to the final device-tree. Including the definitions
> > statically would result in cpu idle calls done even without the SCP
> > firmware, which would probably fail (although maybe some states can
> > still be supported).
>
> Do you refer to some unmerged code? Didn't find it in the current TF-A
> sources...
fdt_add_cpu_idle_states is in common/fdt_fixup.c and it is called by the
common allwinner code in plat/allwinner/common/sunxi_prepare_dtb.c based
on the sunxi_psci_is_scpi check (which currently always returns false
for A133).
> > Also note that the usual way to deal with this is to not load any
> > device-tree when booting the kernel, which will implicitly let U-Boot
> > use its current device-tree for Linux (with the modifications brought by
> > tf-a).
>
> ?!
> We definitely want to load the very device tree coming in the FIT image
> and pass it to the kernel from this FIT image. Sometimes people would
> have several DTs to chose from. The thing in U-Boot is basically to
> get U-Boot up and running. OF_UPSTREAM is rather to reduce the traffic
> on the U-Boot mailing list and maintainers effort, but in most of the
> cases we shall expect this DT to be not from the kernel we actually load.
Yes maybe "usual way" was not the best way to put it. "Current workaround"
would maybe have been better wording. Anyway we agree that this is not a
satisfying situation.
> > But of course I agree that it is very desirable to "forward" the
> > device-tree modifications to the kernel device-tree so we are not stuck
> > with whatever device-tree U-Boot was built with.
> >
> > > Unfortunately seems that the things are not much better on TF-A side and
> > > there is no universal way to get the reserved memory region across
> > > platforms. But there is at least a most common way in TF-A, namely
> > > reserving memory range in the FDT, in particular:
> > > - Allwinner ("tf-a@40000000" node)
> > > - ARM FPGA ("tf-a@80000000" node)
> > > - Xilinx ("tf-a" node)
> >
> > RaspberryPi seems to be using "atf@0". Generally speaking the property
> > is a free-form argument to fdt_add_reserved_memory in tf-a and I don't
> > think we can have a common way to match them.
> >
> > Introducing a Kconfig property for the prefix would be a satisfying
> > solution in my opinion.
>
> This was a very conservative patch solving the A133 case, but actually
> I don't see anything wrong with just copying all the reserved areas from
> the U-Boot live tree to the device tree we are going to pass to the
> kernel. Maybe fdtdec_add_reserved_memory() needs to be taught to detect
> overlapping ranges and extend them properly, or maybe yet another function
> has to be created for this purpose, to avoid duplicated reserved-memory
> nodes by all means,
Yes maybe a more generic approach that goes over each reserved memory
node and decides whether it needs to be copied or not would be best.
I would still be satisfied with a Kconfig prefix though.
> but would also solve the PSCI cpuidle issue, as well
> as potentially Raspi case of TF-A side and simplify TI K3 on U-Boot side.
Well the idle-state node is not in reserved-memory, it is part of the
cpus node, but it would be fairly easy to copy it over if no such node
already exists.
> > > While this patch aims to improve the situation for Allwinner platforms,
> > > it's deliberately adding more generic code to pave the potential way of
> > > unification for other platforms.
> > >
> > > Note that fdtdec_add_reserved_memory() has a check for an already existing
> > > carveout with exactly matching boundaries and will not create a duplicate
> > > even if the name doesn't match. It would not however detect an already
> > > existing bigger carveout fully containing the one requested.
> > >
> > > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > > ---
> > > The patch has been developed to faciliate Allwinner A133 SoC support, where
> > > most of the work currently happens on TF-A [1] and Linux [2] sides, but
> > > I wanted to send this patch upfront to get the first feedback and because
> > > already supported H616 SoC would already benefit from the patch.
> >
> > Thanks for looking at this!
> >
> > Like I said, I guess the same needs to be done for the cpuidle psci
> > nodes.
>
> See above, maybe there is a way to carefully copy all /reserved-memory nodes?
> Maybe this full copy shall be configurable, but with a proper overlapping-aware
> implementation maybe even a Kconfig option is not required...
It is separate from reserved-memory.
All the best,
Paul
--
Paul Kocialkowski,
Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/
Expert in multimedia, graphics and embedded hardware support with Linux.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-14 21:06 ` Paul Kocialkowski
@ 2026-06-14 22:08 ` Alexander Sverdlin
2026-06-15 10:30 ` Paul Kocialkowski
0 siblings, 1 reply; 8+ messages in thread
From: Alexander Sverdlin @ 2026-06-14 22:08 UTC (permalink / raw)
To: Paul Kocialkowski
Cc: u-boot, Tom Rini, Jernej Skrabec, André Przywara, Cody Eksal
Hi Paul,
On Sun, 2026-06-14 at 23:06 +0200, Paul Kocialkowski wrote:
> > > But another thing we do overwrite current is the cpu idle states, which
> > > are added by fdt_add_cpu_idle_states in tf-a. These are only set when the
> > > SCP firmware is available (which is checked at run-time) and they are
> > > never propagated to the final device-tree. Including the definitions
> > > statically would result in cpu idle calls done even without the SCP
> > > firmware, which would probably fail (although maybe some states can
> > > still be supported).
> >
> > Do you refer to some unmerged code? Didn't find it in the current TF-A
> > sources...
>
> fdt_add_cpu_idle_states is in common/fdt_fixup.c and it is called by the
> common allwinner code in plat/allwinner/common/sunxi_prepare_dtb.c based
> on the sunxi_psci_is_scpi check (which currently always returns false
> for A133).
sorry, I misunderstood you initially, I though there are some data structures
of the SCP firmware which are being overwritten by Linux, but it turns out,
you refer to idle-states node and compatible = "arm,idle-state" subnodes...
But contrary to /reserved-memory nodes for TF-A, these are fixed for a SoC
model, even if you'd like to load SCP firmware at a different address, right?
It looks to me that all other machines/SoCs do define this stuff statically
in the Linux DT.
I have a feeling, that idle-states node is more like a "contract" or an API
between FW and Linux and is supposed to change less frequently, while loading
TF-A to a completely different address would be transparent to Linux, as long
as we properly copy /reserved-memory nodes.
--
Alexander Sverdlin.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-14 22:08 ` Alexander Sverdlin
@ 2026-06-15 10:30 ` Paul Kocialkowski
0 siblings, 0 replies; 8+ messages in thread
From: Paul Kocialkowski @ 2026-06-15 10:30 UTC (permalink / raw)
To: Alexander Sverdlin
Cc: u-boot, Tom Rini, Jernej Skrabec, André Przywara, Cody Eksal
[-- Attachment #1: Type: text/plain, Size: 2438 bytes --]
Hi Alexander,
Le Mon 15 Jun 26, 00:08, Alexander Sverdlin a écrit :
> Hi Paul,
>
> On Sun, 2026-06-14 at 23:06 +0200, Paul Kocialkowski wrote:
> > > > But another thing we do overwrite current is the cpu idle states, which
> > > > are added by fdt_add_cpu_idle_states in tf-a. These are only set when the
> > > > SCP firmware is available (which is checked at run-time) and they are
> > > > never propagated to the final device-tree. Including the definitions
> > > > statically would result in cpu idle calls done even without the SCP
> > > > firmware, which would probably fail (although maybe some states can
> > > > still be supported).
> > >
> > > Do you refer to some unmerged code? Didn't find it in the current TF-A
> > > sources...
> >
> > fdt_add_cpu_idle_states is in common/fdt_fixup.c and it is called by the
> > common allwinner code in plat/allwinner/common/sunxi_prepare_dtb.c based
> > on the sunxi_psci_is_scpi check (which currently always returns false
> > for A133).
>
> sorry, I misunderstood you initially, I though there are some data structures
> of the SCP firmware which are being overwritten by Linux, but it turns out,
> you refer to idle-states node and compatible = "arm,idle-state" subnodes...
> But contrary to /reserved-memory nodes for TF-A, these are fixed for a SoC
> model, even if you'd like to load SCP firmware at a different address, right?
The nodes are only inserted by TF-A when the SCP firmware is present.
They should not be there without it so we cannot just have them always
present in the static device-tree declarations.
> It looks to me that all other machines/SoCs do define this stuff statically
> in the Linux DT.
I guess most of them don't consider the SCP firmware as optional but
make it a hard requirement. For Allwinner it is optional (and it's very
nice that way).
> I have a feeling, that idle-states node is more like a "contract" or an API
> between FW and Linux and is supposed to change less frequently, while loading
> TF-A to a completely different address would be transparent to Linux, as long
> as we properly copy /reserved-memory nodes.
You could see it that way yes.
All the best,
Paul
--
Paul Kocialkowski,
Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/
Expert in multimedia, graphics and embedded hardware support with Linux.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-14 18:57 ` Alexander Sverdlin
2026-06-14 21:06 ` Paul Kocialkowski
@ 2026-06-16 14:10 ` Andre Przywara
1 sibling, 0 replies; 8+ messages in thread
From: Andre Przywara @ 2026-06-16 14:10 UTC (permalink / raw)
To: Alexander Sverdlin, Paul Kocialkowski
Cc: u-boot, Tom Rini, Jernej Skrabec, Cody Eksal
Hi Alexander,
thanks for taking care of solving the problem upstream, but ... ;-)
On 6/14/26 20:57, Alexander Sverdlin wrote:
> Hi Paul,
>
> On Sun, 2026-06-14 at 15:54 +0200, Paul Kocialkowski wrote:
>>> Currently some ARM-based platforms reserve TF-A memory in their own ways:
>>> - Mediatek gets BL31 region via SMC call in ft_system_setup()
>>> - K3 uses CONFIG_K3_ATF_LOAD_ADDR, effectively in ft_system_setup()
>>>
>>> And others like Allwinner simply forget to do it, which results in Linux
>>> overwriting TF-A and crashing.
>>
>> To be fair we've been adding the reserved memory regions statically in
>> the Linux device-trees to mitigate the issue.
>
> once for H616, but it could be the only SoC among ARM64 platforms doing
> this and discouraged for A133:
> https://lore.kernel.org/all/b428d57ba5464f1226daf099877f4c25fa4fc191.camel@gmail.com/
>
>> But another thing we do overwrite current is the cpu idle states, which
>> are added by fdt_add_cpu_idle_states in tf-a. These are only set when the
>> SCP firmware is available (which is checked at run-time) and they are
>> never propagated to the final device-tree. Including the definitions
>> statically would result in cpu idle calls done even without the SCP
>> firmware, which would probably fail (although maybe some states can
>> still be supported).
>
> Do you refer to some unmerged code? Didn't find it in the current TF-A
> sources...
>
>> Also note that the usual way to deal with this is to not load any
>> device-tree when booting the kernel, which will implicitly let U-Boot
>> use its current device-tree for Linux (with the modifications brought by
>> tf-a).
>
> ?!
> We definitely want to load the very device tree coming in the FIT image
> and pass it to the kernel from this FIT image. Sometimes people would
> have several DTs to chose from. The thing in U-Boot is basically to
> get U-Boot up and running. OF_UPSTREAM is rather to reduce the traffic
> on the U-Boot mailing list and maintainers effort, but in most of the
> cases we shall expect this DT to be not from the kernel we actually load.
Sorry, buy I completely and strongly disagree here. This concept of "let
me load the DT that shipped with the kernel I am going to load" was
ill-fated from the very beginning, but back 15 years ago it was just the
only practical way of handling things, because the bootloaders were not
ready. I understand that this is how embedded people use to do things
ever since, but I don't think we should continue doing so.
By definition firmware (the combination of SPL, TF-A, U-Boot, crust in
our case) is device specific, so the board DT living in firmware is a
good match. As you said, U-Boot needs the DT anyway, and since the DT
describes the hardware, it's the same DT the kernel gets. Following this
idea, there should be one best (golden) DT for a board at any point in
time, probably the one from the latest kernel tree. And that's the one
that goes into the firmware image, and that both U-Boot and the kernel use.
For distro boot this is basically essential, and for UEFI based boot
there is actually no other choice. And I like to treat the classic
embedded boot methods more as special cases of the more generic ones.
I see a point of loading a custom DT during development, to play around
with nodes and properties, but I think there are better ways to handle this:
- Do the DT changes in the U-Boot tree, and load
u-boot-sunxi-with-spl.bin via FEL. That's what I typically do.
- Put your changes in DT overlays, and load and apply them in U-Boot:
> fdt copy $fdtcontroladdr $fdt_addr_r
> load mmc 0 fdtoverlay_addr_r my_ovl.dtbo
> fdt apply $fdtoverlay_addr_r
- Patch your changes in using U-Boot's fdt command:
> fdt copy $fdtcontroladdr $fdt_addr_r
> fdt set /path/to/node your-property <42>
And even if you really want to completely load your custom DT, this is
probably changed anyway, so you could patch in the things that need
adjustment, like the reserved memory nodes.
Cheers,
Andre
>> But of course I agree that it is very desirable to "forward" the
>> device-tree modifications to the kernel device-tree so we are not stuck
>> with whatever device-tree U-Boot was built with.
>>
>>> Unfortunately seems that the things are not much better on TF-A side and
>>> there is no universal way to get the reserved memory region across
>>> platforms. But there is at least a most common way in TF-A, namely
>>> reserving memory range in the FDT, in particular:
>>> - Allwinner ("tf-a@40000000" node)
>>> - ARM FPGA ("tf-a@80000000" node)
>>> - Xilinx ("tf-a" node)
>>
>> RaspberryPi seems to be using "atf@0". Generally speaking the property
>> is a free-form argument to fdt_add_reserved_memory in tf-a and I don't
>> think we can have a common way to match them.
>>
>> Introducing a Kconfig property for the prefix would be a satisfying
>> solution in my opinion.
>
> This was a very conservative patch solving the A133 case, but actually
> I don't see anything wrong with just copying all the reserved areas from
> the U-Boot live tree to the device tree we are going to pass to the
> kernel. Maybe fdtdec_add_reserved_memory() needs to be taught to detect
> overlapping ranges and extend them properly, or maybe yet another function
> has to be created for this purpose, to avoid duplicated reserved-memory
> nodes by all means, but would also solve the PSCI cpuidle issue, as well
> as potentially Raspi case of TF-A side and simplify TI K3 on U-Boot side.
>
>>> While this patch aims to improve the situation for Allwinner platforms,
>>> it's deliberately adding more generic code to pave the potential way of
>>> unification for other platforms.
>>>
>>> Note that fdtdec_add_reserved_memory() has a check for an already existing
>>> carveout with exactly matching boundaries and will not create a duplicate
>>> even if the name doesn't match. It would not however detect an already
>>> existing bigger carveout fully containing the one requested.
>>>
>>> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
>>> ---
>>> The patch has been developed to faciliate Allwinner A133 SoC support, where
>>> most of the work currently happens on TF-A [1] and Linux [2] sides, but
>>> I wanted to send this patch upfront to get the first feedback and because
>>> already supported H616 SoC would already benefit from the patch.
>>
>> Thanks for looking at this!
>>
>> Like I said, I guess the same needs to be done for the cpuidle psci
>> nodes.
>
> See above, maybe there is a way to carefully copy all /reserved-memory nodes?
> Maybe this full copy shall be configurable, but with a proper overlapping-aware
> implementation maybe even a Kconfig option is not required...
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux
2026-06-13 20:41 [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux Alexander Sverdlin
2026-06-14 13:54 ` Paul Kocialkowski
@ 2026-06-16 14:11 ` Andre Przywara
1 sibling, 0 replies; 8+ messages in thread
From: Andre Przywara @ 2026-06-16 14:11 UTC (permalink / raw)
To: Alexander Sverdlin, u-boot
Cc: Tom Rini, Jernej Skrabec, Paul Kocialkowski, Cody Eksal
Hi Alexander,
thanks for taking care of this upstream, and doing it in a generic (not
Allwinner specific way)!
As you can see from that other reply, I am not a fan of those
propagations from the control DT to something loaded, as this looks like
a can of worms and I think that's unnecessary.
I might be talked into accepting this for the reserved memory regions,
since they are somewhat crucial, and also generic.
On 6/13/26 22:41, Alexander Sverdlin wrote:
> Currently some ARM-based platforms reserve TF-A memory in their own ways:
> - Mediatek gets BL31 region via SMC call in ft_system_setup()
> - K3 uses CONFIG_K3_ATF_LOAD_ADDR, effectively in ft_system_setup()
>
> And others like Allwinner simply forget to do it, which results in Linux
> overwriting TF-A and crashing.
>
> Unfortunately seems that the things are not much better on TF-A side and
> there is no universal way to get the reserved memory region across
> platforms. But there is at least a most common way in TF-A, namely
> reserving memory range in the FDT, in particular:
> - Allwinner ("tf-a@40000000" node)
> - ARM FPGA ("tf-a@80000000" node)
> - Xilinx ("tf-a" node)
Regardless of the general approach, as Paul already mentioned: the node
names are by design arbitrary, and no meaning should be derived from
them. So either we just copy all reserved nodes (why not?), or we look
at the no-map property, which tells us that this region must not be
mapped, to avoid speculation by the core into this memory area. Which
would fault if this memory is secure-only. So all secure memory should
have the no-map property, though not all no-map tagged regions must be
secure-only.
One actual nice way of abstracting this is to look at U-Boot's Logical
Memory Blocks (LMBs), which is U-Boot's crude way of dealing with memory
regions. There is already code in place that puts no-map reserved
regions from the control DT into those LMBs. If you type "bdinfo" on the
U-Boot prompt, you should see them.
If you create reserved memory regions based on the LMBs, that would be
even more generic.
> While this patch aims to improve the situation for Allwinner platforms,
> it's deliberately adding more generic code to pave the potential way of
> unification for other platforms.
>
> Note that fdtdec_add_reserved_memory() has a check for an already existing
> carveout with exactly matching boundaries and will not create a duplicate
> even if the name doesn't match. It would not however detect an already
> existing bigger carveout fully containing the one requested.
Finding larger blocks should be quite easy, although there are
theoretical corner cases which get nasty. I wonder if the LMB parsing
code already solves that problem?
Cheers,
Andre
>
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> ---
> The patch has been developed to faciliate Allwinner A133 SoC support, where
> most of the work currently happens on TF-A [1] and Linux [2] sides, but
> I wanted to send this patch upfront to get the first feedback and because
> already supported H616 SoC would already benefit from the patch.
>
> [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/49754
> [2] https://lore.kernel.org/all/20260605070923.3045073-1-alexander.sverdlin@gmail.com/
> [3] https://lore.kernel.org/all/b428d57ba5464f1226daf099877f4c25fa4fc191.camel@gmail.com/
>
> arch/arm/lib/bootm-fdt.c | 55 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
> index 2671f9a0ebf..19d917943c1 100644
> --- a/arch/arm/lib/bootm-fdt.c
> +++ b/arch/arm/lib/bootm-fdt.c
> @@ -14,7 +14,9 @@
> * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
> */
>
> +#include <dm/ofnode.h>
> #include <fdt_support.h>
> +#include <linux/ioport.h>
> #ifdef CONFIG_ARMV7_NONSEC
> #include <asm/armv7.h>
> #endif
> @@ -24,6 +26,52 @@
>
> DECLARE_GLOBAL_DATA_PTR;
>
> +static int tfa_copy_reserved_memory(void *new_blob)
> +{
> +#ifdef CONFIG_OF_CONTROL
> + ofnode node, subnode;
> +
> + /*
> + * TF-A for several platforms inserts its memory region as
> + * reserved-memory node
> + */
> + node = ofnode_path("/reserved-memory");
> + if (!ofnode_valid(node))
> + return 0;
> +
> + ofnode_for_each_subnode(subnode, node) {
> + struct fdt_memory carveout;
> + struct resource res;
> + const char *name;
> + int ret;
> +
> + name = ofnode_get_name(subnode);
> + if (!name)
> + return -FDT_ERR_BADSTRUCTURE;
> +
> + /* only handle TF-A reservations */
> + if (strncmp(name, "tf-a", 4))
> + continue;
> +
> + /* check if this subnode has a reg property */
> + ret = ofnode_read_resource(subnode, 0, &res);
> + if (ret)
> + continue;
> +
> + carveout.start = res.start,
> + carveout.end = res.end,
> +
> + ret = fdtdec_add_reserved_memory(new_blob, "tf-a", &carveout,
> + NULL, 0, NULL,
> + FDTDEC_RESERVED_MEMORY_NO_MAP);
> + if (ret < 0)
> + return ret;
> + }
> +#endif
> +
> + return 0;
> +}
> +
> #ifdef CONFIG_FMAN_ENET
> __weak int fdt_update_ethernet_dt(void *blob)
> {
> @@ -56,6 +104,13 @@ int arch_fixup_fdt(void *blob)
> return ret;
> #endif
>
> + ret = tfa_copy_reserved_memory(blob);
> + if (ret) {
> + printf("ERROR: transfer of TF-A nodes to new fdt failed: %s\n",
> + fdt_strerror(ret));
> + return ret;
> + }
> +
> #ifdef CONFIG_ARMV8_SPIN_TABLE
> ret = spin_table_update_dt(blob);
> if (ret)
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-16 14:11 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-13 20:41 [PATCH] ARM: fdt: copy TF-A reserved memory into fdt passed to Linux Alexander Sverdlin
2026-06-14 13:54 ` Paul Kocialkowski
2026-06-14 18:57 ` Alexander Sverdlin
2026-06-14 21:06 ` Paul Kocialkowski
2026-06-14 22:08 ` Alexander Sverdlin
2026-06-15 10:30 ` Paul Kocialkowski
2026-06-16 14:10 ` Andre Przywara
2026-06-16 14:11 ` Andre Przywara
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.