2 * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <plat/common/platform.h>
16 #include "../mhu/css_mhu.h"
17 #include "../scpi/css_scpi.h"
20 /* ID of the MHU slot used for the BOM protocol */
21 #define BOM_MHU_SLOT_ID 0
23 /* Boot commands sent from AP -> SCP */
24 #define BOOT_CMD_INFO 0x00
25 #define BOOT_CMD_DATA 0x01
27 /* BOM command header */
30 uint32_t reserved
: 24;
39 * Unlike the SCPI protocol, the boot protocol uses the same memory region
40 * for both AP -> SCP and SCP -> AP transfers; define the address of this...
42 #define BOM_SHARED_MEM PLAT_CSS_SCP_COM_SHARED_MEM_BASE
43 #define BOM_CMD_HEADER ((bom_cmd_t *) BOM_SHARED_MEM)
44 #define BOM_CMD_PAYLOAD ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t)))
47 /* Offset from the base address of the Trusted RAM */
53 * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31
54 * usually resides except when ARM_BL31_IN_DRAM is
55 * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and
58 CASSERT(SCP_BL2_LIMIT
<= BL2_BASE
, assert_scp_bl2_overwrite_bl2
);
59 CASSERT(SCP_BL2U_LIMIT
<= BL2_BASE
, assert_scp_bl2u_overwrite_bl2
);
61 CASSERT(SCP_BL2_BASE
>= ARM_TB_FW_CONFIG_LIMIT
, assert_scp_bl2_overflow
);
62 CASSERT(SCP_BL2U_BASE
>= ARM_TB_FW_CONFIG_LIMIT
, assert_scp_bl2u_overflow
);
64 static void scp_boot_message_start(void)
66 mhu_secure_message_start(BOM_MHU_SLOT_ID
);
69 static void scp_boot_message_send(size_t payload_size
)
71 /* Ensure that any write to the BOM payload area is seen by SCP before
72 * we write to the MHU register. If these 2 writes were reordered by
73 * the CPU then SCP would read stale payload data */
76 /* Send command to SCP */
77 mhu_secure_message_send(BOM_MHU_SLOT_ID
);
80 static uint32_t scp_boot_message_wait(size_t size
)
84 mhu_status
= mhu_secure_message_wait();
86 /* Expect an SCP Boot Protocol message, reject any other protocol */
87 if (mhu_status
!= (1 << BOM_MHU_SLOT_ID
)) {
88 ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n",
93 /* Ensure that any read to the BOM payload area is done after reading
94 * the MHU register. If these 2 reads were reordered then the CPU would
95 * read invalid payload data */
98 return *(uint32_t *) BOM_SHARED_MEM
;
101 static void scp_boot_message_end(void)
103 mhu_secure_message_end(BOM_MHU_SLOT_ID
);
106 int css_scp_boot_image_xfer(void *image
, unsigned int image_size
)
110 cmd_info_payload_t
*cmd_info_payload
;
111 cmd_data_payload_t
*cmd_data_payload
;
113 assert((uintptr_t) image
== SCP_BL2_BASE
);
115 if ((image_size
== 0) || (image_size
% 4 != 0)) {
116 ERROR("Invalid size for the SCP_BL2 image. Must be a multiple of "
117 "4 bytes and not zero (current size = 0x%x)\n",
122 /* Extract the checksum from the image */
123 checksum
= *(uint32_t *) image
;
124 image
= (char *) image
+ sizeof(checksum
);
125 image_size
-= sizeof(checksum
);
129 VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n");
132 * Send information about the SCP firmware image about to be transferred
135 scp_boot_message_start();
137 BOM_CMD_HEADER
->id
= BOOT_CMD_INFO
;
138 cmd_info_payload
= BOM_CMD_PAYLOAD
;
139 cmd_info_payload
->image_size
= image_size
;
140 cmd_info_payload
->checksum
= checksum
;
142 scp_boot_message_send(sizeof(*cmd_info_payload
));
143 #if CSS_DETECT_PRE_1_7_0_SCP
145 const uint32_t deprecated_scp_nack_cmd
= 0x404;
148 VERBOSE("Detecting SCP version incompatibility\n");
150 mhu_status
= mhu_secure_message_wait();
151 if (mhu_status
== deprecated_scp_nack_cmd
) {
152 ERROR("Detected an incompatible version of the SCP firmware.\n");
153 ERROR("Only versions from v1.7.0 onwards are supported.\n");
154 ERROR("Please update the SCP firmware.\n");
158 VERBOSE("SCP version looks OK\n");
160 #endif /* CSS_DETECT_PRE_1_7_0_SCP */
161 response
= scp_boot_message_wait(sizeof(response
));
162 scp_boot_message_end();
165 ERROR("SCP BOOT_CMD_INFO returned error %u\n", response
);
169 VERBOSE("Transferring SCP_BL2 image to SCP\n");
171 /* Transfer SCP_BL2 image to SCP */
172 scp_boot_message_start();
174 BOM_CMD_HEADER
->id
= BOOT_CMD_DATA
;
175 cmd_data_payload
= BOM_CMD_PAYLOAD
;
176 cmd_data_payload
->offset
= (uintptr_t) image
- ARM_TRUSTED_SRAM_BASE
;
177 cmd_data_payload
->block_size
= image_size
;
179 scp_boot_message_send(sizeof(*cmd_data_payload
));
180 response
= scp_boot_message_wait(sizeof(response
));
181 scp_boot_message_end();
184 ERROR("SCP BOOT_CMD_DATA returned error %u\n", response
);
191 int css_scp_boot_ready(void)
193 VERBOSE("Waiting for SCP to signal it is ready to go on\n");
195 /* Wait for SCP to signal it's ready */
196 return scpi_wait_ready();