feat(intel): direct boot from TF-A to Linux for Agilex

Enable and update code for TF-A direct boot Linux
for Agilex platform.

Change-Id: Id95986b7015a2a01f0aff80e1c7d8f8bb8fb4637
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 6e45158..0f069cb 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,12 +14,16 @@
 #include <drivers/ti/uart/uart_16550.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat/common/platform.h>
 
 #include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_sip_svc.h"
 
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
@@ -59,9 +64,7 @@
 				u_register_t arg2, u_register_t arg3)
 {
 	static console_t console;
-
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
-
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
 		PLAT_BAUDRATE, &console);
 	/*
@@ -69,6 +72,33 @@
 	 */
 	void *from_bl2 = (void *) arg0;
 
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	void *plat_params_from_bl2 = (void *) arg3;
+
+	assert(plat_params_from_bl2 == NULL);
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+
+# 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.
+	 */
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
 	assert(params_from_bl2 != NULL);
 
@@ -76,28 +106,36 @@
 	 * Copy BL32 (if populated by BL31) and BL33 entry point information.
 	 * They are stored in Secure RAM, in BL31's address space.
 	 */
-
 	if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
 		params_from_bl2->h.version >= VERSION_2) {
-
 		bl_params_node_t *bl_params = params_from_bl2->head;
-
 		while (bl_params) {
 			if (bl_params->image_id == BL33_IMAGE_ID)
 				bl33_image_ep_info = *bl_params->ep_info;
-
 			bl_params = bl_params->next_params_info;
 		}
 	} else {
 		struct socfpga_bl31_params *arg_from_bl2 =
 			(struct socfpga_bl31_params *) from_bl2;
-
 		assert(arg_from_bl2->h.type == PARAM_BL31);
 		assert(arg_from_bl2->h.version >= VERSION_1);
-
 		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
 		bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
 	}
+
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 }
 
@@ -172,8 +210,34 @@
 #endif
 		{0}
 	};
-
 	setup_page_tables(bl_regions, plat_agilex_mmap);
 	enable_mmu_el3(0);
 }
 
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 1946898..0788ab8 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +32,6 @@
 /* Define next boot image name and offset */
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
 #if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-
 #ifndef PRELOADED_BL33_BASE
 #define PLAT_NS_IMAGE_OFFSET			0x80200000
 #else
@@ -40,7 +40,12 @@
 #define PLAT_HANDOFF_OFFSET 0x0003F000
 
 #else
+/* Legacy Products. Please refactor with Agilex5 */
+#ifndef PRELOADED_BL33_BASE
 #define PLAT_NS_IMAGE_OFFSET			0x10000000
+#else
+#define PLAT_NS_IMAGE_OFFSET			PRELOADED_BL33_BASE
+#endif
 #define PLAT_HANDOFF_OFFSET			0xFFE3F000
 #endif
 
@@ -48,6 +53,7 @@
 #define PLAT_NAND_DATA_BASE			(0x0200000)
 #define PLAT_SDMMC_DATA_BASE			(0x0)
 
+
 /*******************************************************************************
  * Platform binary types for linking
  ******************************************************************************/
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index d250d9e..23c93ea 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,9 +29,9 @@
 
 
 #define PLAT_FIP_BASE		(0)
-#define PLAT_FIP_MAX_SIZE	(0x1000000)
-#define PLAT_MMC_DATA_BASE	(0xffe3c000)
-#define PLAT_MMC_DATA_SIZE	(0x2000)
+#define PLAT_FIP_MAX_SIZE	(0x8000000)
+#define PLAT_MMC_DATA_BASE	(0x10000000)
+#define PLAT_MMC_DATA_SIZE	(0x100000)
 
 static const io_dev_connector_t *fip_dev_con;
 static const io_dev_connector_t *boot_dev_con;