summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTien Fong Chee <tien.fong.chee@intel.com>2021-06-14 22:44:54 -0700
committerLokanathan, Raaj <raaj.lokanathan@intel.com>2022-07-28 00:38:25 +0800
commit657397579859a1e09d4d97b332e3e393fefef3ca (patch)
treefc9ed5e9323dd179cf542924a2cdc932d085971b
parent7df7639aebe41bef77b5fc19c657991b396f6f85 (diff)
downloadu-boot-socfpga-657397579859a1e09d4d97b332e3e393fefef3ca.tar.gz
ddr: altera: n5x: Ensure 'cal->header.data_len' is validated
Klocwork reported the unvalidated integer value 'cal->header.data_len' is used but this is not a issue because the proper value is calculated before assigning 'cal->header.data_len' and CRC32 is generated before saving this value into QSPI to ensure data integrity when reading this variable. Adding checking on 'cal->header.data_len' to ensure the value is valid for the sake of good coding practice. Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
-rw-r--r--drivers/ddr/altera/sdram_n5x.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
index 29ea09a222..fe9f9bb390 100644
--- a/drivers/ddr/altera/sdram_n5x.c
+++ b/drivers/ddr/altera/sdram_n5x.c
@@ -1102,8 +1102,8 @@ static void phy_ocram(phys_addr_t phy_base, phys_addr_t phy_offset,
}
}
-static void cal_data_ocram(phys_addr_t phy_base, u32 addr,
- enum data_process proc)
+static int cal_data_ocram(phys_addr_t phy_base, u32 addr,
+ enum data_process proc)
{
/*
* This array variable contains a list of PHY registers required for
@@ -1428,6 +1428,13 @@ static void cal_data_ocram(phys_addr_t phy_base, u32 addr,
cal->header.ddrconfig_hash,
CHUNKSZ_PER_WD_RESET);
+ if (SOC64_HANDOFF_BASE < ((uintptr_t)(&cal->data) +
+ cal->header.data_len)) {
+ debug("%s: Backup cal data overflow HPS handoff\n",
+ __func__);
+ return -ENOEXEC;
+ }
+
crc32_wd_buf((u8 *)&cal->data, cal->header.data_len,
(u8 *)&cal->header.caldata_crc32,
CHUNKSZ_PER_WD_RESET);
@@ -1436,6 +1443,8 @@ static void cal_data_ocram(phys_addr_t phy_base, u32 addr,
/* Isolate the APB access from internal CSRs */
setbits_le16(phy_base + DDR_PHY_APBONLY0_OFFSET,
DDR_PHY_MICROCONTMUXSEL);
+
+ return 0;
}
static bool is_ddrconfig_hash_match(const void *buffer)
@@ -1552,6 +1561,12 @@ static bool is_cal_bak_data_valid(void)
return false;
}
+ if (SOC64_HANDOFF_BASE < (SOC64_OCRAM_PHY_BACKUP_BASE +
+ cal->header.data_len + sizeof(struct cal_header_t))) {
+ debug("%s: Backup cal data overflow HPS handoff\n", __func__);
+ return false;
+ }
+
/* Load header + DDR bak cal into OCRAM buffer */
ret = request_firmware_into_buf(dev,
qspi_offset,
@@ -1564,6 +1579,12 @@ static bool is_cal_bak_data_valid(void)
return false;
}
+ if (SOC64_HANDOFF_BASE < ((uintptr_t)(&cal->data) +
+ cal->header.data_len)) {
+ debug("%s: Backup cal data overflow HPS handoff\n", __func__);
+ return false;
+ }
+
crc32_wd_buf((u8 *)&cal->data, cal->header.data_len,
(u8 *)&crc32, CHUNKSZ_PER_WD_RESET);
debug("%s: crc32 %x for bak calibration data from QSPI\n", __func__,
@@ -1623,9 +1644,11 @@ static int init_phy(struct ddr_handoff *ddr_handoff_info,
ddr_handoff_info->phy_handoff_length,
ddr_handoff_info->phy_base);
} else {
- cal_data_ocram(ddr_handoff_info->phy_base,
- SOC64_OCRAM_PHY_BACKUP_BASE, LOADING);
+ ret = cal_data_ocram(ddr_handoff_info->phy_base,
+ SOC64_OCRAM_PHY_BACKUP_BASE, LOADING);
+ if (ret)
+ return ret;
/*
* Invalidate the section used for processing the PHY
* backup calibration data
@@ -2929,10 +2952,14 @@ int sdram_mmr_init_full(struct udevice *dev)
* Backup calibration data to OCRAM first, these data
* might be permanant stored to flash in later
*/
- if (is_ddr_retention_enabled(reg))
- cal_data_ocram(ddr_handoff_info.phy_base,
- SOC64_OCRAM_PHY_BACKUP_BASE,
- STORE);
+ if (is_ddr_retention_enabled(reg)) {
+ ret = cal_data_ocram(ddr_handoff_info.phy_base,
+ SOC64_OCRAM_PHY_BACKUP_BASE,
+ STORE);
+
+ if (ret)
+ return ret;
+ }
} else {
/* Updating training result to DDR controller */