mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 15:24:54 +00:00
Add support for BL2 in XIP memory
In some use-cases BL2 will be stored in eXecute In Place (XIP) memory, like BL1. In these use-cases, it is necessary to initialize the RW sections in RAM, while leaving the RO sections in place. This patch enable this use-case with a new build option, BL2_IN_XIP_MEM. For now, this option is only supported when BL2_AT_EL3 is 1. Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
This commit is contained in:
parent
93883a2931
commit
7d173fc594
8 changed files with 125 additions and 5 deletions
7
Makefile
7
Makefile
|
@ -373,6 +373,11 @@ ifneq ($(MULTI_CONSOLE_API), 0)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
#For now, BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is 1.
|
||||||
|
ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1)
|
||||||
|
$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
|
||||||
|
endif
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Process platform overrideable behaviour
|
# Process platform overrideable behaviour
|
||||||
################################################################################
|
################################################################################
|
||||||
|
@ -518,6 +523,7 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM))
|
||||||
$(eval $(call assert_boolean,USE_TBBR_DEFS))
|
$(eval $(call assert_boolean,USE_TBBR_DEFS))
|
||||||
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
|
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
|
||||||
$(eval $(call assert_boolean,BL2_AT_EL3))
|
$(eval $(call assert_boolean,BL2_AT_EL3))
|
||||||
|
$(eval $(call assert_boolean,BL2_IN_XIP_MEM))
|
||||||
|
|
||||||
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
|
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
|
||||||
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
|
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
|
||||||
|
@ -564,6 +570,7 @@ $(eval $(call add_define,USE_COHERENT_MEM))
|
||||||
$(eval $(call add_define,USE_TBBR_DEFS))
|
$(eval $(call add_define,USE_TBBR_DEFS))
|
||||||
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
|
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
|
||||||
$(eval $(call add_define,BL2_AT_EL3))
|
$(eval $(call add_define,BL2_AT_EL3))
|
||||||
|
$(eval $(call add_define,BL2_IN_XIP_MEM))
|
||||||
|
|
||||||
# Define the EL3_PAYLOAD_BASE flag only if it is provided.
|
# Define the EL3_PAYLOAD_BASE flag only if it is provided.
|
||||||
ifdef EL3_PAYLOAD_BASE
|
ifdef EL3_PAYLOAD_BASE
|
||||||
|
|
|
@ -12,15 +12,26 @@ OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
|
||||||
ENTRY(bl2_entrypoint)
|
ENTRY(bl2_entrypoint)
|
||||||
|
|
||||||
MEMORY {
|
MEMORY {
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
|
||||||
|
RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
|
||||||
|
#else
|
||||||
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
|
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
. = BL2_RO_BASE;
|
||||||
|
ASSERT(. == ALIGN(PAGE_SIZE),
|
||||||
|
"BL2_RO_BASE address is not aligned on a page boundary.")
|
||||||
|
#else
|
||||||
. = BL2_BASE;
|
. = BL2_BASE;
|
||||||
ASSERT(. == ALIGN(PAGE_SIZE),
|
ASSERT(. == ALIGN(PAGE_SIZE),
|
||||||
"BL2_BASE address is not aligned on a page boundary.")
|
"BL2_BASE address is not aligned on a page boundary.")
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SEPARATE_CODE_AND_RODATA
|
#if SEPARATE_CODE_AND_RODATA
|
||||||
.text . : {
|
.text . : {
|
||||||
|
@ -33,7 +44,11 @@ SECTIONS
|
||||||
*(.vectors)
|
*(.vectors)
|
||||||
. = NEXT(PAGE_SIZE);
|
. = NEXT(PAGE_SIZE);
|
||||||
__TEXT_END__ = .;
|
__TEXT_END__ = .;
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
} >ROM
|
||||||
|
#else
|
||||||
} >RAM
|
} >RAM
|
||||||
|
#endif
|
||||||
|
|
||||||
.rodata . : {
|
.rodata . : {
|
||||||
__RODATA_START__ = .;
|
__RODATA_START__ = .;
|
||||||
|
@ -56,7 +71,11 @@ SECTIONS
|
||||||
|
|
||||||
. = NEXT(PAGE_SIZE);
|
. = NEXT(PAGE_SIZE);
|
||||||
__RODATA_END__ = .;
|
__RODATA_END__ = .;
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
} >ROM
|
||||||
|
#else
|
||||||
} >RAM
|
} >RAM
|
||||||
|
#endif
|
||||||
|
|
||||||
ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
|
ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
|
||||||
"Resident part of BL2 has exceeded its limit.")
|
"Resident part of BL2 has exceeded its limit.")
|
||||||
|
@ -95,12 +114,22 @@ SECTIONS
|
||||||
. = NEXT(PAGE_SIZE);
|
. = NEXT(PAGE_SIZE);
|
||||||
|
|
||||||
__RO_END__ = .;
|
__RO_END__ = .;
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
} >ROM
|
||||||
|
#else
|
||||||
} >RAM
|
} >RAM
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
|
ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
|
||||||
"cpu_ops not defined for this platform.")
|
"cpu_ops not defined for this platform.")
|
||||||
|
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
. = BL2_RW_BASE;
|
||||||
|
ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
|
||||||
|
"BL2_RW_BASE address is not aligned on a page boundary.")
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define a linker symbol to mark start of the RW memory area for this
|
* Define a linker symbol to mark start of the RW memory area for this
|
||||||
* image.
|
* image.
|
||||||
|
@ -113,10 +142,14 @@ SECTIONS
|
||||||
* section can be placed independently of the main .data section.
|
* section can be placed independently of the main .data section.
|
||||||
*/
|
*/
|
||||||
.data . : {
|
.data . : {
|
||||||
__DATA_START__ = .;
|
__DATA_RAM_START__ = .;
|
||||||
*(.data*)
|
*(.data*)
|
||||||
__DATA_END__ = .;
|
__DATA_RAM_END__ = .;
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
} >RAM AT>ROM
|
||||||
|
#else
|
||||||
} >RAM
|
} >RAM
|
||||||
|
#endif
|
||||||
|
|
||||||
stacks (NOLOAD) : {
|
stacks (NOLOAD) : {
|
||||||
__STACKS_START__ = .;
|
__STACKS_START__ = .;
|
||||||
|
@ -174,12 +207,32 @@ SECTIONS
|
||||||
__RW_END__ = .;
|
__RW_END__ = .;
|
||||||
__BL2_END__ = .;
|
__BL2_END__ = .;
|
||||||
|
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
__BL2_RAM_START__ = ADDR(.data);
|
||||||
|
__BL2_RAM_END__ = .;
|
||||||
|
|
||||||
|
__DATA_ROM_START__ = LOADADDR(.data);
|
||||||
|
__DATA_SIZE__ = SIZEOF(.data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The .data section is the last PROGBITS section so its end marks the end
|
||||||
|
* of BL2's RO content in XIP memory..
|
||||||
|
*/
|
||||||
|
__BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__;
|
||||||
|
ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
|
||||||
|
"BL2's RO content has exceeded its limit.")
|
||||||
|
#endif
|
||||||
__BSS_SIZE__ = SIZEOF(.bss);
|
__BSS_SIZE__ = SIZEOF(.bss);
|
||||||
|
|
||||||
|
|
||||||
#if USE_COHERENT_MEM
|
#if USE_COHERENT_MEM
|
||||||
__COHERENT_RAM_UNALIGNED_SIZE__ =
|
__COHERENT_RAM_UNALIGNED_SIZE__ =
|
||||||
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
|
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
|
||||||
|
#else
|
||||||
ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
|
ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,20 @@
|
||||||
#ifndef __BL2_PRIVATE_H__
|
#ifndef __BL2_PRIVATE_H__
|
||||||
#define __BL2_PRIVATE_H__
|
#define __BL2_PRIVATE_H__
|
||||||
|
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
/*******************************************************************************
|
||||||
|
* Declarations of linker defined symbols which will tell us where BL2 lives
|
||||||
|
* in Trusted ROM and RAM
|
||||||
|
******************************************************************************/
|
||||||
|
extern uintptr_t __BL2_ROM_END__;
|
||||||
|
#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
|
||||||
|
|
||||||
|
extern uintptr_t __BL2_RAM_START__;
|
||||||
|
extern uintptr_t __BL2_RAM_END__;
|
||||||
|
#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
|
||||||
|
#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
* Forward declarations
|
* Forward declarations
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
|
|
@ -217,11 +217,37 @@ platform port to define additional platform porting constants in
|
||||||
- **#define : BL2\_BASE**
|
- **#define : BL2\_BASE**
|
||||||
|
|
||||||
Defines the base address in secure RAM where BL1 loads the BL2 binary image.
|
Defines the base address in secure RAM where BL1 loads the BL2 binary image.
|
||||||
Must be aligned on a page-size boundary.
|
Must be aligned on a page-size boundary. This constant is not applicable
|
||||||
|
when BL2_IN_XIP_MEM is set to '1'.
|
||||||
|
|
||||||
- **#define : BL2\_LIMIT**
|
- **#define : BL2\_LIMIT**
|
||||||
|
|
||||||
Defines the maximum address in secure RAM that the BL2 image can occupy.
|
Defines the maximum address in secure RAM that the BL2 image can occupy.
|
||||||
|
This constant is not applicable when BL2_IN_XIP_MEM is set to '1'.
|
||||||
|
|
||||||
|
- **#define : BL2\_RO\_BASE**
|
||||||
|
|
||||||
|
Defines the base address in secure XIP memory where BL2 RO section originally
|
||||||
|
lives. Must be aligned on a page-size boundary. This constant is only needed
|
||||||
|
when BL2_IN_XIP_MEM is set to '1'.
|
||||||
|
|
||||||
|
- **#define : BL2\_RO\_LIMIT**
|
||||||
|
|
||||||
|
Defines the maximum address in secure XIP memory that BL2's actual content
|
||||||
|
(i.e. excluding any data section allocated at runtime) can occupy. This
|
||||||
|
constant is only needed when BL2_IN_XIP_MEM is set to '1'.
|
||||||
|
|
||||||
|
- **#define : BL2\_RW\_BASE**
|
||||||
|
|
||||||
|
Defines the base address in secure RAM where BL2's read-write data will live
|
||||||
|
at runtime. Must be aligned on a page-size boundary. This constant is only
|
||||||
|
needed when BL2_IN_XIP_MEM is set to '1'.
|
||||||
|
|
||||||
|
- **#define : BL2\_RW\_LIMIT**
|
||||||
|
|
||||||
|
Defines the maximum address in secure RAM that BL2's read-write data can
|
||||||
|
occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set
|
||||||
|
to '1'.
|
||||||
|
|
||||||
- **#define : BL31\_BASE**
|
- **#define : BL31\_BASE**
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,12 @@ Common build options
|
||||||
- ``BL2_AT_EL3``: This is an optional build option that enables the use of
|
- ``BL2_AT_EL3``: This is an optional build option that enables the use of
|
||||||
BL2 at EL3 execution level.
|
BL2 at EL3 execution level.
|
||||||
|
|
||||||
|
- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
|
||||||
|
(XIP) memory, like BL1. In these use-cases, it is necessary to initialize
|
||||||
|
the RW sections in RAM, while leaving the RO sections in place. This option
|
||||||
|
enable this use-case. For now, this option is only supported when BL2_AT_EL3
|
||||||
|
is set to '1'.
|
||||||
|
|
||||||
- ``BL31``: This is an optional build option which specifies the path to
|
- ``BL31``: This is an optional build option which specifies the path to
|
||||||
BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
|
BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
|
||||||
be built.
|
be built.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -294,7 +294,7 @@
|
||||||
bl zeromem
|
bl zeromem
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IMAGE_BL1
|
#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM)
|
||||||
ldr x0, =__DATA_RAM_START__
|
ldr x0, =__DATA_RAM_START__
|
||||||
ldr x1, =__DATA_ROM_START__
|
ldr x1, =__DATA_ROM_START__
|
||||||
ldr x2, =__DATA_SIZE__
|
ldr x2, =__DATA_SIZE__
|
||||||
|
|
|
@ -78,9 +78,19 @@
|
||||||
#define BL1_CODE_END BL_CODE_END
|
#define BL1_CODE_END BL_CODE_END
|
||||||
#define BL1_RO_DATA_BASE BL_RO_DATA_BASE
|
#define BL1_RO_DATA_BASE BL_RO_DATA_BASE
|
||||||
#define BL1_RO_DATA_END round_up(BL1_ROM_END, PAGE_SIZE)
|
#define BL1_RO_DATA_END round_up(BL1_ROM_END, PAGE_SIZE)
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
#define BL2_CODE_END BL_CODE_END
|
||||||
|
#define BL2_RO_DATA_BASE BL_RO_DATA_BASE
|
||||||
|
#define BL2_RO_DATA_END round_up(BL2_ROM_END, PAGE_SIZE)
|
||||||
|
#endif /* BL2_IN_XIP_MEM */
|
||||||
#else
|
#else
|
||||||
#define BL_RO_DATA_BASE 0
|
#define BL_RO_DATA_BASE 0
|
||||||
#define BL_RO_DATA_END 0
|
#define BL_RO_DATA_END 0
|
||||||
#define BL1_CODE_END round_up(BL1_ROM_END, PAGE_SIZE)
|
#define BL1_CODE_END round_up(BL1_ROM_END, PAGE_SIZE)
|
||||||
|
#if BL2_IN_XIP_MEM
|
||||||
|
#define BL2_RO_DATA_BASE 0
|
||||||
|
#define BL2_RO_DATA_END 0
|
||||||
|
#define BL2_CODE_END round_up(BL2_ROM_END, PAGE_SIZE)
|
||||||
|
#endif /* BL2_IN_XIP_MEM */
|
||||||
#endif /* SEPARATE_CODE_AND_RODATA */
|
#endif /* SEPARATE_CODE_AND_RODATA */
|
||||||
#endif /* __COMMON_DEF_H__ */
|
#endif /* __COMMON_DEF_H__ */
|
||||||
|
|
|
@ -30,6 +30,10 @@ BASE_COMMIT := origin/master
|
||||||
# Execute BL2 at EL3
|
# Execute BL2 at EL3
|
||||||
BL2_AT_EL3 := 0
|
BL2_AT_EL3 := 0
|
||||||
|
|
||||||
|
# BL2 image is stored in XIP memory, for now, this option is only supported
|
||||||
|
# when BL2_AT_EL3 is 1.
|
||||||
|
BL2_IN_XIP_MEM := 0
|
||||||
|
|
||||||
# By default, consider that the platform may release several CPUs out of reset.
|
# By default, consider that the platform may release several CPUs out of reset.
|
||||||
# The platform Makefile is free to override this value.
|
# The platform Makefile is free to override this value.
|
||||||
COLD_BOOT_SINGLE_CPU := 0
|
COLD_BOOT_SINGLE_CPU := 0
|
||||||
|
|
Loading…
Add table
Reference in a new issue