Commit d96cf190 authored by Pascal van Leeuwen's avatar Pascal van Leeuwen Committed by Herbert Xu

crypto: inside-secure - Fixed corner case TRC admin RAM probing issue

This patch fixed a corner case admin RAM probing issue witnessed on the
Xilinx VCU118 FPGA development board with an EIP197 configuration with
4096 words of admin RAM, of which only 2050 were recognised.
Signed-off-by: default avatarPascal van Leeuwen <pvanleeuwen@verimatrix.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent b8c5d882
...@@ -75,9 +75,9 @@ static void eip197_trc_cache_banksel(struct safexcel_crypto_priv *priv, ...@@ -75,9 +75,9 @@ static void eip197_trc_cache_banksel(struct safexcel_crypto_priv *priv,
} }
static u32 eip197_trc_cache_probe(struct safexcel_crypto_priv *priv, static u32 eip197_trc_cache_probe(struct safexcel_crypto_priv *priv,
int maxbanks, u32 probemask) int maxbanks, u32 probemask, u32 stride)
{ {
u32 val, addrhi, addrlo, addrmid; u32 val, addrhi, addrlo, addrmid, addralias, delta, marker;
int actbank; int actbank;
/* /*
...@@ -87,33 +87,38 @@ static u32 eip197_trc_cache_probe(struct safexcel_crypto_priv *priv, ...@@ -87,33 +87,38 @@ static u32 eip197_trc_cache_probe(struct safexcel_crypto_priv *priv,
addrhi = 1 << (16 + maxbanks); addrhi = 1 << (16 + maxbanks);
addrlo = 0; addrlo = 0;
actbank = min(maxbanks - 1, 0); actbank = min(maxbanks - 1, 0);
while ((addrhi - addrlo) > 32) { while ((addrhi - addrlo) > stride) {
/* write marker to lowest address in top half */ /* write marker to lowest address in top half */
addrmid = (addrhi + addrlo) >> 1; addrmid = (addrhi + addrlo) >> 1;
marker = (addrmid ^ 0xabadbabe) & probemask; /* Unique */
eip197_trc_cache_banksel(priv, addrmid, &actbank); eip197_trc_cache_banksel(priv, addrmid, &actbank);
writel((addrmid | (addrlo << 16)) & probemask, writel(marker,
priv->base + EIP197_CLASSIFICATION_RAMS + priv->base + EIP197_CLASSIFICATION_RAMS +
(addrmid & 0xffff)); (addrmid & 0xffff));
/* write marker to lowest address in bottom half */ /* write invalid markers to possible aliases */
eip197_trc_cache_banksel(priv, addrlo, &actbank); delta = 1 << __fls(addrmid);
writel((addrlo | (addrhi << 16)) & probemask, while (delta >= stride) {
addralias = addrmid - delta;
eip197_trc_cache_banksel(priv, addralias, &actbank);
writel(~marker,
priv->base + EIP197_CLASSIFICATION_RAMS + priv->base + EIP197_CLASSIFICATION_RAMS +
(addrlo & 0xffff)); (addralias & 0xffff));
delta >>= 1;
}
/* read back marker from top half */ /* read back marker from top half */
eip197_trc_cache_banksel(priv, addrmid, &actbank); eip197_trc_cache_banksel(priv, addrmid, &actbank);
val = readl(priv->base + EIP197_CLASSIFICATION_RAMS + val = readl(priv->base + EIP197_CLASSIFICATION_RAMS +
(addrmid & 0xffff)); (addrmid & 0xffff));
if (val == ((addrmid | (addrlo << 16)) & probemask)) { if ((val & probemask) == marker)
/* read back correct, continue with top half */ /* read back correct, continue with top half */
addrlo = addrmid; addrlo = addrmid;
} else { else
/* not read back correct, continue with bottom half */ /* not read back correct, continue with bottom half */
addrhi = addrmid; addrhi = addrmid;
} }
}
return addrhi; return addrhi;
} }
...@@ -150,7 +155,7 @@ static void eip197_trc_cache_clear(struct safexcel_crypto_priv *priv, ...@@ -150,7 +155,7 @@ static void eip197_trc_cache_clear(struct safexcel_crypto_priv *priv,
htable_offset + i * sizeof(u32)); htable_offset + i * sizeof(u32));
} }
static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv) static int eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
{ {
u32 val, dsize, asize; u32 val, dsize, asize;
int cs_rc_max, cs_ht_wc, cs_trc_rec_wc, cs_trc_lg_rec_wc; int cs_rc_max, cs_ht_wc, cs_trc_rec_wc, cs_trc_lg_rec_wc;
...@@ -183,7 +188,7 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv) ...@@ -183,7 +188,7 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
writel(val, priv->base + EIP197_TRC_PARAMS); writel(val, priv->base + EIP197_TRC_PARAMS);
/* Probed data RAM size in bytes */ /* Probed data RAM size in bytes */
dsize = eip197_trc_cache_probe(priv, maxbanks, 0xffffffff); dsize = eip197_trc_cache_probe(priv, maxbanks, 0xffffffff, 32);
/* /*
* Now probe the administration RAM size pretty much the same way * Now probe the administration RAM size pretty much the same way
...@@ -196,11 +201,18 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv) ...@@ -196,11 +201,18 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
writel(val, priv->base + EIP197_TRC_PARAMS); writel(val, priv->base + EIP197_TRC_PARAMS);
/* Probed admin RAM size in admin words */ /* Probed admin RAM size in admin words */
asize = eip197_trc_cache_probe(priv, 0, 0xbfffffff) >> 4; asize = eip197_trc_cache_probe(priv, 0, 0x3fffffff, 16) >> 4;
/* Clear any ECC errors detected while probing! */ /* Clear any ECC errors detected while probing! */
writel(0, priv->base + EIP197_TRC_ECCCTRL); writel(0, priv->base + EIP197_TRC_ECCCTRL);
/* Sanity check probing results */
if (dsize < EIP197_MIN_DSIZE || asize < EIP197_MIN_ASIZE) {
dev_err(priv->dev, "Record cache probing failed (%d,%d).",
dsize, asize);
return -ENODEV;
}
/* /*
* Determine optimal configuration from RAM sizes * Determine optimal configuration from RAM sizes
* Note that we assume that the physical RAM configuration is sane * Note that we assume that the physical RAM configuration is sane
...@@ -251,6 +263,7 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv) ...@@ -251,6 +263,7 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
dev_info(priv->dev, "TRC init: %dd,%da (%dr,%dh)\n", dev_info(priv->dev, "TRC init: %dd,%da (%dr,%dh)\n",
dsize, asize, cs_rc_max, cs_ht_wc + cs_ht_wc); dsize, asize, cs_rc_max, cs_ht_wc + cs_ht_wc);
return 0;
} }
static void eip197_init_firmware(struct safexcel_crypto_priv *priv) static void eip197_init_firmware(struct safexcel_crypto_priv *priv)
...@@ -737,7 +750,10 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv) ...@@ -737,7 +750,10 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK); writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
if (priv->flags & SAFEXCEL_HW_EIP197) { if (priv->flags & SAFEXCEL_HW_EIP197) {
eip197_trc_cache_init(priv); ret = eip197_trc_cache_init(priv);
if (ret)
return ret;
priv->flags |= EIP197_TRC_CACHE; priv->flags |= EIP197_TRC_CACHE;
ret = eip197_load_firmwares(priv); ret = eip197_load_firmwares(priv);
......
...@@ -439,6 +439,8 @@ struct safexcel_context_record { ...@@ -439,6 +439,8 @@ struct safexcel_context_record {
#define EIP197_TRC_PARAMS2_RC_SZ_SMALL(n) ((n) << 18) #define EIP197_TRC_PARAMS2_RC_SZ_SMALL(n) ((n) << 18)
/* Cache helpers */ /* Cache helpers */
#define EIP197_MIN_DSIZE 1024
#define EIP197_MIN_ASIZE 8
#define EIP197_CS_TRC_REC_WC 64 #define EIP197_CS_TRC_REC_WC 64
#define EIP197_CS_RC_SIZE (4 * sizeof(u32)) #define EIP197_CS_RC_SIZE (4 * sizeof(u32))
#define EIP197_CS_RC_NEXT(x) (x) #define EIP197_CS_RC_NEXT(x) (x)
......
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