Merge pull request #1680 from pbatard/rpi3-runtime-uart

rpi3: add RPI3_RUNTIME_UART build option
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 7777954..019a19e 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -8,6 +8,9 @@
 # Include SPM Makefile
 ################################################################################
 ifeq (${ENABLE_SPM},1)
+ifeq (${EL3_EXCEPTION_HANDLING},0)
+  $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
+endif
 $(info Including SPM makefile)
 include services/std_svc/spm/spm.mk
 endif
diff --git a/docs/secure-partition-manager-design.rst b/docs/secure-partition-manager-design.rst
index fec7c00..73406b2 100644
--- a/docs/secure-partition-manager-design.rst
+++ b/docs/secure-partition-manager-design.rst
@@ -125,8 +125,9 @@
 the rest of this document.
 
 To enable SPM support in TF-A, the source code must be compiled with the build
-flag ``ENABLE_SPM=1``. On Arm platforms the build option ``ARM_BL31_IN_DRAM``
-must be set to 1. Also, the location of the binary that contains the BL32 image
+flag ``ENABLE_SPM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm
+platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
+location of the binary that contains the BL32 image
 (``BL32=path/to/image.bin``) must be specified.
 
 First, build the Standalone MM Secure Partition. To build it, refer to the
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
index 9cc917d..0c51e62 100644
--- a/drivers/partition/gpt.c
+++ b/drivers/partition/gpt.c
@@ -13,10 +13,14 @@
 
 static int unicode_to_ascii(unsigned short *str_in, unsigned char *str_out)
 {
-	uint8_t *name = (uint8_t *)str_in;
+	uint8_t *name;
 	int i;
 
-	assert((str_in != NULL) && (str_out != NULL) && (name[0] != '\0'));
+	assert((str_in != NULL) && (str_out != NULL));
+
+	name = (uint8_t *)str_in;
+
+	assert(name[0] != '\0');
 
 	/* check whether the unicode string is valid */
 	for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
@@ -36,7 +40,7 @@
 {
 	int result;
 
-	assert((gpt_entry != 0) && (entry != 0));
+	assert((gpt_entry != NULL) && (entry != NULL));
 
 	if ((gpt_entry->first_lba == 0) && (gpt_entry->last_lba == 0)) {
 		return -EINVAL;
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index f0bf363..b8457cb 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1323,7 +1323,7 @@
 	int ret, len;
 	enum stm32mp1_pll_id i;
 	bool lse_css = false;
-	const uint32_t *pkcs_cell;
+	const fdt32_t *pkcs_cell;
 
 	/* Check status field to disable security */
 	if (!fdt_get_rcc_secure_status()) {
@@ -1529,7 +1529,7 @@
 		priv->pkcs_usb_value = 0;
 
 		for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
-			uint32_t pkcs = (uint32_t)fdt32_to_cpu(pkcs_cell[j]);
+			uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]);
 
 			if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
 				ckper_disabled = true;
diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c
index d4c69cb..078d803 100644
--- a/drivers/st/clk/stm32mp1_clkfunc.c
+++ b/drivers/st/clk/stm32mp1_clkfunc.c
@@ -265,11 +265,11 @@
  * This function gets the pointer to a rcc-clk property from its name.
  * It reads the values indicated inside the device tree.
  * Length of the property is stored in the second parameter.
- * Returns pointer if success, and NULL value else.
+ * Returns pointer on success, and NULL value on failure.
  ******************************************************************************/
-const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
+const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
 {
-	const uint32_t *cuint;
+	const fdt32_t *cuint;
 	int node, len;
 	void *fdt;
 
diff --git a/include/drivers/st/stm32mp1_clkfunc.h b/include/drivers/st/stm32mp1_clkfunc.h
index b11ccf8..2467af9 100644
--- a/include/drivers/st/stm32mp1_clkfunc.h
+++ b/include/drivers/st/stm32mp1_clkfunc.h
@@ -7,6 +7,7 @@
 #ifndef STM32MP1_CLKFUNC_H
 #define STM32MP1_CLKFUNC_H
 
+#include <libfdt.h>
 #include <stdbool.h>
 
 enum stm32mp_osc_id {
@@ -33,7 +34,7 @@
 int fdt_rcc_read_uint32_array(const char *prop_name,
 			      uint32_t *array, uint32_t count);
 int fdt_rcc_subnode_offset(const char *name);
-const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
+const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
 bool fdt_get_rcc_secure_status(void);
 
 uintptr_t fdt_get_stgen_base(void);
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
index 9598d9b..288e072 100644
--- a/include/drivers/st/stm32mp1_ddr_regs.h
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -408,6 +408,4 @@
 #define DDRPHYC_DXNDLLCR_SDPHASE_MASK		GENMASK(17, 14)
 #define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT		14
 
-void ddr_enable_clock(void);
-
 #endif /* STM32MP1_DDR_REGS_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index b27e481..b7febc3 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -302,10 +302,10 @@
 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
 	void (*pwr_domain_suspend_finish)(
 				const psci_power_state_t *target_state);
-	void (*pwr_domain_pwr_down_wfi)(
-				const psci_power_state_t *target_state) __dead2;
-	void (*system_off)(void) __dead2;
-	void (*system_reset)(void) __dead2;
+	void __dead2 (*pwr_domain_pwr_down_wfi)(
+				const psci_power_state_t *target_state);
+	void __dead2 (*system_off)(void);
+	void __dead2 (*system_reset)(void);
 	int (*validate_power_state)(unsigned int power_state,
 				    psci_power_state_t *req_state);
 	int (*validate_ns_entrypoint)(uintptr_t ns_entrypoint);
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 4fd4aef..58b68ab 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -268,4 +268,6 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(ARM_SP_IMAGE_NS_BUF_BASE +	\
 					 ARM_SP_IMAGE_NS_BUF_SIZE)
 
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
index 665871b..f313851 100644
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ b/plat/arm/common/aarch64/arm_ehf.c
@@ -23,6 +23,9 @@
 	/* Normal priority SDEI */
 	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
+#if ENABLE_SPM
+	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
+#endif
 };
 
 /* Plug in ARM exceptions to Exception Handling Framework. */
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 90eb336..1395373 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -142,6 +142,8 @@
 					SOC_CSS_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#define PLAT_SP_PRI				PLAT_RAS_PRI
+
 #if RAS_EXTENSION
 /* Allocate 128KB for CPER buffers */
 #define PLAT_SP_BUF_BASE			ULL(0x20000)
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
index 9a02312..fdbd4bf 100644
--- a/plat/st/stm32mp1/bl2_io_storage.c
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -37,7 +37,7 @@
 	.length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
 };
 
-uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
+static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
 
 static const io_block_dev_spec_t mmc_block_dev_spec = {
 	/* It's used as temp buffer in block driver */
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index 3c6d677..d5b328e 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -5,6 +5,7 @@
  */
 
 #include <desc_image_load.h>
+#include <platform.h>
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index 585707d..880e86e 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -9,6 +9,7 @@
 #include <bl31.h>
 #include <context_mgmt.h>
 #include <debug.h>
+#include <ehf.h>
 #include <errno.h>
 #include <mm_svc.h>
 #include <platform.h>
@@ -233,6 +234,19 @@
 		VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
 	}
 
+	/*
+	 * The current secure partition design mandates
+	 * - at any point, only a single core can be
+	 *   executing in the secure partiton.
+	 * - a core cannot be preempted by an interrupt
+	 *   while executing in secure partition.
+	 * Raise the running priority of the core to the
+	 * interrupt level configured for secure partition
+	 * so as to block any interrupt from preempting this
+	 * core.
+	 */
+	ehf_activate_priority(PLAT_SP_PRI);
+
 	/* Save the Normal world context */
 	cm_el1_sysregs_context_save(NON_SECURE);
 
@@ -243,6 +257,12 @@
 	cm_el1_sysregs_context_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 
+	/*
+	 * Exited from secure partition. This core can take
+	 * interrupts now.
+	 */
+	ehf_deactivate_priority(PLAT_SP_PRI);
+
 	SMC_RET1(handle, rc);
 }