xref: /openbmc/u-boot/arch/arm/cpu/armv7/cache_v7_asm.S (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */
2c09d2905SHans de Goede
3c09d2905SHans de Goede#include <config.h>
4c09d2905SHans de Goede#include <linux/linkage.h>
5c09d2905SHans de Goede#include <linux/sizes.h>
6c09d2905SHans de Goede#include <asm/system.h>
7c09d2905SHans de Goede
83a649407STom Rini#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
9c09d2905SHans de Goede#define ARM(x...)
10c09d2905SHans de Goede#define THUMB(x...)	x
11c09d2905SHans de Goede#else
12c09d2905SHans de Goede#define ARM(x...)	x
13c09d2905SHans de Goede#define THUMB(x...)
14c09d2905SHans de Goede#endif
15c09d2905SHans de Goede
16c09d2905SHans de Goede/*
17c09d2905SHans de Goede *	v7_flush_dcache_all()
18c09d2905SHans de Goede *
19c09d2905SHans de Goede *	Flush the whole D-cache.
20c09d2905SHans de Goede *
21c09d2905SHans de Goede *	Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
22c09d2905SHans de Goede *
23c09d2905SHans de Goede *	Note: copied from arch/arm/mm/cache-v7.S of Linux 4.4
24c09d2905SHans de Goede */
25c09d2905SHans de GoedeENTRY(__v7_flush_dcache_all)
26c09d2905SHans de Goede	dmb					@ ensure ordering with previous memory accesses
27c09d2905SHans de Goede	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
28c09d2905SHans de Goede	mov	r3, r0, lsr #23			@ move LoC into position
29c09d2905SHans de Goede	ands	r3, r3, #7 << 1			@ extract LoC*2 from clidr
30c09d2905SHans de Goede	beq	finished			@ if loc is 0, then no need to clean
31c09d2905SHans de Goedestart_flush_levels:
32c09d2905SHans de Goede	mov	r10, #0				@ start clean at cache level 0
33c09d2905SHans de Goedeflush_levels:
34c09d2905SHans de Goede	add	r2, r10, r10, lsr #1		@ work out 3x current cache level
35c09d2905SHans de Goede	mov	r1, r0, lsr r2			@ extract cache type bits from clidr
36c09d2905SHans de Goede	and	r1, r1, #7			@ mask of the bits for current cache only
37c09d2905SHans de Goede	cmp	r1, #2				@ see what cache we have at this level
38c09d2905SHans de Goede	blt	skip				@ skip if no cache, or just i-cache
39c09d2905SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
40c09d2905SHans de Goede	isb					@ isb to sych the new cssr&csidr
41c09d2905SHans de Goede	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
42c09d2905SHans de Goede	and	r2, r1, #7			@ extract the length of the cache lines
43c09d2905SHans de Goede	add	r2, r2, #4			@ add 4 (line length offset)
44c09d2905SHans de Goede	movw	r4, #0x3ff
45c09d2905SHans de Goede	ands	r4, r4, r1, lsr #3		@ find maximum number on the way size
46c09d2905SHans de Goede	clz	r5, r4				@ find bit position of way size increment
47c09d2905SHans de Goede	movw	r7, #0x7fff
48c09d2905SHans de Goede	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
49c09d2905SHans de Goedeloop1:
50c09d2905SHans de Goede	mov	r9, r7				@ create working copy of max index
51c09d2905SHans de Goedeloop2:
52c09d2905SHans de Goede ARM(	orr	r11, r10, r4, lsl r5	)	@ factor way and cache number into r11
53c09d2905SHans de Goede THUMB(	lsl	r6, r4, r5		)
54c09d2905SHans de Goede THUMB(	orr	r11, r10, r6		)	@ factor way and cache number into r11
55c09d2905SHans de Goede ARM(	orr	r11, r11, r9, lsl r2	)	@ factor index number into r11
56c09d2905SHans de Goede THUMB(	lsl	r6, r9, r2		)
57c09d2905SHans de Goede THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
58c09d2905SHans de Goede	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
59c09d2905SHans de Goede	subs	r9, r9, #1			@ decrement the index
60c09d2905SHans de Goede	bge	loop2
61c09d2905SHans de Goede	subs	r4, r4, #1			@ decrement the way
62c09d2905SHans de Goede	bge	loop1
63c09d2905SHans de Goedeskip:
64c09d2905SHans de Goede	add	r10, r10, #2			@ increment cache number
65c09d2905SHans de Goede	cmp	r3, r10
66c09d2905SHans de Goede	bgt	flush_levels
67c09d2905SHans de Goedefinished:
68c09d2905SHans de Goede	mov	r10, #0				@ swith back to cache level 0
69c09d2905SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
70c09d2905SHans de Goede	dsb	st
71c09d2905SHans de Goede	isb
72c09d2905SHans de Goede	bx	lr
73c09d2905SHans de GoedeENDPROC(__v7_flush_dcache_all)
74c09d2905SHans de Goede
75c09d2905SHans de GoedeENTRY(v7_flush_dcache_all)
76c09d2905SHans de Goede ARM(	stmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
77c09d2905SHans de Goede THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
78c09d2905SHans de Goede	bl	__v7_flush_dcache_all
79c09d2905SHans de Goede ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
80c09d2905SHans de Goede THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
81c09d2905SHans de Goede	bx	lr
82c09d2905SHans de GoedeENDPROC(v7_flush_dcache_all)
83df120142SHans de Goede
84df120142SHans de Goede/*
85df120142SHans de Goede *	v7_invalidate_dcache_all()
86df120142SHans de Goede *
87df120142SHans de Goede *	Invalidate the whole D-cache.
88df120142SHans de Goede *
89df120142SHans de Goede *	Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
90df120142SHans de Goede *
91df120142SHans de Goede *	Note: copied from __v7_flush_dcache_all above with
92df120142SHans de Goede *	mcr     p15, 0, r11, c7, c14, 2
93df120142SHans de Goede *	Replaced with:
94df120142SHans de Goede *	mcr     p15, 0, r11, c7, c6, 2
95df120142SHans de Goede */
96df120142SHans de GoedeENTRY(__v7_invalidate_dcache_all)
97df120142SHans de Goede	dmb					@ ensure ordering with previous memory accesses
98df120142SHans de Goede	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
99df120142SHans de Goede	mov	r3, r0, lsr #23			@ move LoC into position
100df120142SHans de Goede	ands	r3, r3, #7 << 1			@ extract LoC*2 from clidr
101df120142SHans de Goede	beq	inval_finished			@ if loc is 0, then no need to clean
102df120142SHans de Goede	mov	r10, #0				@ start clean at cache level 0
103df120142SHans de Goedeinval_levels:
104df120142SHans de Goede	add	r2, r10, r10, lsr #1		@ work out 3x current cache level
105df120142SHans de Goede	mov	r1, r0, lsr r2			@ extract cache type bits from clidr
106df120142SHans de Goede	and	r1, r1, #7			@ mask of the bits for current cache only
107df120142SHans de Goede	cmp	r1, #2				@ see what cache we have at this level
108df120142SHans de Goede	blt	inval_skip			@ skip if no cache, or just i-cache
109df120142SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
110df120142SHans de Goede	isb					@ isb to sych the new cssr&csidr
111df120142SHans de Goede	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
112df120142SHans de Goede	and	r2, r1, #7			@ extract the length of the cache lines
113df120142SHans de Goede	add	r2, r2, #4			@ add 4 (line length offset)
114df120142SHans de Goede	movw	r4, #0x3ff
115df120142SHans de Goede	ands	r4, r4, r1, lsr #3		@ find maximum number on the way size
116df120142SHans de Goede	clz	r5, r4				@ find bit position of way size increment
117df120142SHans de Goede	movw	r7, #0x7fff
118df120142SHans de Goede	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
119df120142SHans de Goedeinval_loop1:
120df120142SHans de Goede	mov	r9, r7				@ create working copy of max index
121df120142SHans de Goedeinval_loop2:
122df120142SHans de Goede ARM(	orr	r11, r10, r4, lsl r5	)	@ factor way and cache number into r11
123df120142SHans de Goede THUMB(	lsl	r6, r4, r5		)
124df120142SHans de Goede THUMB(	orr	r11, r10, r6		)	@ factor way and cache number into r11
125df120142SHans de Goede ARM(	orr	r11, r11, r9, lsl r2	)	@ factor index number into r11
126df120142SHans de Goede THUMB(	lsl	r6, r9, r2		)
127df120142SHans de Goede THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
128df120142SHans de Goede	mcr	p15, 0, r11, c7, c6, 2		@ invalidate by set/way
129df120142SHans de Goede	subs	r9, r9, #1			@ decrement the index
130df120142SHans de Goede	bge	inval_loop2
131df120142SHans de Goede	subs	r4, r4, #1			@ decrement the way
132df120142SHans de Goede	bge	inval_loop1
133df120142SHans de Goedeinval_skip:
134df120142SHans de Goede	add	r10, r10, #2			@ increment cache number
135df120142SHans de Goede	cmp	r3, r10
136df120142SHans de Goede	bgt	inval_levels
137df120142SHans de Goedeinval_finished:
138df120142SHans de Goede	mov	r10, #0				@ swith back to cache level 0
139df120142SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
140df120142SHans de Goede	dsb	st
141df120142SHans de Goede	isb
142df120142SHans de Goede	bx	lr
143df120142SHans de GoedeENDPROC(__v7_invalidate_dcache_all)
144df120142SHans de Goede
145df120142SHans de GoedeENTRY(v7_invalidate_dcache_all)
146df120142SHans de Goede ARM(	stmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
147df120142SHans de Goede THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
148df120142SHans de Goede	bl	__v7_invalidate_dcache_all
149df120142SHans de Goede ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
150df120142SHans de Goede THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
151df120142SHans de Goede	bx	lr
152df120142SHans de GoedeENDPROC(v7_invalidate_dcache_all)
153