summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorRichard Gong <richard.gong@intel.com>2020-10-16 13:41:47 -0500
committerYau Wai Gan <yau.wai.gan@.intel.com>2020-10-27 14:50:02 +0800
commit1d4284034527cd72ece1bdbc4e9a4951d3fd5ec3 (patch)
treed2fb3a33f208455022ffa91c9d5ef7c7614cf6d3 /arch
parent6a7e8c4e9fe371c443eb71fa5f9c9eb3b524bbfd (diff)
downloadu-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.h4
-rw-r--r--arch/arm/mach-socfpga/rsu_ll_qspi.c42
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) {