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 |
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 --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"