[PATCH u-boot-mvebu v2 4/5] arm: mvebu: a37xx: Extend mbox_do_cmd() code

Pali Rohár pali at kernel.org
Thu Feb 17 19:50:45 CET 2022


Allow to specify input parameters, define all available mbox commands
supported by CZ.NIC's secure firmware and also Marvell's fuse.bin firmware
and fix parsing response from Marvell OTP commands.

Signed-off-by: Pali Rohár <pali at kernel.org>
Reviewed-by: Marek Behún <marek.behun at nic.cz>
---
 arch/arm/mach-mvebu/armada3700/mbox.c   | 20 ++++++++++++++++++--
 arch/arm/mach-mvebu/include/mach/mbox.h | 19 ++++++++++++++++++-
 board/CZ.NIC/turris_mox/mox_sp.c        |  4 ++--
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mvebu/armada3700/mbox.c b/arch/arm/mach-mvebu/armada3700/mbox.c
index cb86b967c2eb..eb1f82845f0f 100644
--- a/arch/arm/mach-mvebu/armada3700/mbox.c
+++ b/arch/arm/mach-mvebu/armada3700/mbox.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2018 Marek Behun <marek.behun at nic.cz>
+ * Copyright (C) 2021 Pali Rohár <pali at kernel.org>
  */
 
 #include <common.h>
@@ -15,6 +16,7 @@
 #define RWTM_CMD		(RWTM_BASE + 0x40)
 #define RWTM_CMD_RETSTATUS	(RWTM_BASE + 0x80)
 #define RWTM_CMD_STATUS(i)	(size_t)(RWTM_BASE + 0x84 + (i) * 4)
+#define MAX_ARGS		16
 
 #define RWTM_HOST_INT_RESET	(RWTM_BASE + 0xc8)
 #define RWTM_HOST_INT_MASK	(RWTM_BASE + 0xcc)
@@ -27,15 +29,27 @@
 #define MBOX_STS_ERROR(s)		((s) & (3 << 30))
 #define MBOX_STS_VALUE(s)		(((s) >> 10) & 0xfffff)
 #define MBOX_STS_CMD(s)			((s) & 0x3ff)
+#define MBOX_STS_MARVELL_ERROR(s)	((s) == 0 ? 0         : \
+					 (s) == 2 ? ETIMEDOUT : \
+					 (s) == 3 ? EINVAL    : \
+					 (s) == 4 ? ENOSYS    : \
+					            EIO)
 
-int mbox_do_cmd(enum mbox_cmd cmd, u32 *out, int nout)
+int mbox_do_cmd(enum mbox_cmd cmd, u32 *in, int nin, u32 *out, int nout)
 {
 	const int tries = 50;
 	int i;
 	u32 status;
 
+	if (nin > MAX_ARGS || nout > MAX_ARGS)
+		return -EINVAL;
+
 	clrbits_le32(RWTM_HOST_INT_MASK, SP_CMD_COMPLETE);
 
+	for (i = 0; i < nin; i++)
+		writel(in[i], RWTM_CMD_PARAM(i));
+	for (; i < MAX_ARGS; i++)
+		writel(0x0, RWTM_CMD_PARAM(i));
 	writel(cmd, RWTM_CMD);
 
 	for (i = 0; i < tries; ++i) {
@@ -57,9 +71,11 @@ int mbox_do_cmd(enum mbox_cmd cmd, u32 *out, int nout)
 	setbits_le32(RWTM_HOST_INT_RESET, SP_CMD_COMPLETE);
 
 	if (MBOX_STS_CMD(status) != cmd)
-		return -EIO;
+		return -MBOX_STS_MARVELL_ERROR(status);
 	else if (MBOX_STS_ERROR(status) == MBOX_STS_FAIL)
 		return -(int)MBOX_STS_VALUE(status);
+	else if (MBOX_STS_ERROR(status) == MBOX_STS_BADCMD)
+		return -ENOSYS;
 	else if (MBOX_STS_ERROR(status) != MBOX_STS_SUCCESS)
 		return -EIO;
 	else
diff --git a/arch/arm/mach-mvebu/include/mach/mbox.h b/arch/arm/mach-mvebu/include/mach/mbox.h
index 981204935832..f1cb55f2bfe7 100644
--- a/arch/arm/mach-mvebu/include/mach/mbox.h
+++ b/arch/arm/mach-mvebu/include/mach/mbox.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2018 Marek Behun <marek.behun at nic.cz>
+ * Copyright (C) 2021 Pali Rohár <pali at kernel.org>
  */
 
 #ifndef _MVEBU_MBOX_H
@@ -16,8 +17,24 @@ enum mbox_cmd {
 
 	MBOX_CMD_OTP_READ,
 	MBOX_CMD_OTP_WRITE,
+
+	MBOX_CMD_REBOOT,
+
+	/* OTP read commands supported by Marvell fuse.bin firmware */
+	MBOX_CMD_OTP_READ_1B	= 257,
+	MBOX_CMD_OTP_READ_8B,
+	MBOX_CMD_OTP_READ_32B,
+	MBOX_CMD_OTP_READ_64B,
+	MBOX_CMD_OTP_READ_256B,
+
+	/* OTP write commands supported by Marvell fuse.bin firmware */
+	MBOX_CMD_OTP_WRITE_1B	= 513,
+	MBOX_CMD_OTP_WRITE_8B,
+	MBOX_CMD_OTP_WRITE_32B,
+	MBOX_CMD_OTP_WRITE_64B,
+	MBOX_CMD_OTP_WRITE_256B,
 };
 
-int mbox_do_cmd(enum mbox_cmd cmd, u32 *in, int nout);
+int mbox_do_cmd(enum mbox_cmd cmd, u32 *in, int nin, u32 *out, int nout);
 
 #endif
diff --git a/board/CZ.NIC/turris_mox/mox_sp.c b/board/CZ.NIC/turris_mox/mox_sp.c
index 4de067bbebbb..93e96b014fca 100644
--- a/board/CZ.NIC/turris_mox/mox_sp.c
+++ b/board/CZ.NIC/turris_mox/mox_sp.c
@@ -19,7 +19,7 @@ const char *mox_sp_get_ecdsa_public_key(void)
 	if (public_key[0])
 		return public_key;
 
-	res = mbox_do_cmd(MBOX_CMD_ECDSA_PUB_KEY, out, 16);
+	res = mbox_do_cmd(MBOX_CMD_ECDSA_PUB_KEY, NULL, 0, out, 16);
 	if (res < 0)
 		return NULL;
 
@@ -47,7 +47,7 @@ int mbox_sp_get_board_info(u64 *sn, u8 *mac1, u8 *mac2, int *bv, int *ram)
 	u32 out[8];
 	int res;
 
-	res = mbox_do_cmd(MBOX_CMD_BOARD_INFO, out, 8);
+	res = mbox_do_cmd(MBOX_CMD_BOARD_INFO, NULL, 0, out, 8);
 	if (res < 0)
 		return res;
 
-- 
2.20.1



More information about the U-Boot mailing list