diff options
author | Richard Gong <richard.gong@intel.com> | 2020-10-16 13:41:47 -0500 |
---|---|---|
committer | Yau Wai Gan <yau.wai.gan@.intel.com> | 2020-10-27 14:50:02 +0800 |
commit | 1d4284034527cd72ece1bdbc4e9a4951d3fd5ec3 (patch) | |
tree | d2fb3a33f208455022ffa91c9d5ef7c7614cf6d3 /arch | |
parent | 6a7e8c4e9fe371c443eb71fa5f9c9eb3b524bbfd (diff) | |
download | u-boot-socfpga-1d4284034527cd72ece1bdbc4e9a4951d3fd5ec3.tar.gz |
HSD #22010730357: rsu: change to handle the corrupted CPB reported by firmware
Firmware is able to detect CPB corruption status and report the status via
error code to HPS.
0xF004D011 -- both CPBs were corrupted
0xF004D010 -- CPB0 was corrupted but CPB1 was fine
Changes to handle the corrupted CPBs reported by firmware:
1. Don't perform additional integrity check on CPB0 and CPB1 if both CPBs
were corrupted.
2. Don't perform additional integrity check on CPB0 if CPB0 was corrupted.
Signed-off-by: Richard Gong <richard.gong@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/rsu.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/rsu_ll_qspi.c | 42 |
2 files changed, 37 insertions, 9 deletions
diff --git a/arch/arm/mach-socfpga/include/mach/rsu.h b/arch/arm/mach-socfpga/include/mach/rsu.h index 6e9207129c..e03e43d710 100644 --- a/arch/arm/mach-socfpga/include/mach/rsu.h +++ b/arch/arm/mach-socfpga/include/mach/rsu.h @@ -28,6 +28,10 @@ #define ECORRUPTED_CPB 15 #define ECORRUPTED_SPT 16 +#define STATE_DCIO_CORRUPTED 0xF004D00F +#define STATE_CPB0_CORRUPTED 0xF004D010 +#define STATE_CPB0_CPB1_CORRUPTED 0xF004D011 + /* RSU Version Bitmasks */ #define RSU_VERSION_CRT_IDX_MASK GENMASK(31, 28) #define RSU_VERSION_ERR_MASK GENMASK(27, 16) diff --git a/arch/arm/mach-socfpga/rsu_ll_qspi.c b/arch/arm/mach-socfpga/rsu_ll_qspi.c index b30634979a..ef9371db38 100644 --- a/arch/arm/mach-socfpga/rsu_ll_qspi.c +++ b/arch/arm/mach-socfpga/rsu_ll_qspi.c @@ -52,6 +52,8 @@ #define CPB_IMAGE_PTR_OFFSET 24 #define CPB_IMAGE_PTR_NSLOTS 508 +#define SPT_CHECKSUM_OFFSET 0x0C + /** * struct sub_partition_table_partition - SPT partition structure * @name: sub-partition name @@ -797,6 +799,26 @@ static int load_cpb(void) int x; int cpb0_good = 0; int cpb1_good = 0; + struct rsu_status_info status_info; + int cpb0_corrupted = 0; + + if (mbox_rsu_status((u32 *)&status_info, + sizeof(status_info) / 4)) { + rsu_log(RSU_ERR, "FW doesn't support RSU\n"); + return -EINVAL; + } + + if (status_info.state == STATE_CPB0_CPB1_CORRUPTED) { + rsu_log(RSU_ERR, "FW detects both CPBs corrupted\n"); + cpb_corrupted = true; + return -EINVAL; + } + + if (status_info.state == STATE_CPB0_CORRUPTED) { + rsu_log(RSU_ERR, + "FW detects corrupted CPB0 but CPB1 is fine\n"); + cpb0_corrupted = 1; + } for (x = 0; x < spt.partitions; x++) { if (strcmp(spt.partition[x].name, "CPB0") == 0) @@ -824,15 +846,17 @@ static int load_cpb(void) rsu_log(RSU_ERR, "Bad CPB1 is bad\n"); } - rsu_log(RSU_DEBUG, "Reading CPB0\n"); - if (read_part(cpb0_part, 0, &cpb, sizeof(cpb)) == 0 && - cpb.header.magic_number == CPB_MAGIC_NUMBER) { - cpb_slots = (u64 *) - &cpb.data[cpb.header.image_ptr_offset]; - if (check_cpb() == 0) - cpb0_good = 1; - } else { - rsu_log(RSU_ERR, "Bad CPB0 is bad\n"); + if (!cpb0_corrupted) { + rsu_log(RSU_DEBUG, "Reading CPB0\n"); + if (read_part(cpb0_part, 0, &cpb, sizeof(cpb)) == 0 && + cpb.header.magic_number == CPB_MAGIC_NUMBER) { + cpb_slots = (u64 *) + &cpb.data[cpb.header.image_ptr_offset]; + if (check_cpb() == 0) + cpb0_good = 1; + } else { + rsu_log(RSU_ERR, "Bad CPB0 is bad\n"); + } } if (cpb0_good && cpb1_good) { |