Merge changes I0fb7cf79,Ia8eb4710 into integration
* changes: qemu: Implement qemu_system_off via semihosting. qemu: Support ARM_LINUX_KERNEL_AS_BL33 to pass FDT address.
This commit is contained in:
commit
8efec9e097
|
@ -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
|
||||
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
|
||||
provided as it's generated by QEMU.
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define SEMIHOSTING_SYS_REMOVE 0x0E
|
||||
#define SEMIHOSTING_SYS_SYSTEM 0x12
|
||||
#define SEMIHOSTING_SYS_ERRNO 0x13
|
||||
#define SEMIHOSTING_SYS_EXIT 0x18
|
||||
|
||||
#define FOPEN_MODE_R 0x0
|
||||
#define FOPEN_MODE_RB 0x1
|
||||
|
@ -54,5 +55,6 @@ long semihosting_download_file(const char *file_name,
|
|||
void semihosting_write_char(char character);
|
||||
void semihosting_write_string(char *string);
|
||||
char semihosting_read_char(void);
|
||||
void semihosting_exit(uint32_t reason, uint32_t subcode);
|
||||
|
||||
#endif /* SEMIHOSTING_H */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#endif
|
||||
|
||||
long semihosting_call(unsigned long operation,
|
||||
void *system_block_address);
|
||||
uintptr_t system_block_address);
|
||||
|
||||
typedef struct {
|
||||
const char *file_name;
|
||||
|
@ -53,7 +53,7 @@ long semihosting_file_open(const char *file_name, size_t mode)
|
|||
open_block.name_length = strlen(file_name);
|
||||
|
||||
return semihosting_call(SEMIHOSTING_SYS_OPEN,
|
||||
(void *) &open_block);
|
||||
(uintptr_t) &open_block);
|
||||
}
|
||||
|
||||
long semihosting_file_seek(long file_handle, ssize_t offset)
|
||||
|
@ -65,7 +65,7 @@ long semihosting_file_seek(long file_handle, ssize_t offset)
|
|||
seek_block.location = offset;
|
||||
|
||||
result = semihosting_call(SEMIHOSTING_SYS_SEEK,
|
||||
(void *) &seek_block);
|
||||
(uintptr_t) &seek_block);
|
||||
|
||||
if (result)
|
||||
result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0);
|
||||
|
@ -86,7 +86,7 @@ long semihosting_file_read(long file_handle, size_t *length, uintptr_t buffer)
|
|||
read_block.length = *length;
|
||||
|
||||
result = semihosting_call(SEMIHOSTING_SYS_READ,
|
||||
(void *) &read_block);
|
||||
(uintptr_t) &read_block);
|
||||
|
||||
if (result == *length) {
|
||||
return -EINVAL;
|
||||
|
@ -112,7 +112,7 @@ long semihosting_file_write(long file_handle,
|
|||
write_block.length = *length;
|
||||
|
||||
result = semihosting_call(SEMIHOSTING_SYS_WRITE,
|
||||
(void *) &write_block);
|
||||
(uintptr_t) &write_block);
|
||||
|
||||
*length = result;
|
||||
|
||||
|
@ -122,28 +122,28 @@ long semihosting_file_write(long file_handle,
|
|||
long semihosting_file_close(long file_handle)
|
||||
{
|
||||
return semihosting_call(SEMIHOSTING_SYS_CLOSE,
|
||||
(void *) &file_handle);
|
||||
(uintptr_t) &file_handle);
|
||||
}
|
||||
|
||||
long semihosting_file_length(long file_handle)
|
||||
{
|
||||
return semihosting_call(SEMIHOSTING_SYS_FLEN,
|
||||
(void *) &file_handle);
|
||||
(uintptr_t) &file_handle);
|
||||
}
|
||||
|
||||
char semihosting_read_char(void)
|
||||
{
|
||||
return semihosting_call(SEMIHOSTING_SYS_READC, NULL);
|
||||
return semihosting_call(SEMIHOSTING_SYS_READC, 0);
|
||||
}
|
||||
|
||||
void semihosting_write_char(char character)
|
||||
{
|
||||
semihosting_call(SEMIHOSTING_SYS_WRITEC, (void *) &character);
|
||||
semihosting_call(SEMIHOSTING_SYS_WRITEC, (uintptr_t) &character);
|
||||
}
|
||||
|
||||
void semihosting_write_string(char *string)
|
||||
{
|
||||
semihosting_call(SEMIHOSTING_SYS_WRITE0, (void *) string);
|
||||
semihosting_call(SEMIHOSTING_SYS_WRITE0, (uintptr_t) string);
|
||||
}
|
||||
|
||||
long semihosting_system(char *command_line)
|
||||
|
@ -154,7 +154,7 @@ long semihosting_system(char *command_line)
|
|||
system_block.command_length = strlen(command_line);
|
||||
|
||||
return semihosting_call(SEMIHOSTING_SYS_SYSTEM,
|
||||
(void *) &system_block);
|
||||
(uintptr_t) &system_block);
|
||||
}
|
||||
|
||||
long semihosting_get_flen(const char *file_name)
|
||||
|
@ -216,3 +216,15 @@ semihosting_fail:
|
|||
semihosting_file_close(file_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void semihosting_exit(uint32_t reason, uint32_t subcode)
|
||||
{
|
||||
#ifdef __aarch64__
|
||||
uint64_t parameters[] = {reason, subcode};
|
||||
|
||||
(void) semihosting_call(SEMIHOSTING_SYS_EXIT, (uintptr_t) ¶meters);
|
||||
#else
|
||||
/* The subcode is not supported on AArch32. */
|
||||
(void) semihosting_call(SEMIHOSTING_SYS_EXIT, reason);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ static void security_setup(void)
|
|||
static void update_dt(void)
|
||||
{
|
||||
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);
|
||||
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.
|
||||
* 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 */
|
||||
bl_mem_params->ep_info.args.arg0 =
|
||||
bl_mem_params->ep_info.args.arg1;
|
||||
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;
|
||||
#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;
|
||||
#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) */
|
||||
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
|
||||
#endif
|
||||
|
||||
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/psci/psci.h>
|
||||
#include <lib/semihosting.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "qemu_private.h"
|
||||
|
||||
#define ADP_STOPPED_APPLICATION_EXIT 0x20026
|
||||
|
||||
/*
|
||||
* The secure entry point to be used on warm reset.
|
||||
*/
|
||||
|
@ -191,7 +194,8 @@ void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
|
|||
******************************************************************************/
|
||||
static void __dead2 qemu_system_off(void)
|
||||
{
|
||||
ERROR("QEMU System Off: operation not handled.\n");
|
||||
semihosting_exit(ADP_STOPPED_APPLICATION_EXIT, 0);
|
||||
ERROR("QEMU System Off: semihosting call unexpectedly returned.\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,8 @@ ifeq (${ARM_ARCH_MAJOR},8)
|
|||
BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \
|
||||
lib/cpus/aarch64/cortex_a53.S \
|
||||
lib/cpus/aarch64/cortex_a57.S \
|
||||
lib/semihosting/semihosting.c \
|
||||
lib/semihosting/${ARCH}/semihosting_call.S \
|
||||
plat/common/plat_psci_common.c \
|
||||
${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \
|
||||
${PLAT_QEMU_COMMON_PATH}/topology.c \
|
||||
|
@ -186,5 +188,13 @@ endif
|
|||
# Process flags
|
||||
$(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
|
||||
ENABLE_SVE_FOR_NS := 0
|
||||
|
|
|
@ -71,6 +71,8 @@ QEMU_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
|
|||
BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \
|
||||
lib/cpus/aarch64/cortex_a53.S \
|
||||
lib/cpus/aarch64/cortex_a57.S \
|
||||
lib/semihosting/semihosting.c \
|
||||
lib/semihosting/${ARCH}/semihosting_call.S \
|
||||
plat/common/plat_psci_common.c \
|
||||
${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \
|
||||
${PLAT_QEMU_COMMON_PATH}/topology.c \
|
||||
|
@ -97,5 +99,13 @@ PRELOADED_BL33_BASE ?= 0x10000000
|
|||
BL32_RAM_LOCATION_ID = SEC_SRAM_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
|
||||
ENABLE_SVE_FOR_NS := 0
|
||||
|
|
Loading…
Reference in New Issue