Commit b143fa74 authored by Grzegorz Jaszczyk's avatar Grzegorz Jaszczyk
Browse files

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: default avatarGrzegorz Jaszczyk <jaz@semihalf.com>
Change-Id: Ia74dbc36efcfbefc4a102d31191e6af5808c4a82
parent 8a08e272
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment