summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiafei Pan <Jiafei.Pan@nxp.com>2018-03-21 07:20:09 +0000
committerJiafei Pan <Jiafei.Pan@nxp.com>2018-04-07 10:12:21 +0800
commit7d173fc594d7d50c02e180c56c59ca1d3e51152e (patch)
tree8c04f896f7a0569bd7ba7a4baa0368c6be18f9b9
parent93883a293145f6c85b3fc8c219f400e28b7d1491 (diff)
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>
-rw-r--r--Makefile7
-rw-r--r--bl2/bl2_el3.ld.S57
-rw-r--r--bl2/bl2_private.h14
-rw-r--r--docs/porting-guide.rst28
-rw-r--r--docs/user-guide.rst6
-rw-r--r--include/common/aarch64/el3_common_macros.S4
-rw-r--r--include/plat/common/common_def.h10
-rw-r--r--make_helpers/defaults.mk4
8 files changed, 125 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index ef4e5c68..a8378462 100644
--- a/Makefile
+++ b/Makefile
@@ -373,6 +373,11 @@ ifneq ($(MULTI_CONSOLE_API), 0)
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
################################################################################
@@ -518,6 +523,7 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
$(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_MINOR))
@@ -564,6 +570,7 @@ $(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
$(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.
ifdef EL3_PAYLOAD_BASE
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 3728643c..0f91edc9 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -12,15 +12,26 @@ OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
ENTRY(bl2_entrypoint)
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
+#endif
}
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;
ASSERT(. == ALIGN(PAGE_SIZE),
"BL2_BASE address is not aligned on a page boundary.")
+#endif
#if SEPARATE_CODE_AND_RODATA
.text . : {
@@ -33,7 +44,11 @@ SECTIONS
*(.vectors)
. = NEXT(PAGE_SIZE);
__TEXT_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
+#endif
.rodata . : {
__RODATA_START__ = .;
@@ -56,7 +71,11 @@ SECTIONS
. = NEXT(PAGE_SIZE);
__RODATA_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
+#endif
ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
"Resident part of BL2 has exceeded its limit.")
@@ -95,12 +114,22 @@ SECTIONS
. = NEXT(PAGE_SIZE);
__RO_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
#endif
+#endif
ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
"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
* image.
@@ -113,10 +142,14 @@ SECTIONS
* section can be placed independently of the main .data section.
*/
.data . : {
- __DATA_START__ = .;
+ __DATA_RAM_START__ = .;
*(.data*)
- __DATA_END__ = .;
+ __DATA_RAM_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >RAM AT>ROM
+#else
} >RAM
+#endif
stacks (NOLOAD) : {
__STACKS_START__ = .;
@@ -174,12 +207,32 @@ SECTIONS
__RW_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);
+
#if USE_COHERENT_MEM
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
#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.")
+#endif
}
diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h
index 50295d67..f93a179d 100644
--- a/bl2/bl2_private.h
+++ b/bl2/bl2_private.h
@@ -7,6 +7,20 @@
#ifndef __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
*****************************************/
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index ff5bb122..12e135f7 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -217,11 +217,37 @@ platform port to define additional platform porting constants in
- **#define : BL2\_BASE**
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**
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**
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 57948554..fdf1568e 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -246,6 +246,12 @@ Common build options
- ``BL2_AT_EL3``: This is an optional build option that enables the use of
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 image for the ``fip`` target. In this case, the BL31 in TF-A will not
be built.
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 4ebf77bb..e85249c4 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -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
*/
@@ -294,7 +294,7 @@
bl zeromem
#endif
-#ifdef IMAGE_BL1
+#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM)
ldr x0, =__DATA_RAM_START__
ldr x1, =__DATA_ROM_START__
ldr x2, =__DATA_SIZE__
diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h
index 84923b9a..827d416f 100644
--- a/include/plat/common/common_def.h
+++ b/include/plat/common/common_def.h
@@ -78,9 +78,19 @@
#define BL1_CODE_END BL_CODE_END
#define BL1_RO_DATA_BASE BL_RO_DATA_BASE
#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
#define BL_RO_DATA_BASE 0
#define BL_RO_DATA_END 0
#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 /* __COMMON_DEF_H__ */
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 751f8343..77eb157c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -30,6 +30,10 @@ BASE_COMMIT := origin/master
# Execute BL2 at EL3
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.
# The platform Makefile is free to override this value.
COLD_BOOT_SINGLE_CPU := 0