arch/arm/mm/cache-v7.S

Source file repositories/reference/linux-study-clean/arch/arm/mm/cache-v7.S

File Facts

System
Linux kernel
Corpus path
arch/arm/mm/cache-v7.S
Extension
.S
Size
12220 bytes
Lines
461
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: arch/arm
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/cfi_types.h>
#include <asm/assembler.h>
#include <asm/errno.h>
#include <asm/unwind.h>
#include <asm/hardware/cache-b15-rac.h>

#include "proc-macros.S"

.arch armv7-a

#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
.globl icache_size
	.data
	.align	2
icache_size:
	.long	64
	.text
#endif
/*
 * The secondary kernel init calls v7_flush_dcache_all before it enables
 * the L1; however, the L1 comes out of reset in an undefined state, so
 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
 * of cache lines with uninitialized data and uninitialized tags to get
 * written out to memory, which does really unpleasant things to the main
 * processor.  We fix this by performing an invalidate, rather than a
 * clean + invalidate, before jumping into the kernel.
 *
 * This function needs to be called for both secondary cores startup and
 * primary core resume procedures.
 */
ENTRY(v7_invalidate_l1)
	mov	r0, #0
	mcr	p15, 2, r0, c0, c0, 0	@ select L1 data cache in CSSELR
	isb
	mrc	p15, 1, r0, c0, c0, 0	@ read cache geometry from CCSIDR

	movw	r3, #0x3ff
	and	r3, r3, r0, lsr #3	@ 'Associativity' in CCSIDR[12:3]
	clz	r1, r3			@ WayShift
	mov	r2, #1
	mov	r3, r3, lsl r1		@ NumWays-1 shifted into bits [31:...]
	movs	r1, r2, lsl r1		@ #1 shifted left by same amount
	moveq	r1, #1			@ r1 needs value > 0 even if only 1 way

	and	r2, r0, #0x7
	add	r2, r2, #4		@ SetShift

1:	movw	ip, #0x7fff
	and	r0, ip, r0, lsr #13	@ 'NumSets' in CCSIDR[27:13]

2:	mov	ip, r0, lsl r2		@ NumSet << SetShift
	orr	ip, ip, r3		@ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
	mcr	p15, 0, ip, c7, c6, 2
	subs	r0, r0, #1		@ Set--
	bpl	2b
	subs	r3, r3, r1		@ Way--
	bcc	3f
	mrc	p15, 1, r0, c0, c0, 0	@ re-read cache geometry from CCSIDR
	b	1b
3:	dsb	st
	isb
	ret	lr
ENDPROC(v7_invalidate_l1)

/*
 *	v7_flush_icache_all()
 *
 *	Flush the whole I-cache.

Annotation

Implementation Notes