diff mbox

[U-Boot,4/8] ARMv8: PSCI: Add linker section to hold PSCI code

Message ID 1409171401-22616-5-git-send-email-arnab.basu@freescale.com
State Changes Requested
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Arnab Basu Aug. 27, 2014, 8:29 p.m. UTC
A separate linker section makes it possible to keep this code either
in DDR or in some secure memory location provided specifically for the
purpose.

So far no one is using this section.

Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/config.mk            |    2 +-
 arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)

Comments

Albert ARIBAUD Sept. 18, 2014, 9:12 a.m. UTC | #1
Hi Arnab,

On Thu, 28 Aug 2014 01:59:57 +0530, Arnab Basu
<arnab.basu@freescale.com> wrote:

> A separate linker section makes it possible to keep this code either
> in DDR or in some secure memory location provided specifically for the
> purpose.
> 
> So far no one is using this section.
> 
> Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
> Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/config.mk            |    2 +-
>  arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
>  2 files changed, 31 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/config.mk b/arch/arm/config.mk
> index c339e6d..9272e9c 100644
> --- a/arch/arm/config.mk
> +++ b/arch/arm/config.mk
> @@ -111,7 +111,7 @@ endif
>  
>  # limit ourselves to the sections we want in the .bin.
>  ifdef CONFIG_ARM64
> -OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
> +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
>  else
>  OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
>  endif
> diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
> index 4c12222..bd95fff 100644
> --- a/arch/arm/cpu/armv8/u-boot.lds
> +++ b/arch/arm/cpu/armv8/u-boot.lds
> @@ -8,6 +8,8 @@
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> +#include <config.h>
> +
>  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
>  OUTPUT_ARCH(aarch64)
>  ENTRY(_start)
> @@ -23,6 +25,34 @@ SECTIONS
>  		*(.text*)
>  	}
>  
> +#ifdef CONFIG_ARMV8_PSCI
> +
> +#ifndef CONFIG_ARMV8_SECURE_BASE
> +#define CONFIG_ARMV8_SECURE_BASE
> +#endif
> +
> +	.__secure_start : {
> +		. = ALIGN(0x1000);
> +		*(.__secure_start)
> +	}
> +
> +	.secure_text CONFIG_ARMV8_SECURE_BASE :
> +		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
> +	{
> +		*(._secure.text)
> +	}
> +
> +	. = LOADADDR(.__secure_start) +
> +		SIZEOF(.__secure_start) +
> +		SIZEOF(.secure_text);
> +
> +	__secure_end_lma = .;
> +	.__secure_end : AT(__secure_end_lma) {
> +		*(.__secure_end)
> +		LONG(0x1d1071c);	/* Must output something to reset LMA */

Can you explain in more detail what issue this fixes?

> +	}
> +#endif
> +
>  	. = ALIGN(8);
>  	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
>  


Amicalement,
Marc Zyngier Sept. 18, 2014, 3:28 p.m. UTC | #2
On Thu, Sep 18 2014 at 10:12:17 AM, Albert ARIBAUD <albert.u.boot@aribaud.net> wrote:
> Hi Arnab,
>
> On Thu, 28 Aug 2014 01:59:57 +0530, Arnab Basu
> <arnab.basu@freescale.com> wrote:
>
>> A separate linker section makes it possible to keep this code either
>> in DDR or in some secure memory location provided specifically for the
>> purpose.
>> 
>> So far no one is using this section.
>> 
>> Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
>> Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm/config.mk            |    2 +-
>>  arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
>>  2 files changed, 31 insertions(+), 1 deletions(-)
>> 
>> diff --git a/arch/arm/config.mk b/arch/arm/config.mk
>> index c339e6d..9272e9c 100644
>> --- a/arch/arm/config.mk
>> +++ b/arch/arm/config.mk
>> @@ -111,7 +111,7 @@ endif
>>  
>>  # limit ourselves to the sections we want in the .bin.
>>  ifdef CONFIG_ARM64
>> -OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
>> +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
>>  else
>>  OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
>>  endif
>> diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
>> index 4c12222..bd95fff 100644
>> --- a/arch/arm/cpu/armv8/u-boot.lds
>> +++ b/arch/arm/cpu/armv8/u-boot.lds
>> @@ -8,6 +8,8 @@
>>   * SPDX-License-Identifier:	GPL-2.0+
>>   */
>>  
>> +#include <config.h>
>> +
>>  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
>>  OUTPUT_ARCH(aarch64)
>>  ENTRY(_start)
>> @@ -23,6 +25,34 @@ SECTIONS
>>  		*(.text*)
>>  	}
>>  
>> +#ifdef CONFIG_ARMV8_PSCI
>> +
>> +#ifndef CONFIG_ARMV8_SECURE_BASE
>> +#define CONFIG_ARMV8_SECURE_BASE
>> +#endif
>> +
>> +	.__secure_start : {
>> +		. = ALIGN(0x1000);
>> +		*(.__secure_start)
>> +	}
>> +
>> +	.secure_text CONFIG_ARMV8_SECURE_BASE :
>> +		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
>> +	{
>> +		*(._secure.text)
>> +	}
>> +
>> +	. = LOADADDR(.__secure_start) +
>> +		SIZEOF(.__secure_start) +
>> +		SIZEOF(.secure_text);
>> +
>> +	__secure_end_lma = .;
>> +	.__secure_end : AT(__secure_end_lma) {
>> +		*(.__secure_end)
>> +		LONG(0x1d1071c);	/* Must output something to reset LMA */
>
> Can you explain in more detail what issue this fixes?

If you use AT to force a new load address (LMA), you must ensure that
you actually output something at this address. Here, if *(.__secure_end)
ends up being empty, whatever follows would be as if the AT never
happened, ending up at the wrong LMA.

The workaround is to force the output of a dummy value in all
cases, ensuring that the rest of the text is at a sensible LMA. This is
an issue that has been in GNU ld for years, and this workaround is a
copy/paste of the same one in the ARMv7 ld script.

Thanks,

	M.
Albert ARIBAUD Sept. 19, 2014, 4:04 p.m. UTC | #3
Hi Marc,

On Thu, 18 Sep 2014 16:28:52 +0100, Marc Zyngier <marc.zyngier@arm.com>
wrote:

> On Thu, Sep 18 2014 at 10:12:17 AM, Albert ARIBAUD <albert.u.boot@aribaud.net> wrote:
> > Hi Arnab,
> >
> > On Thu, 28 Aug 2014 01:59:57 +0530, Arnab Basu
> > <arnab.basu@freescale.com> wrote:
> >
> >> A separate linker section makes it possible to keep this code either
> >> in DDR or in some secure memory location provided specifically for the
> >> purpose.
> >> 
> >> So far no one is using this section.
> >> 
> >> Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
> >> Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> >> Cc: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm/config.mk            |    2 +-
> >>  arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
> >>  2 files changed, 31 insertions(+), 1 deletions(-)
> >> 
> >> diff --git a/arch/arm/config.mk b/arch/arm/config.mk
> >> index c339e6d..9272e9c 100644
> >> --- a/arch/arm/config.mk
> >> +++ b/arch/arm/config.mk
> >> @@ -111,7 +111,7 @@ endif
> >>  
> >>  # limit ourselves to the sections we want in the .bin.
> >>  ifdef CONFIG_ARM64
> >> -OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
> >> +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
> >>  else
> >>  OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
> >>  endif
> >> diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
> >> index 4c12222..bd95fff 100644
> >> --- a/arch/arm/cpu/armv8/u-boot.lds
> >> +++ b/arch/arm/cpu/armv8/u-boot.lds
> >> @@ -8,6 +8,8 @@
> >>   * SPDX-License-Identifier:	GPL-2.0+
> >>   */
> >>  
> >> +#include <config.h>
> >> +
> >>  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
> >>  OUTPUT_ARCH(aarch64)
> >>  ENTRY(_start)
> >> @@ -23,6 +25,34 @@ SECTIONS
> >>  		*(.text*)
> >>  	}
> >>  
> >> +#ifdef CONFIG_ARMV8_PSCI
> >> +
> >> +#ifndef CONFIG_ARMV8_SECURE_BASE
> >> +#define CONFIG_ARMV8_SECURE_BASE
> >> +#endif
> >> +
> >> +	.__secure_start : {
> >> +		. = ALIGN(0x1000);
> >> +		*(.__secure_start)
> >> +	}
> >> +
> >> +	.secure_text CONFIG_ARMV8_SECURE_BASE :
> >> +		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
> >> +	{
> >> +		*(._secure.text)
> >> +	}
> >> +
> >> +	. = LOADADDR(.__secure_start) +
> >> +		SIZEOF(.__secure_start) +
> >> +		SIZEOF(.secure_text);
> >> +
> >> +	__secure_end_lma = .;
> >> +	.__secure_end : AT(__secure_end_lma) {
> >> +		*(.__secure_end)
> >> +		LONG(0x1d1071c);	/* Must output something to reset LMA */
> >
> > Can you explain in more detail what issue this fixes?
> 
> If you use AT to force a new load address (LMA), you must ensure that
> you actually output something at this address. Here, if *(.__secure_end)
> ends up being empty, whatever follows would be as if the AT never
> happened, ending up at the wrong LMA.
>
> The workaround is to force the output of a dummy value in all
> cases, ensuring that the rest of the text is at a sensible LMA. This is
> an issue that has been in GNU ld for years, and this workaround is a
> copy/paste of the same one in the ARMv7 ld script.

I see. Does the ld bug have an identifier that we could mention in a
comment in the linker script as a reference?

> Thanks,
> 
> 	M.

Amicalement,
Albert ARIBAUD Oct. 11, 2014, 11:27 a.m. UTC | #4
Hi Albert,

On Fri, 19 Sep 2014 18:04:14 +0200, Albert ARIBAUD
<albert.u.boot@aribaud.net> wrote:

> Hi Marc,
> 
> On Thu, 18 Sep 2014 16:28:52 +0100, Marc Zyngier <marc.zyngier@arm.com>
> wrote:
> 
> > On Thu, Sep 18 2014 at 10:12:17 AM, Albert ARIBAUD <albert.u.boot@aribaud.net> wrote:
> > > Hi Arnab,
> > >
> > > On Thu, 28 Aug 2014 01:59:57 +0530, Arnab Basu
> > > <arnab.basu@freescale.com> wrote:
> > >
> > >> A separate linker section makes it possible to keep this code either
> > >> in DDR or in some secure memory location provided specifically for the
> > >> purpose.
> > >> 
> > >> So far no one is using this section.
> > >> 
> > >> Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
> > >> Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> > >> Cc: Marc Zyngier <marc.zyngier@arm.com>
> > >> ---
> > >>  arch/arm/config.mk            |    2 +-
> > >>  arch/arm/cpu/armv8/u-boot.lds |   30 ++++++++++++++++++++++++++++++
> > >>  2 files changed, 31 insertions(+), 1 deletions(-)
> > >> 
> > >> diff --git a/arch/arm/config.mk b/arch/arm/config.mk
> > >> index c339e6d..9272e9c 100644
> > >> --- a/arch/arm/config.mk
> > >> +++ b/arch/arm/config.mk
> > >> @@ -111,7 +111,7 @@ endif
> > >>  
> > >>  # limit ourselves to the sections we want in the .bin.
> > >>  ifdef CONFIG_ARM64
> > >> -OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
> > >> +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
> > >>  else
> > >>  OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
> > >>  endif
> > >> diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
> > >> index 4c12222..bd95fff 100644
> > >> --- a/arch/arm/cpu/armv8/u-boot.lds
> > >> +++ b/arch/arm/cpu/armv8/u-boot.lds
> > >> @@ -8,6 +8,8 @@
> > >>   * SPDX-License-Identifier:	GPL-2.0+
> > >>   */
> > >>  
> > >> +#include <config.h>
> > >> +
> > >>  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
> > >>  OUTPUT_ARCH(aarch64)
> > >>  ENTRY(_start)
> > >> @@ -23,6 +25,34 @@ SECTIONS
> > >>  		*(.text*)
> > >>  	}
> > >>  
> > >> +#ifdef CONFIG_ARMV8_PSCI
> > >> +
> > >> +#ifndef CONFIG_ARMV8_SECURE_BASE
> > >> +#define CONFIG_ARMV8_SECURE_BASE
> > >> +#endif
> > >> +
> > >> +	.__secure_start : {
> > >> +		. = ALIGN(0x1000);
> > >> +		*(.__secure_start)
> > >> +	}
> > >> +
> > >> +	.secure_text CONFIG_ARMV8_SECURE_BASE :
> > >> +		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
> > >> +	{
> > >> +		*(._secure.text)
> > >> +	}
> > >> +
> > >> +	. = LOADADDR(.__secure_start) +
> > >> +		SIZEOF(.__secure_start) +
> > >> +		SIZEOF(.secure_text);
> > >> +
> > >> +	__secure_end_lma = .;
> > >> +	.__secure_end : AT(__secure_end_lma) {
> > >> +		*(.__secure_end)
> > >> +		LONG(0x1d1071c);	/* Must output something to reset LMA */
> > >
> > > Can you explain in more detail what issue this fixes?
> > 
> > If you use AT to force a new load address (LMA), you must ensure that
> > you actually output something at this address. Here, if *(.__secure_end)
> > ends up being empty, whatever follows would be as if the AT never
> > happened, ending up at the wrong LMA.
> >
> > The workaround is to force the output of a dummy value in all
> > cases, ensuring that the rest of the text is at a sensible LMA. This is
> > an issue that has been in GNU ld for years, and this workaround is a
> > copy/paste of the same one in the ARMv7 ld script.
> 
> I see. Does the ld bug have an identifier that we could mention in a
> comment in the linker script as a reference?

Ping.

> > Thanks,
> > 
> > 	M.
> 
> Amicalement,

Amicalement,
Marc Zyngier Oct. 11, 2014, 4:04 p.m. UTC | #5
On 2014-10-11 12:27, Albert ARIBAUD wrote:
> Hi Albert,
>
> On Fri, 19 Sep 2014 18:04:14 +0200, Albert ARIBAUD
> <albert.u.boot@aribaud.net> wrote:
>
>> Hi Marc,
>>
>> On Thu, 18 Sep 2014 16:28:52 +0100, Marc Zyngier 
>> <marc.zyngier@arm.com>
>> wrote:
>>
>> > On Thu, Sep 18 2014 at 10:12:17 AM, Albert ARIBAUD 
>> <albert.u.boot@aribaud.net> wrote:
>> > > Hi Arnab,
>> > >
>> > > On Thu, 28 Aug 2014 01:59:57 +0530, Arnab Basu
>> > > <arnab.basu@freescale.com> wrote:
>> > >
>> > >> A separate linker section makes it possible to keep this code 
>> either
>> > >> in DDR or in some secure memory location provided specifically 
>> for the
>> > >> purpose.
>> > >>
>> > >> So far no one is using this section.
>> > >>
>> > >> Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
>> > >> Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
>> > >> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> > >> ---
>> > >>  arch/arm/config.mk            |    2 +-
>> > >>  arch/arm/cpu/armv8/u-boot.lds |   30 
>> ++++++++++++++++++++++++++++++
>> > >>  2 files changed, 31 insertions(+), 1 deletions(-)
>> > >>
>> > >> diff --git a/arch/arm/config.mk b/arch/arm/config.mk
>> > >> index c339e6d..9272e9c 100644
>> > >> --- a/arch/arm/config.mk
>> > >> +++ b/arch/arm/config.mk
>> > >> @@ -111,7 +111,7 @@ endif
>> > >>
>> > >>  # limit ourselves to the sections we want in the .bin.
>> > >>  ifdef CONFIG_ARM64
>> > >> -OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list 
>> -j .rela.dyn
>> > >> +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data 
>> -j .u_boot_list -j .rela.dyn
>> > >>  else
>> > >>  OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash 
>> -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
>> > >>  endif
>> > >> diff --git a/arch/arm/cpu/armv8/u-boot.lds 
>> b/arch/arm/cpu/armv8/u-boot.lds
>> > >> index 4c12222..bd95fff 100644
>> > >> --- a/arch/arm/cpu/armv8/u-boot.lds
>> > >> +++ b/arch/arm/cpu/armv8/u-boot.lds
>> > >> @@ -8,6 +8,8 @@
>> > >>   * SPDX-License-Identifier:	GPL-2.0+
>> > >>   */
>> > >>
>> > >> +#include <config.h>
>> > >> +
>> > >>  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", 
>> "elf64-littleaarch64")
>> > >>  OUTPUT_ARCH(aarch64)
>> > >>  ENTRY(_start)
>> > >> @@ -23,6 +25,34 @@ SECTIONS
>> > >>  		*(.text*)
>> > >>  	}
>> > >>
>> > >> +#ifdef CONFIG_ARMV8_PSCI
>> > >> +
>> > >> +#ifndef CONFIG_ARMV8_SECURE_BASE
>> > >> +#define CONFIG_ARMV8_SECURE_BASE
>> > >> +#endif
>> > >> +
>> > >> +	.__secure_start : {
>> > >> +		. = ALIGN(0x1000);
>> > >> +		*(.__secure_start)
>> > >> +	}
>> > >> +
>> > >> +	.secure_text CONFIG_ARMV8_SECURE_BASE :
>> > >> +		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
>> > >> +	{
>> > >> +		*(._secure.text)
>> > >> +	}
>> > >> +
>> > >> +	. = LOADADDR(.__secure_start) +
>> > >> +		SIZEOF(.__secure_start) +
>> > >> +		SIZEOF(.secure_text);
>> > >> +
>> > >> +	__secure_end_lma = .;
>> > >> +	.__secure_end : AT(__secure_end_lma) {
>> > >> +		*(.__secure_end)
>> > >> +		LONG(0x1d1071c);	/* Must output something to reset LMA */
>> > >
>> > > Can you explain in more detail what issue this fixes?
>> >
>> > If you use AT to force a new load address (LMA), you must ensure 
>> that
>> > you actually output something at this address. Here, if 
>> *(.__secure_end)
>> > ends up being empty, whatever follows would be as if the AT never
>> > happened, ending up at the wrong LMA.
>> >
>> > The workaround is to force the output of a dummy value in all
>> > cases, ensuring that the rest of the text is at a sensible LMA. 
>> This is
>> > an issue that has been in GNU ld for years, and this workaround is 
>> a
>> > copy/paste of the same one in the ARMv7 ld script.
>>
>> I see. Does the ld bug have an identifier that we could mention in a
>> comment in the linker script as a reference?

The only report I'm aware of is this one:
https://sourceware.org/bugzilla/show_bug.cgi?id=948

There may be other ways to work around this, but my linker-foo is 
admittedly pretty limited.

Thanks,

         M.
diff mbox

Patch

diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index c339e6d..9272e9c 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -111,7 +111,7 @@  endif
 
 # limit ourselves to the sections we want in the .bin.
 ifdef CONFIG_ARM64
-OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
 OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
index 4c12222..bd95fff 100644
--- a/arch/arm/cpu/armv8/u-boot.lds
+++ b/arch/arm/cpu/armv8/u-boot.lds
@@ -8,6 +8,8 @@ 
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 ENTRY(_start)
@@ -23,6 +25,34 @@  SECTIONS
 		*(.text*)
 	}
 
+#ifdef CONFIG_ARMV8_PSCI
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#endif
+
+	.__secure_start : {
+		. = ALIGN(0x1000);
+		*(.__secure_start)
+	}
+
+	.secure_text CONFIG_ARMV8_SECURE_BASE :
+		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+	{
+		*(._secure.text)
+	}
+
+	. = LOADADDR(.__secure_start) +
+		SIZEOF(.__secure_start) +
+		SIZEOF(.secure_text);
+
+	__secure_end_lma = .;
+	.__secure_end : AT(__secure_end_lma) {
+		*(.__secure_end)
+		LONG(0x1d1071c);	/* Must output something to reset LMA */
+	}
+#endif
+
 	. = ALIGN(8);
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }