plat/arm: Support direct Linux kernel boot in AArch32

This option allows the Trusted Firmware to directly jump to Linux
kernel for aarch32 without the need of an intermediate loader such
as U-Boot.

Similar to AArch64 ARM_LINUX_KERNEL_AS_BL33 only available with
RESET_TO_SP_MIN=1 as well as BL33 and DTB are preloaded in memory.

Change-Id: I908bc1633696be1caad0ce2f099c34215c8e0633
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index 59e88eb..a12a83b 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -101,6 +101,8 @@
 				smc_ctx_t *next_smc_ctx)
 {
 	next_smc_ctx->r0 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R0);
+	next_smc_ctx->r1 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R1);
+	next_smc_ctx->r2 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R2);
 	next_smc_ctx->lr_mon = read_ctx_reg(cpu_reg_ctx, CTX_LR);
 	next_smc_ctx->spsr_mon = read_ctx_reg(cpu_reg_ctx, CTX_SPSR);
 	next_smc_ctx->scr = read_ctx_reg(cpu_reg_ctx, CTX_SCR);
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 52cb45c..a8bd40c 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -728,11 +728,12 @@
 -  ``ARM_LINUX_KERNEL_AS_BL33``: The Linux kernel expects registers x0-x3 to
    have specific values at boot. This boolean option allows the Trusted Firmware
    to have a Linux kernel image as BL33 by preparing the registers to these
-   values before jumping to BL33. This option defaults to 0 (disabled). For now,
-   it  only supports AArch64 kernels. ``RESET_TO_BL31`` must be 1 when using it.
-   If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set to the
-   location of a device tree blob (DTB) already loaded in memory.  The Linux
-   Image address must be specified using the ``PRELOADED_BL33_BASE`` option.
+   values before jumping to BL33. This option defaults to 0 (disabled). For
+   AArch64 ``RESET_TO_BL31`` and for AArch32 ``RESET_TO_SP_MIN`` must be 1 when
+   using it. If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set
+   to the location of a device tree blob (DTB) already loaded in memory. The
+   Linux Image address must be specified using the ``PRELOADED_BL33_BASE``
+   option.
 
 -  ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
    for the construction of composite state-ID in the power-state parameter.
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 23777fb..cb969b2 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -86,11 +86,14 @@
 $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 
 ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
-  ifneq (${ARCH},aarch64)
-    $(error "ARM_LINUX_KERNEL_AS_BL33 is only available in AArch64.")
-  endif
-  ifneq (${RESET_TO_BL31},1)
-    $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_BL31=1.")
+  ifeq (${ARCH},aarch64)
+    ifneq (${RESET_TO_BL31},1)
+      $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_BL31=1.")
+    endif
+  else
+    ifneq (${RESET_TO_SP_MIN},1)
+      $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_SP_MIN=1.")
+    endif
   endif
   ifndef PRELOADED_BL33_BASE
     $(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index e151073..ca427d5 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -82,6 +82,19 @@
 	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
+# if ARM_LINUX_KERNEL_AS_BL33
+	/*
+	 * According to the file ``Documentation/arm/Booting`` of the Linux
+	 * kernel tree, Linux expects:
+	 * r0 = 0
+	 * r1 = machine type number, optional in DT-only platforms (~0 if so)
+	 * r2 = Physical address of the device tree blob
+	 */
+	bl33_image_ep_info.args.arg0 = 0U;
+	bl33_image_ep_info.args.arg1 = ~0U;
+	bl33_image_ep_info.args.arg2 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+# endif
+
 #else /* RESET_TO_SP_MIN */
 
 	/*