mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
ARCv2: SLC: provide a line based flush routine for debugging
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
parent
9f82e90a66
commit
ae0b63d97d
2 changed files with 55 additions and 1 deletions
|
@ -96,6 +96,8 @@ extern unsigned long perip_base, perip_end;
|
||||||
#define ARC_REG_SLC_CTRL 0x903
|
#define ARC_REG_SLC_CTRL 0x903
|
||||||
#define ARC_REG_SLC_FLUSH 0x904
|
#define ARC_REG_SLC_FLUSH 0x904
|
||||||
#define ARC_REG_SLC_INVALIDATE 0x905
|
#define ARC_REG_SLC_INVALIDATE 0x905
|
||||||
|
#define ARC_AUX_SLC_IVDL 0x910
|
||||||
|
#define ARC_AUX_SLC_FLDL 0x912
|
||||||
#define ARC_REG_SLC_RGN_START 0x914
|
#define ARC_REG_SLC_RGN_START 0x914
|
||||||
#define ARC_REG_SLC_RGN_START1 0x915
|
#define ARC_REG_SLC_RGN_START1 0x915
|
||||||
#define ARC_REG_SLC_RGN_END 0x916
|
#define ARC_REG_SLC_RGN_END 0x916
|
||||||
|
|
|
@ -652,7 +652,7 @@ static void __ic_line_inv_vaddr(phys_addr_t paddr, unsigned long vaddr,
|
||||||
|
|
||||||
#endif /* CONFIG_ARC_HAS_ICACHE */
|
#endif /* CONFIG_ARC_HAS_ICACHE */
|
||||||
|
|
||||||
noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
|
noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ISA_ARCV2
|
#ifdef CONFIG_ISA_ARCV2
|
||||||
/*
|
/*
|
||||||
|
@ -715,6 +715,58 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_ISA_ARCV2
|
||||||
|
/*
|
||||||
|
* SLC is shared between all cores and concurrent aux operations from
|
||||||
|
* multiple cores need to be serialized using a spinlock
|
||||||
|
* A concurrent operation can be silently ignored and/or the old/new
|
||||||
|
* operation can remain incomplete forever (lockup in SLC_CTRL_BUSY loop
|
||||||
|
* below)
|
||||||
|
*/
|
||||||
|
static DEFINE_SPINLOCK(lock);
|
||||||
|
|
||||||
|
const unsigned long SLC_LINE_MASK = ~(l2_line_sz - 1);
|
||||||
|
unsigned int ctrl, cmd;
|
||||||
|
unsigned long flags;
|
||||||
|
int num_lines;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&lock, flags);
|
||||||
|
|
||||||
|
ctrl = read_aux_reg(ARC_REG_SLC_CTRL);
|
||||||
|
|
||||||
|
/* Don't rely on default value of IM bit */
|
||||||
|
if (!(op & OP_FLUSH)) /* i.e. OP_INV */
|
||||||
|
ctrl &= ~SLC_CTRL_IM; /* clear IM: Disable flush before Inv */
|
||||||
|
else
|
||||||
|
ctrl |= SLC_CTRL_IM;
|
||||||
|
|
||||||
|
write_aux_reg(ARC_REG_SLC_CTRL, ctrl);
|
||||||
|
|
||||||
|
cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;
|
||||||
|
|
||||||
|
sz += paddr & ~SLC_LINE_MASK;
|
||||||
|
paddr &= SLC_LINE_MASK;
|
||||||
|
|
||||||
|
num_lines = DIV_ROUND_UP(sz, l2_line_sz);
|
||||||
|
|
||||||
|
while (num_lines-- > 0) {
|
||||||
|
write_aux_reg(cmd, paddr);
|
||||||
|
paddr += l2_line_sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
|
||||||
|
read_aux_reg(ARC_REG_SLC_CTRL);
|
||||||
|
|
||||||
|
while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&lock, flags);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define slc_op(paddr, sz, op) slc_op_rgn(paddr, sz, op)
|
||||||
|
|
||||||
noinline static void slc_entire_op(const int op)
|
noinline static void slc_entire_op(const int op)
|
||||||
{
|
{
|
||||||
unsigned int ctrl, r = ARC_REG_SLC_CTRL;
|
unsigned int ctrl, r = ARC_REG_SLC_CTRL;
|
||||||
|
|
Loading…
Reference in a new issue