summaryrefslogtreecommitdiff
path: root/plat/marvell
diff options
context:
space:
mode:
authorGrzegorz Jaszczyk <jaz@semihalf.com>2019-04-04 17:16:39 +0200
committerGrzegorz Jaszczyk <jaz@semihalf.com>2019-04-05 12:48:40 +0200
commitb143fa7491bf9029ccd46c05d7d2267b3c2e2775 (patch)
treea42d600695cd8789977163ae7da29ea7e8348be1 /plat/marvell
parent8a08e27232d0c1b906fd2f3e4b3b7a90661a50b9 (diff)
plat: marvell: sip: make sure that comphy init will use correct address
The argument passed via x1 is used as a base address for comphy related routines. Nevertheless validation of this address wasn't good enough and allowed some non comphy related addresses to slip over. To overcome this issue make sure that the address passed via SMC points to valid CP range and allow to proceed comphy initializations only with correct comphy offset. This could be fixed in a different way e.g. by passing CP id from the caller, but since this API is already used with various Linux, U-Boot and UEFI versions it can't be changed. Signed-off-by: Grzegorz Jaszczyk <jaz@semihalf.com> Change-Id: Ia74dbc36efcfbefc4a102d31191e6af5808c4a82
Diffstat (limited to 'plat/marvell')
-rw-r--r--plat/marvell/common/mrvl_sip_svc.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/common/mrvl_sip_svc.c
index df211059..36cada19 100644
--- a/plat/marvell/common/mrvl_sip_svc.c
+++ b/plat/marvell/common/mrvl_sip_svc.c
@@ -15,6 +15,7 @@
#include <plat_marvell.h>
#include "comphy/phy-comphy-cp110.h"
+#include <stdbool.h>
/* #define DEBUG_COMPHY */
#ifdef DEBUG_COMPHY
@@ -38,12 +39,24 @@
#define MAX_LANE_NR 6
#define MVEBU_COMPHY_OFFSET 0x441000
-#define MVEBU_SD_OFFSET 0x120000
+#define MVEBU_CP_BASE_MASK (~0xffffff)
/* This macro is used to identify COMPHY related calls from SMC function ID */
#define is_comphy_fid(fid) \
((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET)
+_Bool is_cp_range_valid(u_register_t *addr)
+{
+ int cp_nr;
+
+ *addr &= MVEBU_CP_BASE_MASK;
+ for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) {
+ if (*addr == MVEBU_CP_REGS_BASE(cp_nr))
+ return true;
+ }
+
+ return false;
+}
uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid,
u_register_t x1,
@@ -59,20 +72,17 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid,
debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n",
__func__, smc_fid, x1, x2, x3);
- if (is_comphy_fid(smc_fid)) {
-
- /* some systems passes SD phys address instead of COMPHY phys
- * address - convert it
- */
- if (x1 & MVEBU_SD_OFFSET)
- x1 = (x1 & ~0xffffff) + MVEBU_COMPHY_OFFSET;
- if ((x1 & 0xffffff) != MVEBU_COMPHY_OFFSET) {
+ if (is_comphy_fid(smc_fid)) {
+ /* validate address passed via x1 */
+ if (!is_cp_range_valid(&x1)) {
ERROR("%s: Wrong smc (0x%x) address: %lx\n",
__func__, smc_fid, x1);
SMC_RET1(handle, SMC_UNK);
}
+ x1 += MVEBU_COMPHY_OFFSET;
+
if (x2 >= MAX_LANE_NR) {
ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n",
__func__, smc_fid, x2);