armv7-a/r: NON-primary core should invalidate dacache level1

NON-primary cpu will invalidate cpu0's cache L2, that will caused cpu0's data mismatch, and then system crash

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2022-09-22 11:56:49 +08:00 committed by Xiang Xiao
parent a1ebd499ea
commit 059497d1d1
5 changed files with 171 additions and 145 deletions

View File

@ -90,7 +90,7 @@ void arm_enable_smp(int cpu)
* coherent L2.
*/
cp15_invalidate_dcache_all();
cp15_dcache_op_level(0, CP15_CACHE_INVALIDATE);
ARM_DSB();
/* Wait for the SCU to be enabled by the primary processor -- should

View File

@ -28,14 +28,6 @@
#include "cp15_cacheops.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define CP15_CACHE_INVALIDATE 0
#define CP15_CACHE_CLEAN 1
#define CP15_CACHE_CLEANINVALIDATE 2
/****************************************************************************
* Private Functions
****************************************************************************/
@ -69,70 +61,6 @@ static inline uint32_t cp15_cache_get_info(uint32_t *sets, uint32_t *ways)
return (1 << ((ccsidr & 0x7) + 2)) * 4;
}
static void cp15_dcache_op_level(uint32_t level, int op)
{
uint32_t sets;
uint32_t ways;
uint32_t set;
uint32_t way;
uint32_t line;
uint32_t way_shift;
uint32_t set_shift;
uint32_t val = level << 1;
/* Select by CSSELR */
CP15_SET(CSSELR, val);
/* Get cache info */
line = cp15_cache_get_info(&sets, &ways);
way_shift = 32 - ilog2(ways);
set_shift = ilog2(line);
ARM_DSB();
/* A: Log2(ways)
* B: L+S
* L: Log2(line)
* S: Log2(sets)
*
* The bits are packed as follows:
* 31 31-A B B-1 L L-1 4 3 1 0
* |---|-------------|--------|-------|-----|-|
* |Way| zeros | Set | zeros |level|0|
* |---|-------------|--------|-------|-----|-|
*/
for (way = 0; way < ways; way++)
{
for (set = 0; set < sets; set++)
{
val = level << 1;
val |= way << way_shift;
val |= set << set_shift;
switch (op)
{
case CP15_CACHE_INVALIDATE:
cp15_invalidate_dcacheline_bysetway(val);
break;
case CP15_CACHE_CLEAN:
cp15_clean_dcache_bysetway(val);
break;
case CP15_CACHE_CLEANINVALIDATE:
cp15_cleaninvalidate_dcacheline(val);
break;
default:
break;
}
}
}
ARM_ISB();
}
static void cp15_dcache_op(int op)
{
uint32_t clidr = CP15_GET(CLIDR);
@ -197,6 +125,70 @@ static void cp15_dcache_op_mva(uintptr_t start, uintptr_t end, int op)
* Public Functions
****************************************************************************/
void cp15_dcache_op_level(uint32_t level, int op)
{
uint32_t sets;
uint32_t ways;
uint32_t set;
uint32_t way;
uint32_t line;
uint32_t way_shift;
uint32_t set_shift;
uint32_t val = level << 1;
/* Select by CSSELR */
CP15_SET(CSSELR, val);
/* Get cache info */
line = cp15_cache_get_info(&sets, &ways);
way_shift = 32 - ilog2(ways);
set_shift = ilog2(line);
ARM_DSB();
/* A: Log2(ways)
* B: L+S
* L: Log2(line)
* S: Log2(sets)
*
* The bits are packed as follows:
* 31 31-A B B-1 L L-1 4 3 1 0
* |---|-------------|--------|-------|-----|-|
* |Way| zeros | Set | zeros |level|0|
* |---|-------------|--------|-------|-----|-|
*/
for (way = 0; way < ways; way++)
{
for (set = 0; set < sets; set++)
{
val = level << 1;
val |= way << way_shift;
val |= set << set_shift;
switch (op)
{
case CP15_CACHE_INVALIDATE:
cp15_invalidate_dcacheline_bysetway(val);
break;
case CP15_CACHE_CLEAN:
cp15_clean_dcache_bysetway(val);
break;
case CP15_CACHE_CLEANINVALIDATE:
cp15_cleaninvalidate_dcacheline(val);
break;
default:
break;
}
}
}
ARM_ISB();
}
void cp15_coherent_dcache(uintptr_t start, uintptr_t end)
{
cp15_dcache_op_mva(start, end, CP15_CACHE_CLEANINVALIDATE);

View File

@ -63,6 +63,10 @@
/* Cache definitions ********************************************************/
#define CP15_CACHE_INVALIDATE 0
#define CP15_CACHE_CLEAN 1
#define CP15_CACHE_CLEANINVALIDATE 2
/* L1 Memory */
#define CP15_L1_LINESIZE 32
@ -898,6 +902,23 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: cp15_dcache_op_level
*
* Description:
* Dcache operation from level
*
* Input Parameters:
* level - cache level
* op - CP15_CACHE_XX
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_dcache_op_level(uint32_t level, int op);
/****************************************************************************
* Name: cp15_coherent_dcache
*

View File

@ -28,14 +28,6 @@
#include "cp15_cacheops.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define CP15_CACHE_INVALIDATE 0
#define CP15_CACHE_CLEAN 1
#define CP15_CACHE_CLEANINVALIDATE 2
/****************************************************************************
* Private Functions
****************************************************************************/
@ -69,70 +61,6 @@ static inline uint32_t cp15_cache_get_info(uint32_t *sets, uint32_t *ways)
return (1 << ((ccsidr & 0x7) + 2)) * 4;
}
static void cp15_dcache_op_level(uint32_t level, int op)
{
uint32_t sets;
uint32_t ways;
uint32_t set;
uint32_t way;
uint32_t line;
uint32_t way_shift;
uint32_t set_shift;
uint32_t val = level << 1;
/* Select by CSSELR */
CP15_SET(CSSELR, val);
/* Get cache info */
line = cp15_cache_get_info(&sets, &ways);
way_shift = 32 - ilog2(ways);
set_shift = ilog2(line);
ARM_DSB();
/* A: Log2(ways)
* B: L+S
* L: Log2(line)
* S: Log2(sets)
*
* The bits are packed as follows:
* 31 31-A B B-1 L L-1 4 3 1 0
* |---|-------------|--------|-------|-----|-|
* |Way| zeros | Set | zeros |level|0|
* |---|-------------|--------|-------|-----|-|
*/
for (way = 0; way < ways; way++)
{
for (set = 0; set < sets; set++)
{
val = level << 1;
val |= way << way_shift;
val |= set << set_shift;
switch (op)
{
case CP15_CACHE_INVALIDATE:
cp15_invalidate_dcacheline_bysetway(val);
break;
case CP15_CACHE_CLEAN:
cp15_clean_dcache_bysetway(val);
break;
case CP15_CACHE_CLEANINVALIDATE:
cp15_cleaninvalidate_dcacheline(val);
break;
default:
break;
}
}
}
ARM_ISB();
}
static void cp15_dcache_op(int op)
{
uint32_t clidr = CP15_GET(CLIDR);
@ -197,6 +125,70 @@ static void cp15_dcache_op_mva(uintptr_t start, uintptr_t end, int op)
* Public Functions
****************************************************************************/
void cp15_dcache_op_level(uint32_t level, int op)
{
uint32_t sets;
uint32_t ways;
uint32_t set;
uint32_t way;
uint32_t line;
uint32_t way_shift;
uint32_t set_shift;
uint32_t val = level << 1;
/* Select by CSSELR */
CP15_SET(CSSELR, val);
/* Get cache info */
line = cp15_cache_get_info(&sets, &ways);
way_shift = 32 - ilog2(ways);
set_shift = ilog2(line);
ARM_DSB();
/* A: Log2(ways)
* B: L+S
* L: Log2(line)
* S: Log2(sets)
*
* The bits are packed as follows:
* 31 31-A B B-1 L L-1 4 3 1 0
* |---|-------------|--------|-------|-----|-|
* |Way| zeros | Set | zeros |level|0|
* |---|-------------|--------|-------|-----|-|
*/
for (way = 0; way < ways; way++)
{
for (set = 0; set < sets; set++)
{
val = level << 1;
val |= way << way_shift;
val |= set << set_shift;
switch (op)
{
case CP15_CACHE_INVALIDATE:
cp15_invalidate_dcacheline_bysetway(val);
break;
case CP15_CACHE_CLEAN:
cp15_clean_dcache_bysetway(val);
break;
case CP15_CACHE_CLEANINVALIDATE:
cp15_cleaninvalidate_dcacheline(val);
break;
default:
break;
}
}
}
ARM_ISB();
}
void cp15_coherent_dcache(uintptr_t start, uintptr_t end)
{
cp15_dcache_op_mva(start, end, CP15_CACHE_CLEANINVALIDATE);

View File

@ -61,6 +61,10 @@
/* Cache definitions ********************************************************/
#define CP15_CACHE_INVALIDATE 0
#define CP15_CACHE_CLEAN 1
#define CP15_CACHE_CLEANINVALIDATE 2
/* L1 Memory */
#define CP15_L1_LINESIZE 32
@ -905,6 +909,23 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: cp15_dcache_op_level
*
* Description:
* Dcache operation from level
*
* Input Parameters:
* level - cache level
* op - CP15_CACHE_XX
*
* Returned Value:
* None
*
****************************************************************************/
void cp15_dcache_op_level(uint32_t level, int op);
/****************************************************************************
* Name: cp15_coherent_dcache
*