Merge pull request #1668 from ldts/rcar_gen3/e3_build

rcar_gen3: E3 target: fix compilation issues
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/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 1a726a8..31dafb2 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -10,6 +10,7 @@
 #include <debug.h>
 #include <fdt_wrappers.h>
 #include <libfdt.h>
+#include <string.h>
 
 /*
  * Read cells from a given property of the given node. At most 2 cells of the
@@ -39,7 +40,6 @@
 		return -1;
 	}
 
-
 	/* Verify that property length accords with cell length */
 	if (NCELLS((unsigned int)value_len) != cells) {
 		WARN("Property length mismatch\n");
@@ -62,6 +62,77 @@
 }
 
 /*
+ * Read cells from a given property of the given node. Any number of 32-bit
+ * cells of the property can be read. The fdt pointer is updated. Returns 0 on
+ * success, and -1 on error.
+ */
+int fdtw_read_array(const void *dtb, int node, const char *prop,
+		unsigned int cells, void *value)
+{
+	const uint32_t *value_ptr;
+	int value_len;
+
+	assert(dtb != NULL);
+	assert(prop != NULL);
+	assert(value != NULL);
+	assert(node >= 0);
+
+	/* Access property and obtain its length (in bytes) */
+	value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop),
+			&value_len);
+	if (value_ptr == NULL) {
+		WARN("Couldn't find property %s in dtb\n", prop);
+		return -1;
+	}
+
+	/* Verify that property length accords with cell length */
+	if (NCELLS((unsigned int)value_len) != cells) {
+		WARN("Property length mismatch\n");
+		return -1;
+	}
+
+	uint32_t *dst = value;
+
+	for (unsigned int i = 0U; i < cells; i++) {
+		dst[i] = fdt32_to_cpu(value_ptr[i]);
+	}
+
+	return 0;
+}
+
+/*
+ * Read string from a given property of the given node. Up to 'size - 1'
+ * characters are read, and a NUL terminator is added. Returns 0 on success,
+ * and -1 upon error.
+ */
+int fdtw_read_string(const void *dtb, int node, const char *prop,
+		char *str, size_t size)
+{
+	const char *ptr;
+	size_t len;
+
+	assert(dtb != NULL);
+	assert(node >= 0);
+	assert(prop != NULL);
+	assert(str != NULL);
+	assert(size > 0U);
+
+	ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), NULL);
+	if (ptr == NULL) {
+		WARN("Couldn't find property %s in dtb\n", prop);
+		return -1;
+	}
+
+	len = strlcpy(str, ptr, size);
+	if (len >= size) {
+		WARN("String of property %s in dtb has been truncated\n", prop);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
  * Write cells in place to a given property of the given node. At most 2 cells
  * of the property are written. Returns 0 on success, and -1 upon error.
  */
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/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 763eba7..d27b010 100644
--- a/drivers/arm/tzc/tzc400.c
+++ b/drivers/arm/tzc/tzc400.c
@@ -182,8 +182,8 @@
 	 * Do address range check based on TZC configuration. A 64bit address is
 	 * the max and expected case.
 	 */
-	assert(((region_top <= _tzc_get_max_top_addr(tzc400.addr_width)) &&
-		(region_base < region_top)));
+	assert((region_top <= (UINT64_MAX >> (64U - tzc400.addr_width))) &&
+		(region_base < region_top));
 
 	/* region_base and (region_top + 1) must be 4KB aligned */
 	assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U);
diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h
index 5fbea92..efac850 100644
--- a/drivers/arm/tzc/tzc_common_private.h
+++ b/drivers/arm/tzc/tzc_common_private.h
@@ -180,39 +180,4 @@
 	return id;
 }
 
-#if ENABLE_ASSERTIONS
-#ifdef AARCH32
-static inline unsigned long long _tzc_get_max_top_addr(unsigned int addr_width)
-{
-	/*
-	 * Assume at least 32 bit wide address and initialize the max.
-	 * This function doesn't use 64-bit integer arithmetic to avoid
-	 * having to implement additional compiler library functions.
-	 */
-	unsigned long long addr_mask = 0xFFFFFFFFU;
-	uint32_t *addr_ptr = (uint32_t *)&addr_mask;
-
-	assert(addr_width >= 32U);
-
-	/* This logic works only on little - endian platforms */
-	assert((read_sctlr() & SCTLR_EE_BIT) == 0U);
-
-	/*
-	 * If required address width is greater than 32, populate the higher
-	 * 32 bits of the 64 bit field with the max address.
-	 */
-	if (addr_width > 32U)
-		*(addr_ptr + 1U) = ((1U << (addr_width - 32U)) - 1U);
-
-	return addr_mask;
-}
-#else
-static inline unsigned long long _tzc_get_max_top_addr(unsigned int addr_width)
-{
-	return UINT64_MAX >> (64U - addr_width);
-}
-#endif /* AARCH32 */
-
-#endif /* ENABLE_ASSERTIONS */
-
 #endif /* TZC_COMMON_PRIVATE_H */
diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c
index 3e6c783..f0aba9c 100644
--- a/drivers/arm/tzc/tzc_dmc500.c
+++ b/drivers/arm/tzc/tzc_dmc500.c
@@ -188,7 +188,7 @@
 	 * Do address range check based on DMC-TZ configuration. A 43bit address
 	 * is the max and expected case.
 	 */
-	assert(((region_top <= _tzc_get_max_top_addr(43)) &&
+	assert(((region_top <= (UINT64_MAX >> (64U - 43U))) &&
 		(region_base < region_top)));
 
 	/* region_base and (region_top + 1) must be 4KB aligned */
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 3eae944..c8d753f 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -14,6 +14,11 @@
 
 int fdtw_read_cells(const void *dtb, int node, const char *prop,
 		unsigned int cells, void *value);
+int fdtw_read_array(const void *dtb, int node, const char *prop,
+		unsigned int cells, void *value);
+int fdtw_read_string(const void *dtb, int node, const char *prop,
+		char *str, size_t size);
 int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,
 		unsigned int cells, void *value);
+
 #endif /* __FDT_WRAPPERS__ */
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 3c8e3b6..ee6eeac 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -28,5 +28,6 @@
 size_t strlen(const char *s);
 size_t strnlen(const char *s, size_t maxlen);
 char *strrchr(const char *p, int ch);
+size_t strlcpy(char * dst, const char * src, size_t dsize);
 
 #endif /* STRING_H */
diff --git a/lib/compiler-rt/builtins/int_lib.h b/lib/compiler-rt/builtins/int_lib.h
index 787777a..80a7c41 100644
--- a/lib/compiler-rt/builtins/int_lib.h
+++ b/lib/compiler-rt/builtins/int_lib.h
@@ -27,27 +27,28 @@
 
 #if defined(__ELF__)
 #define FNALIAS(alias_name, original_name) \
-  void alias_name() __attribute__((alias(#original_name)))
+  void alias_name() __attribute__((__alias__(#original_name)))
+#define COMPILER_RT_ALIAS(aliasee) __attribute__((__alias__(#aliasee)))
 #else
 #define FNALIAS(alias, name) _Pragma("GCC error(\"alias unsupported on this file format\")")
+#define COMPILER_RT_ALIAS(aliasee) _Pragma("GCC error(\"alias unsupported on this file format\")")
 #endif
 
 /* ABI macro definitions */
 
 #if __ARM_EABI__
-# define ARM_EABI_FNALIAS(aeabi_name, name)         \
-  void __aeabi_##aeabi_name() __attribute__((alias("__" #name)));
 # ifdef COMPILER_RT_ARMHF_TARGET
 #   define COMPILER_RT_ABI
 # else
-#   define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
+#   define COMPILER_RT_ABI __attribute__((__pcs__("aapcs")))
 # endif
 #else
-# define ARM_EABI_FNALIAS(aeabi_name, name)
 # define COMPILER_RT_ABI
 #endif
 
-#ifdef _MSC_VER
+#define AEABI_RTABI __attribute__((__pcs__("aapcs")))
+
+#if defined(_MSC_VER) && !defined(__clang__)
 #define ALWAYS_INLINE __forceinline
 #define NOINLINE __declspec(noinline)
 #define NORETURN __declspec(noreturn)
diff --git a/lib/compiler-rt/builtins/lshrdi3.c b/lib/compiler-rt/builtins/lshrdi3.c
new file mode 100644
index 0000000..67b2a76
--- /dev/null
+++ b/lib/compiler-rt/builtins/lshrdi3.c
@@ -0,0 +1,45 @@
+/* ===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __lshrdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: logical a >> b */
+
+/* Precondition:  0 <= b < bits_in_dword */
+
+COMPILER_RT_ABI di_int
+__lshrdi3(di_int a, si_int b)
+{
+    const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+    udwords input;
+    udwords result;
+    input.all = a;
+    if (b & bits_in_word)  /* bits_in_word <= b < bits_in_dword */
+    {
+        result.s.high = 0;
+        result.s.low = input.s.high >> (b - bits_in_word);
+    }
+    else  /* 0 <= b < bits_in_word */
+    {
+        if (b == 0)
+            return a;
+        result.s.high  = input.s.high >> b;
+        result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);
+    }
+    return result.all;
+}
+
+#if defined(__ARM_EABI__)
+AEABI_RTABI di_int __aeabi_llsr(di_int a, si_int b) COMPILER_RT_ALIAS(__lshrdi3);
+#endif
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index cb5ab31..49e497e 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -31,5 +31,6 @@
 ifeq (${ARCH},aarch32)
 COMPILER_RT_SRCS	:=	lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
 				lib/compiler-rt/builtins/udivmoddi4.c		\
-				lib/compiler-rt/builtins/ctzdi2.c
+				lib/compiler-rt/builtins/ctzdi2.c		\
+				lib/compiler-rt/builtins/lshrdi3.c
 endif
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index daa2ec1..1276f5c 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -19,6 +19,7 @@
 			snprintf.c			\
 			strchr.c			\
 			strcmp.c			\
+			strlcpy.c			\
 			strlen.c			\
 			strncmp.c			\
 			strnlen.c			\
diff --git a/lib/libc/strlcpy.c b/lib/libc/strlcpy.c
new file mode 100644
index 0000000..c4f39bb
--- /dev/null
+++ b/lib/libc/strlcpy.c
@@ -0,0 +1,52 @@
+/*	$OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $	*/
+
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+/*
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char * dst, const char * src, size_t dsize)
+{
+	const char *osrc = src;
+	size_t nleft = dsize;
+
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == '\0')
+				break;
+		}
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = '\0';		/* NUL-terminate dst */
+		while (*src++)
+			;
+	}
+
+	return(src - osrc - 1);	/* count does not include NUL */
+}
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index f5198f6..0edf6ba 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -176,7 +176,7 @@
 	u_register_t mpidr;
 
 	mpidr = read_mpidr_el1();
-	master = (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) ?
+	master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
 		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
 
 	assert(master < FVP_CLUSTER_COUNT);
@@ -327,7 +327,7 @@
 	 * affinities, is uniform across the platform: either all CPUs, or no
 	 * CPUs implement it.
 	 */
-	if (read_mpidr_el1() & MPIDR_MT_MASK)
+	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U)
 		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
 }
 
@@ -336,35 +336,31 @@
 {
 #if FVP_INTERCONNECT_DRIVER == FVP_CCN
 	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
-		ERROR("Unrecognized CCN variant detected. Only CCN-502"
-				" is supported");
+		ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
 		panic();
 	}
 
 	plat_arm_interconnect_init();
 #else
-	uintptr_t cci_base = 0;
-	const int *cci_map = 0;
-	unsigned int map_size = 0;
-
-	if (!(arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
-				ARM_CONFIG_FVP_HAS_CCI5XX))) {
-		return;
-	}
+	uintptr_t cci_base = 0U;
+	const int *cci_map = NULL;
+	unsigned int map_size = 0U;
 
 	/* Initialize the right interconnect */
-	if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) {
+	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
 		cci_base = PLAT_FVP_CCI5XX_BASE;
 		cci_map = fvp_cci5xx_map;
 		map_size = ARRAY_SIZE(fvp_cci5xx_map);
-	} else if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) {
+	} else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
 		cci_base = PLAT_FVP_CCI400_BASE;
 		cci_map = fvp_cci400_map;
 		map_size = ARRAY_SIZE(fvp_cci400_map);
+	} else {
+		return;
 	}
 
-	assert(cci_base);
-	assert(cci_map);
+	assert(cci_base != 0U);
+	assert(cci_map != NULL);
 	cci_init(cci_base, cci_map, map_size);
 #endif
 }
@@ -376,8 +372,8 @@
 #else
 	unsigned int master;
 
-	if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
-				ARM_CONFIG_FVP_HAS_CCI5XX)) {
+	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
 		master = get_interconnect_master();
 		cci_enable_snoop_dvm_reqs(master);
 	}
@@ -391,8 +387,8 @@
 #else
 	unsigned int master;
 
-	if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
-				ARM_CONFIG_FVP_HAS_CCI5XX)) {
+	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
 		master = get_interconnect_master();
 		cci_disable_snoop_dvm_reqs(master);
 	}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 44ab1b3..4fd4aef 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -208,7 +208,7 @@
 #define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP	1, 5, 7, 11
 
 /* System timer related constants */
-#define PLAT_ARM_NSTIMER_FRAME_ID		1
+#define PLAT_ARM_NSTIMER_FRAME_ID		U(1)
 
 /* Mailbox base address */
 #define PLAT_ARM_TRUSTED_MAILBOX_BASE	ARM_TRUSTED_SRAM_BASE
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 89e28ef..735e4a3 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -202,7 +202,7 @@
 #define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX	3
 
 /* System timer related constants */
-#define PLAT_ARM_NSTIMER_FRAME_ID		1
+#define PLAT_ARM_NSTIMER_FRAME_ID		U(1)
 
 /* TZC related constants */
 #define PLAT_ARM_TZC_BASE		UL(0x2a4a0000)
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 49f0074..b72dd20 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -108,13 +108,13 @@
 	unsigned int freq_val = plat_get_syscnt_freq2();
 
 #if ARM_CONFIG_CNTACR
-	reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
-	reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
-	reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
+	reg_val = (1U << CNTACR_RPCT_SHIFT) | (1U << CNTACR_RVCT_SHIFT);
+	reg_val |= (1U << CNTACR_RFRQ_SHIFT) | (1U << CNTACR_RVOFF_SHIFT);
+	reg_val |= (1U << CNTACR_RWVT_SHIFT) | (1U << CNTACR_RWPT_SHIFT);
 	mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTACR_BASE(PLAT_ARM_NSTIMER_FRAME_ID), reg_val);
 #endif /* ARM_CONFIG_CNTACR */
 
-	reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID));
+	reg_val = (1U << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID));
 	mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTNSAR, reg_val);
 
 	/*
@@ -154,7 +154,7 @@
 	counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
 
 	/* The first entry of the frequency modes table must not be 0 */
-	if (counter_base_frequency == 0)
+	if (counter_base_frequency == 0U)
 		panic();
 
 	return counter_base_frequency;
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/arm_err.c b/plat/arm/common/arm_err.c
index 519d44d..aa65f4f 100644
--- a/plat/arm/common/arm_err.c
+++ b/plat/arm/common/arm_err.c
@@ -8,6 +8,7 @@
 #include <console.h>
 #include <debug.h>
 #include <errno.h>
+#include <plat_arm.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <stdint.h>
@@ -27,7 +28,7 @@
 	case -EAUTH:
 		/* Image load or authentication error. Erase the ToC */
 		INFO("Erasing FIP ToC from flash...\n");
-		nor_unlock(PLAT_ARM_FIP_BASE);
+		(void)nor_unlock(PLAT_ARM_FIP_BASE);
 		ret = nor_word_program(PLAT_ARM_FIP_BASE, 0);
 		if (ret != 0) {
 			ERROR("Cannot erase ToC\n");
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 */
 
 	/*
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index 1d7da00..62cd1f2 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -9,6 +9,7 @@
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
+#include <delay_timer.h>
 #include <desc_image_load.h>
 #include <dw_mmc.h>
 #include <errno.h>
@@ -333,6 +334,7 @@
 	params.flags = MMC_FLAG_CMD23;
 	info.mmc_dev_type = MMC_IS_EMMC;
 	dw_mmc_init(&params, &info);
+	mdelay(5);
 
 	hikey_io_setup();
 }