qemu: Support ARM_LINUX_KERNEL_AS_BL33 to pass FDT address.

This lets the Linux kernel or any other image which expects an FDT in x0 be
loaded directly as BL33 without a separate bootloader on QEMU.

Signed-off-by: Andrew Walbran <qwandor@google.com>
Change-Id: Ia8eb4710a3d97cdd877af3b8aae36a2de7cfc654
This commit is contained in:
Andrew Walbran 2020-01-15 14:11:31 +00:00
parent d81e38f66e
commit 74464d5b51
4 changed files with 38 additions and 3 deletions

View file

@ -10,6 +10,10 @@ loop to be released by normal world via PSCI.
BL2 edits the Flattened Device Tree, FDT, generated by QEMU at run-time to BL2 edits the Flattened Device Tree, FDT, generated by QEMU at run-time to
add a node describing PSCI and also enable methods for the CPUs. add a node describing PSCI and also enable methods for the CPUs.
If ``ARM_LINUX_KERNEL_AS_BL33`` is set to 1 then this FDT will be passed to BL33
via register x0, as expected by a Linux kernel. This allows a Linux kernel image
to be booted directly as BL33 rather than using a bootloader.
An ARM64 defconfig v4.5 Linux kernel is known to boot, FDT doesn't need to be An ARM64 defconfig v4.5 Linux kernel is known to boot, FDT doesn't need to be
provided as it's generated by QEMU. provided as it's generated by QEMU.

View file

@ -51,7 +51,7 @@ static void security_setup(void)
static void update_dt(void) static void update_dt(void)
{ {
int ret; int ret;
void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE; void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE); ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
if (ret < 0) { if (ret < 0) {
@ -172,12 +172,12 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
* OP-TEE expect to receive DTB address in x2. * OP-TEE expect to receive DTB address in x2.
* This will be copied into x2 by dispatcher. * This will be copied into x2 by dispatcher.
*/ */
bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE; bl_mem_params->ep_info.args.arg3 = ARM_PRELOADED_DTB_BASE;
#else /* case AARCH32_SP_OPTEE */ #else /* case AARCH32_SP_OPTEE */
bl_mem_params->ep_info.args.arg0 = bl_mem_params->ep_info.args.arg0 =
bl_mem_params->ep_info.args.arg1; bl_mem_params->ep_info.args.arg1;
bl_mem_params->ep_info.args.arg1 = 0; bl_mem_params->ep_info.args.arg1 = 0;
bl_mem_params->ep_info.args.arg2 = PLAT_QEMU_DT_BASE; bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
bl_mem_params->ep_info.args.arg3 = 0; bl_mem_params->ep_info.args.arg3 = 0;
#endif #endif
#endif #endif
@ -192,8 +192,23 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
#endif #endif
#if ARM_LINUX_KERNEL_AS_BL33
/*
* According to the file ``Documentation/arm64/booting.txt`` of
* the Linux kernel tree, Linux expects the physical address of
* the device tree blob (DTB) in x0, while x1-x3 are reserved
* for future use and must be 0.
*/
bl_mem_params->ep_info.args.arg0 =
(u_register_t)ARM_PRELOADED_DTB_BASE;
bl_mem_params->ep_info.args.arg1 = 0U;
bl_mem_params->ep_info.args.arg2 = 0U;
bl_mem_params->ep_info.args.arg3 = 0U;
#else
/* BL33 expects to receive the primary CPU MPID (through r0) */ /* BL33 expects to receive the primary CPU MPID (through r0) */
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
#endif
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry(); bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
break; break;
default: default:

View file

@ -186,5 +186,13 @@ endif
# Process flags # Process flags
$(eval $(call add_define,BL32_RAM_LOCATION_ID)) $(eval $(call add_define,BL32_RAM_LOCATION_ID))
# Don't have the Linux kernel as a BL33 image by default
ARM_LINUX_KERNEL_AS_BL33 := 0
$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
# Do not enable SVE # Do not enable SVE
ENABLE_SVE_FOR_NS := 0 ENABLE_SVE_FOR_NS := 0

View file

@ -97,5 +97,13 @@ PRELOADED_BL33_BASE ?= 0x10000000
BL32_RAM_LOCATION_ID = SEC_SRAM_ID BL32_RAM_LOCATION_ID = SEC_SRAM_ID
$(eval $(call add_define,BL32_RAM_LOCATION_ID)) $(eval $(call add_define,BL32_RAM_LOCATION_ID))
# Don't have the Linux kernel as a BL33 image by default
ARM_LINUX_KERNEL_AS_BL33 := 0
$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
# Do not enable SVE # Do not enable SVE
ENABLE_SVE_FOR_NS := 0 ENABLE_SVE_FOR_NS := 0