Move to the new ARM SCP Messaging Interfaces

The communication protocol used between the AP cores and the SCP
in CSS-based platforms like Juno has undergone a number of changes.
This patch makes the required modifications to the SCP Boot Protocol,
SCPI Protocol and MHU driver code in shared CSS platform code so that
the AP cores are still able to communicate with the SCP.

This patch focuses on the mandatory changes to make it work. The
design of this code needs to be improved but this will come in
a subsequent patch.

The main changes are:

 - MHU communication protocol

   - The command ID and payload size are no longer written into the
     MHU registers directly. Instead, they are stored in the payload
     area. The MHU registers are now used only as a doorbell to kick
     off messages. Same goes for any command result, the AP has to
     pick it up from the payload area.

 - SCP Boot Protocol

   - The BL3-0 image is now expected to embed a checksum. This
     checksum must be passed to the SCP, which uses it to check the
     integrity of the image it received.

   - The BL3-0 image used to be transferred a block (4KB)
     at a time. The SCP now supports receiving up to 128KB at a
     time, which is more than the size of the BL3-0 image.
     Therefore, the image is now sent in one go.

   - The command IDs have changed.

 - SCPI Protocol

   - The size of the SCPI payload has been reduced down from 512
     bytes to 256 bytes. This changes the base address of the
     AP-to-SCP payload area.

   - For commands that have a response, the response is the same SCPI
     header that was sent, except for the size and the status, which
     both must be updated appropriately. Success/Failure of a command
     is determined by looking at the updated status code.

   - Some command IDs have changed.

NOTE: THIS PATCH BREAKS COMPATIBILITY WITH FORMER VERSIONS OF THE SCP
FIRMWARE AND THUS REQUIRES AN UPDATE OF THIS BINARY. THE LATEST SCP
BINARY CAN BE OBTAINED FROM THE ARM CONNECTED COMMUNITY WEBSITE.

Change-Id: Ia5f6b95fe32401ee04a3805035748e8ef6718da7
diff --git a/plat/arm/css/common/css_mhu.c b/plat/arm/css/common/css_mhu.c
index fa4a81d..b1714e2 100644
--- a/plat/arm/css/common/css_mhu.c
+++ b/plat/arm/css/common/css_mhu.c
@@ -29,6 +29,7 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <bakery_lock.h>
 #include <css_def.h>
 #include <mmio.h>
@@ -51,21 +52,31 @@
 #pragma weak plat_arm_pwrc_setup
 
 
-void mhu_secure_message_start(void)
+/*
+ * Slot 31 is reserved because the MHU hardware uses this register bit to
+ * indicate a non-secure access attempt. The total number of available slots is
+ * therefore 31 [30:0].
+ */
+#define MHU_MAX_SLOT_ID		30
+
+void mhu_secure_message_start(unsigned int slot_id)
 {
+	assert(slot_id <= MHU_MAX_SLOT_ID);
+
 	arm_lock_get();
 
 	/* Make sure any previous command has finished */
-	while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+	while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) & (1 << slot_id))
 		;
 }
 
-void mhu_secure_message_send(uint32_t command)
+void mhu_secure_message_send(unsigned int slot_id)
 {
-	/* Send command to SCP and wait for it to pick it up */
-	mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command);
-	while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
-		;
+	assert(slot_id <= MHU_MAX_SLOT_ID);
+	assert(!(mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) & (1 << slot_id)));
+
+	/* Send command to SCP */
+	mmio_write_32(MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
 }
 
 uint32_t mhu_secure_message_wait(void)
@@ -78,13 +89,15 @@
 	return response;
 }
 
-void mhu_secure_message_end(void)
+void mhu_secure_message_end(unsigned int slot_id)
 {
+	assert(slot_id <= MHU_MAX_SLOT_ID);
+
 	/*
-	 * Clear any response we got by writing all ones to the CLEAR
-	 * register
+	 * Clear any response we got by writing one in the relevant slot bit to
+	 * the CLEAR register
 	 */
-	mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu);
+	mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
 
 	arm_lock_release();
 }
@@ -94,10 +107,11 @@
 	arm_lock_init();
 
 	/*
-	 * Clear the CPU's INTR register to make sure we don't see a stale
-	 * or garbage value and think it's a message we've already sent.
+	 * The STAT register resets to zero. Ensure it is in the expected state,
+	 * as a stale or garbage value would make us think it's a message we've
+	 * already sent.
 	 */
-	mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu);
+	assert(mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) == 0);
 }
 
 void plat_arm_pwrc_setup(void)