rpi4: Determine BL33 entry point at runtime

Now that we have the armstub magic value in place, the GPU firmware will
write the kernel load address (and DTB address) into our special page,
so we can always easily access the actual location without hardcoding
any addresses into the BL31 image.

Make the compile-time defined PRELOADED_BL33_BASE macro optional, and
read the BL33 entry point from the magic location, if the macro was not
defined. We do the same for the DTB address.

This also splits the currently "common" definition of
plat_get_ns_image_entrypoint() to be separate between RPi3 and RPi4.

Change-Id: I6f26c0adc6fce2df47786b271c490928b4529abb
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Andre Przywara 2019-07-11 01:42:12 +01:00
parent c4597e13a2
commit 448fb352f9
4 changed files with 48 additions and 28 deletions

View File

@ -175,18 +175,6 @@ void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
init_xlat_tables();
}
/*******************************************************************************
* Return entrypoint of BL33.
******************************************************************************/
uintptr_t plat_get_ns_image_entrypoint(void)
{
#ifdef PRELOADED_BL33_BASE
return PRELOADED_BL33_BASE;
#else
return PLAT_RPI3_NS_IMAGE_OFFSET;
#endif
}
/*******************************************************************************
* Gets SPSR for BL32 entry
******************************************************************************/

View File

@ -47,6 +47,18 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
}
}
/*******************************************************************************
* Return entrypoint of BL33.
******************************************************************************/
uintptr_t plat_get_ns_image_entrypoint(void)
{
#ifdef PRELOADED_BL33_BASE
return PRELOADED_BL33_BASE;
#else
return PLAT_RPI3_NS_IMAGE_OFFSET;
#endif
}
/*******************************************************************************
* Perform any BL31 early platform setup. Here is an opportunity to copy
* parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before

View File

@ -68,8 +68,8 @@ USE_COHERENT_MEM := 1
# Platform build flags
# --------------------
# Assume that BL33 isn't the Linux kernel by default
RPI3_DIRECT_LINUX_BOOT := 0
# There is not much else than a Linux kernel to load at the moment.
RPI3_DIRECT_LINUX_BOOT := 1
# BL33 images are in AArch64 by default
RPI3_BL33_IN_AARCH32 := 0
@ -92,15 +92,6 @@ endif
$(eval $(call add_define,RPI3_RUNTIME_UART))
$(eval $(call add_define,RPI3_USE_UEFI_MAP))
# Verify build config
# -------------------
#
ifneq (${RPI3_DIRECT_LINUX_BOOT}, 0)
ifndef RPI3_PRELOADED_DTB_BASE
$(error Error: RPI3_PRELOADED_DTB_BASE needed if RPI3_DIRECT_LINUX_BOOT=1)
endif
endif
ifeq (${ARCH},aarch32)
$(error Error: AArch32 not supported on rpi4)
endif

View File

@ -27,6 +27,8 @@
* confirmation and puts the kernel and DT address in the following words.
*/
extern uint32_t stub_magic;
extern uint32_t dtb_ptr32;
extern uint32_t kernel_entry32;
static const gicv2_driver_data_t rpi4_gic_data = {
.gicd_base = RPI4_GIC_GICD_BASE,
@ -63,6 +65,34 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
}
}
uintptr_t plat_get_ns_image_entrypoint(void)
{
#ifdef PRELOADED_BL33_BASE
return PRELOADED_BL33_BASE;
#else
/* Cleared by the GPU if kernel address is valid. */
if (stub_magic == 0)
return kernel_entry32;
WARN("Stub magic failure, using default kernel address 0x80000\n");
return 0x80000;
#endif
}
static uintptr_t rpi4_get_dtb_address(void)
{
#ifdef RPI3_PRELOADED_DTB_BASE
return RPI3_PRELOADED_DTB_BASE;
#else
/* Cleared by the GPU if DTB address is valid. */
if (stub_magic == 0)
return dtb_ptr32;
WARN("Stub magic failure, DTB address unknown\n");
return 0;
#endif
}
static void ldelay(register_t delay)
{
__asm__ volatile (
@ -114,12 +144,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
div_reg = 1;
rpi3_console_init(PLAT_RPI4_VPU_CLK_RATE / div_reg);
#if RPI3_DIRECT_LINUX_BOOT
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
#if RPI3_DIRECT_LINUX_BOOT
# if RPI3_BL33_IN_AARCH32
/*
* According to the file ``Documentation/arm/Booting`` of the Linux
@ -131,7 +160,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
VERBOSE("rpi4: Preparing to boot 32-bit Linux kernel\n");
bl33_image_ep_info.args.arg0 = 0U;
bl33_image_ep_info.args.arg1 = ~0U;
bl33_image_ep_info.args.arg2 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address();
# else
/*
* According to the file ``Documentation/arm64/booting.txt`` of the
@ -140,7 +169,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
* must be 0.
*/
VERBOSE("rpi4: Preparing to boot 64-bit Linux kernel\n");
bl33_image_ep_info.args.arg0 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address();
bl33_image_ep_info.args.arg1 = 0ULL;
bl33_image_ep_info.args.arg2 = 0ULL;
bl33_image_ep_info.args.arg3 = 0ULL;