diff mbox series

arm64: zynqmp: Add u-boot command to boot into recovery image

Message ID 20240827115529.2931334-1-prasad.kummari@amd.com
State Accepted
Delegated to: Michal Simek
Headers show
Series arm64: zynqmp: Add u-boot command to boot into recovery image | expand

Commit Message

Kummari, Prasad Aug. 27, 2024, 11:55 a.m. UTC
To boot into the firmware recovery tool, the user currently
needs to press a button on the board while powering the
system up. To simplify this process, a U-Boot command
was added to allow booting directly into the recovery tool.

For example:
ZynqMP> zynqmp reboot <multiboot offset in hex>

Co-develop-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Co-develop-by: Prasad Kummari <prasad.kummari@amd.com>
Signed-off-by: Prasad Kummari <prasad.kummari@amd.com>
---
 arch/arm/mach-zynqmp/include/mach/hardware.h |  6 ++++-
 arch/arm/mach-zynqmp/zynqmp.c                | 26 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

Comments

Michal Simek Sept. 6, 2024, 6:52 a.m. UTC | #1
On 8/27/24 13:55, Prasad Kummari wrote:
> To boot into the firmware recovery tool, the user currently
> needs to press a button on the board while powering the
> system up. To simplify this process, a U-Boot command
> was added to allow booting directly into the recovery tool.
> 
> For example:
> ZynqMP> zynqmp reboot <multiboot offset in hex>
> 
> Co-develop-by: Michal Simek <michal.simek@amd.com>
> Signed-off-by: Michal Simek <michal.simek@amd.com>
> Co-develop-by: Prasad Kummari <prasad.kummari@amd.com>
> Signed-off-by: Prasad Kummari <prasad.kummari@amd.com>
> ---
>   arch/arm/mach-zynqmp/include/mach/hardware.h |  6 ++++-
>   arch/arm/mach-zynqmp/zynqmp.c                | 26 ++++++++++++++++++++
>   2 files changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h
> index 8cb6494e52..9228fa3c80 100644
> --- a/arch/arm/mach-zynqmp/include/mach/hardware.h
> +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h
> @@ -42,6 +42,8 @@
>   #define CRLAPB_DBG_LPD_CTRL_SETUP_CLK	0x01002002
>   #define CRLAPB_RST_LPD_DBG_RESET	0
>   
> +#define CRL_APB_SOFT_RESET_CTRL_MASK	0x10
> +
>   struct crlapb_regs {
>   	u32 reserved0[36];
>   	u32 cpu_r5_ctrl; /* 0x90 */
> @@ -51,7 +53,9 @@ struct crlapb_regs {
>   	u32 timestamp_ref_ctrl; /* 0x128 */
>   	u32 reserved3[53];
>   	u32 boot_mode; /* 0x200 */
> -	u32 reserved4_0[7];
> +	u32 reserved4_0[5];
> +	u32 soft_reset; /* 0x218 */
> +	u32 reserved4_10;
>   	u32 reset_reason; /* 0x220 */
>   	u32 reserved4_1[6];
>   	u32 rst_lpd_top; /* 0x23C */
> diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c
> index bf39c5472e..3b4d9c60e5 100644
> --- a/arch/arm/mach-zynqmp/zynqmp.c
> +++ b/arch/arm/mach-zynqmp/zynqmp.c
> @@ -340,6 +340,30 @@ static int do_zynqmp_sha3(struct cmd_tbl *cmdtp, int flag,
>   	return CMD_RET_SUCCESS;
>   }
>   
> +static int do_zynqmp_reboot(struct cmd_tbl *cmdtp, int flag,
> +			    int argc, char * const argv[])
> +{
> +	u32 multiboot;
> +	int ret;
> +
> +	if (argc != cmdtp->maxargs)
> +		return CMD_RET_USAGE;
> +
> +	multiboot = hextoul(argv[2], NULL);
> +
> +	ret = zynqmp_mmio_write(0xFFCA0010, 0xfff, multiboot);
> +	if (ret != 0) {
> +		printf("Failed: mmio write\n");
> +		return ret;
> +	}
> +
> +	/* issue soft reset */
> +	writel(CRL_APB_SOFT_RESET_CTRL_MASK, &crlapb_base->soft_reset);
> +
> +	/* never get here */
> +	return CMD_RET_SUCCESS;
> +}
> +
>   static struct cmd_tbl cmd_zynqmp_sub[] = {
>   	U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
>   	U_BOOT_CMD_MKENT(pmufw, 4, 0, do_zynqmp_pmufw, "", ""),
> @@ -348,6 +372,7 @@ static struct cmd_tbl cmd_zynqmp_sub[] = {
>   	U_BOOT_CMD_MKENT(aes, 9, 0, do_zynqmp_aes, "", ""),
>   	U_BOOT_CMD_MKENT(rsa, 7, 0, do_zynqmp_rsa, "", ""),
>   	U_BOOT_CMD_MKENT(sha3, 5, 0, do_zynqmp_sha3, "", ""),
> +	U_BOOT_CMD_MKENT(reboot, 3, 0, do_zynqmp_reboot, "", ""),
>   #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
>   	U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
>   #endif
> @@ -387,6 +412,7 @@ U_BOOT_LONGHELP(zynqmp,
>   	"                            long at address $src. Optional key_addr\n"
>   	"                            can be specified if user key needs to\n"
>   	"                            be used for decryption\n"
> +	"zynqmp reboot multiboot - soft reboot to multiboot offset\n"
>   	"zynqmp mmio_read address - read from address\n"
>   	"zynqmp mmio_write address mask value - write value after masking to\n"
>   	"					address\n"

Applied.
M
diff mbox series

Patch

diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h
index 8cb6494e52..9228fa3c80 100644
--- a/arch/arm/mach-zynqmp/include/mach/hardware.h
+++ b/arch/arm/mach-zynqmp/include/mach/hardware.h
@@ -42,6 +42,8 @@ 
 #define CRLAPB_DBG_LPD_CTRL_SETUP_CLK	0x01002002
 #define CRLAPB_RST_LPD_DBG_RESET	0
 
+#define CRL_APB_SOFT_RESET_CTRL_MASK	0x10
+
 struct crlapb_regs {
 	u32 reserved0[36];
 	u32 cpu_r5_ctrl; /* 0x90 */
@@ -51,7 +53,9 @@  struct crlapb_regs {
 	u32 timestamp_ref_ctrl; /* 0x128 */
 	u32 reserved3[53];
 	u32 boot_mode; /* 0x200 */
-	u32 reserved4_0[7];
+	u32 reserved4_0[5];
+	u32 soft_reset; /* 0x218 */
+	u32 reserved4_10;
 	u32 reset_reason; /* 0x220 */
 	u32 reserved4_1[6];
 	u32 rst_lpd_top; /* 0x23C */
diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c
index bf39c5472e..3b4d9c60e5 100644
--- a/arch/arm/mach-zynqmp/zynqmp.c
+++ b/arch/arm/mach-zynqmp/zynqmp.c
@@ -340,6 +340,30 @@  static int do_zynqmp_sha3(struct cmd_tbl *cmdtp, int flag,
 	return CMD_RET_SUCCESS;
 }
 
+static int do_zynqmp_reboot(struct cmd_tbl *cmdtp, int flag,
+			    int argc, char * const argv[])
+{
+	u32 multiboot;
+	int ret;
+
+	if (argc != cmdtp->maxargs)
+		return CMD_RET_USAGE;
+
+	multiboot = hextoul(argv[2], NULL);
+
+	ret = zynqmp_mmio_write(0xFFCA0010, 0xfff, multiboot);
+	if (ret != 0) {
+		printf("Failed: mmio write\n");
+		return ret;
+	}
+
+	/* issue soft reset */
+	writel(CRL_APB_SOFT_RESET_CTRL_MASK, &crlapb_base->soft_reset);
+
+	/* never get here */
+	return CMD_RET_SUCCESS;
+}
+
 static struct cmd_tbl cmd_zynqmp_sub[] = {
 	U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
 	U_BOOT_CMD_MKENT(pmufw, 4, 0, do_zynqmp_pmufw, "", ""),
@@ -348,6 +372,7 @@  static struct cmd_tbl cmd_zynqmp_sub[] = {
 	U_BOOT_CMD_MKENT(aes, 9, 0, do_zynqmp_aes, "", ""),
 	U_BOOT_CMD_MKENT(rsa, 7, 0, do_zynqmp_rsa, "", ""),
 	U_BOOT_CMD_MKENT(sha3, 5, 0, do_zynqmp_sha3, "", ""),
+	U_BOOT_CMD_MKENT(reboot, 3, 0, do_zynqmp_reboot, "", ""),
 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
 	U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
 #endif
@@ -387,6 +412,7 @@  U_BOOT_LONGHELP(zynqmp,
 	"                            long at address $src. Optional key_addr\n"
 	"                            can be specified if user key needs to\n"
 	"                            be used for decryption\n"
+	"zynqmp reboot multiboot - soft reboot to multiboot offset\n"
 	"zynqmp mmio_read address - read from address\n"
 	"zynqmp mmio_write address mask value - write value after masking to\n"
 	"					address\n"