2019-06-04 10:11:33 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / a r m / m m / c a c h e - v6 . S
*
* Copyright ( C ) 2 0 0 1 D e e p B l u e S o l u t i o n s L t d .
*
* This i s t h e " s h e l l " o f t h e A R M v6 p r o c e s s o r s u p p o r t .
* /
# include < l i n u x / l i n k a g e . h >
# include < l i n u x / i n i t . h >
# include < a s m / a s s e m b l e r . h >
2012-04-27 13:08:53 +01:00
# include < a s m / e r r n o . h >
2009-10-06 17:57:09 +01:00
# include < a s m / u n w i n d . h >
2005-04-16 15:20:36 -07:00
# include " p r o c - m a c r o s . S "
# define H A R V A R D _ C A C H E
# define C A C H E _ L I N E _ S I Z E 3 2
# define D _ C A C H E _ L I N E _ S I Z E 3 2
2005-09-30 16:09:17 +01:00
# define B T B _ F L U S H _ S I Z E 8
2005-04-16 15:20:36 -07:00
ARM: 9263/1: use .arch directives instead of assembler command line flags
Similar to commit a6c30873ee4a ("ARM: 8989/1: use .fpu assembler
directives instead of assembler arguments").
GCC and GNU binutils support setting the "sub arch" via -march=,
-Wa,-march, target function attribute, and .arch assembler directive.
Clang was missing support for -Wa,-march=, but this was implemented in
clang-13.
The behavior of both GCC and Clang is to
prefer -Wa,-march= over -march= for assembler and assembler-with-cpp
sources, but Clang will warn about the -march= being unused.
clang: warning: argument unused during compilation: '-march=armv6k'
[-Wunused-command-line-argument]
Since most assembler is non-conditionally assembled with one sub arch
(modulo arch/arm/delay-loop.S which conditionally is assembled as armv4
based on CONFIG_ARCH_RPC, and arch/arm/mach-at91/pm-suspend.S which is
conditionally assembled as armv7-a based on CONFIG_CPU_V7), prefer the
.arch assembler directive.
Add a few more instances found in compile testing as found by Arnd and
Nathan.
Link: https://github.com/llvm/llvm-project/commit/1d51c699b9e2ebc5bcfdbe85c74cc871426333d4
Link: https://bugs.llvm.org/show_bug.cgi?id=48894
Link: https://github.com/ClangBuiltLinux/linux/issues/1195
Link: https://github.com/ClangBuiltLinux/linux/issues/1315
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Suggested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
2022-10-24 20:44:41 +01:00
.arch armv6
2009-04-30 17:06:03 +01:00
/ *
2010-09-21 17:16:40 +01:00
* v6 _ f l u s h _ i c a c h e _ a l l ( )
*
* Flush t h e w h o l e I - c a c h e .
2009-04-30 17:06:03 +01:00
*
2010-09-21 17:16:40 +01:00
* ARM1 1 3 6 e r r a t u m 4 1 1 9 2 0 - I n v a l i d a t e I n s t r u c t i o n C a c h e o p e r a t i o n c a n f a i l .
* This e r r a t u m i s p r e s e n t i n 1 1 3 6 , 1 1 5 6 a n d 1 1 7 6 . I t d o e s n o t a f f e c t t h e
* MPCore.
*
* Registers :
* r0 - s e t t o 0
* r1 - c o r r u p t e d
2009-04-30 17:06:03 +01:00
* /
2010-09-21 17:16:40 +01:00
ENTRY( v6 _ f l u s h _ i c a c h e _ a l l )
2009-04-30 17:06:03 +01:00
mov r0 , #0
2010-09-21 17:16:40 +01:00
# ifdef C O N F I G _ A R M _ E R R A T A _ 4 1 1 9 2 0
2009-04-30 17:06:03 +01:00
mrs r1 , c p s r
cpsid i f a @ disable interrupts
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate entire I-cache
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate entire I-cache
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate entire I-cache
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate entire I-cache
msr c p s r _ c x , r1 @ restore interrupts
.rept 11 @ ARM Ltd recommends at least
nop @ 11 NOPs
.endr
2010-09-21 17:16:40 +01:00
# else
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate I-cache
2009-04-30 17:06:03 +01:00
# endif
2014-06-30 16:29:12 +01:00
ret l r
2010-09-21 17:16:40 +01:00
ENDPROC( v6 _ f l u s h _ i c a c h e _ a l l )
2009-04-30 17:06:03 +01:00
2005-04-16 15:20:36 -07:00
/ *
* v6 _ f l u s h _ c a c h e _ a l l ( )
*
* Flush t h e e n t i r e c a c h e .
*
* It i s a s s u m e d t h a t :
* /
ENTRY( v6 _ f l u s h _ k e r n _ c a c h e _ a l l )
mov r0 , #0
# ifdef H A R V A R D _ C A C H E
mcr p15 , 0 , r0 , c7 , c14 , 0 @ D cache clean+invalidate
2009-04-30 17:06:03 +01:00
# ifndef C O N F I G _ A R M _ E R R A T A _ 4 1 1 9 2 0
2005-04-16 15:20:36 -07:00
mcr p15 , 0 , r0 , c7 , c5 , 0 @ I+BTB cache invalidate
2009-04-30 17:06:03 +01:00
# else
2010-09-21 17:16:40 +01:00
b v6 _ f l u s h _ i c a c h e _ a l l
2009-04-30 17:06:03 +01:00
# endif
2005-04-16 15:20:36 -07:00
# else
mcr p15 , 0 , r0 , c7 , c15 , 0 @ Cache clean+invalidate
# endif
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
/ *
* v6 _ f l u s h _ c a c h e _ a l l ( )
*
* Flush a l l T L B e n t r i e s i n a p a r t i c u l a r a d d r e s s s p a c e
*
* - mm - m m _ s t r u c t d e s c r i b i n g a d d r e s s s p a c e
* /
ENTRY( v6 _ f l u s h _ u s e r _ c a c h e _ a l l )
/*FALLTHROUGH*/
/ *
* v6 _ f l u s h _ c a c h e _ r a n g e ( s t a r t , e n d , f l a g s )
*
* Flush a r a n g e o f T L B e n t r i e s i n t h e s p e c i f i e d a d d r e s s s p a c e .
*
* - start - s t a r t a d d r e s s ( m a y n o t b e a l i g n e d )
* - end - e n d a d d r e s s ( e x c l u s i v e , m a y n o t b e a l i g n e d )
* - flags - v m _ a r e a _ s t r u c t f l a g s d e s c r i b i n g a d d r e s s s p a c e
*
* It i s a s s u m e d t h a t :
* - we h a v e a V I P T c a c h e .
* /
ENTRY( v6 _ f l u s h _ u s e r _ c a c h e _ r a n g e )
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
/ *
* v6 _ c o h e r e n t _ k e r n _ r a n g e ( s t a r t ,e n d )
*
* Ensure t h a t t h e I a n d D c a c h e s a r e c o h e r e n t w i t h i n s p e c i f i e d
* region. T h i s i s t y p i c a l l y u s e d w h e n c o d e h a s b e e n w r i t t e n t o
* a m e m o r y r e g i o n , a n d w i l l b e e x e c u t e d .
*
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
*
* It i s a s s u m e d t h a t :
* - the I c a c h e d o e s n o t r e a d d a t a f r o m t h e w r i t e b u f f e r
* /
ENTRY( v6 _ c o h e r e n t _ k e r n _ r a n g e )
/* FALLTHROUGH */
/ *
* v6 _ c o h e r e n t _ u s e r _ r a n g e ( s t a r t ,e n d )
*
* Ensure t h a t t h e I a n d D c a c h e s a r e c o h e r e n t w i t h i n s p e c i f i e d
* region. T h i s i s t y p i c a l l y u s e d w h e n c o d e h a s b e e n w r i t t e n t o
* a m e m o r y r e g i o n , a n d w i l l b e e x e c u t e d .
*
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
*
* It i s a s s u m e d t h a t :
* - the I c a c h e d o e s n o t r e a d d a t a f r o m t h e w r i t e b u f f e r
* /
ENTRY( v6 _ c o h e r e n t _ u s e r _ r a n g e )
2009-10-06 17:57:09 +01:00
UNWIND( . f n s t a r t )
2005-04-16 15:20:36 -07:00
# ifdef H A R V A R D _ C A C H E
2006-02-01 19:26:01 +00:00
bic r0 , r0 , #C A C H E _ L I N E _ S I Z E - 1
2009-10-06 17:57:09 +01:00
1 :
USER( m c r p15 , 0 , r0 , c7 , c10 , 1 ) @ clean D line
2006-02-01 19:26:01 +00:00
add r0 , r0 , #C A C H E _ L I N E _ S I Z E
2005-04-16 15:20:36 -07:00
cmp r0 , r1
blo 1 b
2006-02-01 19:26:01 +00:00
# endif
2005-04-16 15:20:36 -07:00
mov r0 , #0
2006-03-10 22:26:47 +00:00
# ifdef H A R V A R D _ C A C H E
2005-04-16 15:20:36 -07:00
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
2009-04-30 17:06:03 +01:00
# ifndef C O N F I G _ A R M _ E R R A T A _ 4 1 1 9 2 0
2006-03-10 22:26:47 +00:00
mcr p15 , 0 , r0 , c7 , c5 , 0 @ I+BTB cache invalidate
2009-04-30 17:06:03 +01:00
# else
2010-09-21 17:16:40 +01:00
b v6 _ f l u s h _ i c a c h e _ a l l
2009-04-30 17:06:03 +01:00
# endif
2006-03-10 22:26:47 +00:00
# else
mcr p15 , 0 , r0 , c7 , c5 , 6 @ invalidate BTB
2005-04-16 15:20:36 -07:00
# endif
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
2009-10-06 17:57:09 +01:00
/ *
* Fault h a n d l i n g f o r t h e c a c h e o p e r a t i o n a b o v e . I f t h e v i r t u a l a d d r e s s i n r0
2012-04-27 13:08:53 +01:00
* isn' t m a p p e d , f a i l w i t h - E F A U L T .
2009-10-06 17:57:09 +01:00
* /
9001 :
2012-04-27 13:08:53 +01:00
mov r0 , #- E F A U L T
2014-06-30 16:29:12 +01:00
ret l r
2009-10-06 17:57:09 +01:00
UNWIND( . f n e n d )
ENDPROC( v6 _ c o h e r e n t _ u s e r _ r a n g e )
ENDPROC( v6 _ c o h e r e n t _ k e r n _ r a n g e )
2005-04-16 15:20:36 -07:00
/ *
2009-11-26 12:56:21 +00:00
* v6 _ f l u s h _ k e r n _ d c a c h e _ a r e a ( v o i d * a d d r , s i z e _ t s i z e )
2005-04-16 15:20:36 -07:00
*
* Ensure t h a t t h e d a t a h e l d i n t h e p a g e k a d d r i s w r i t t e n b a c k
* to t h e p a g e i n q u e s t i o n .
*
2009-11-26 12:56:21 +00:00
* - addr - k e r n e l a d d r e s s
* - size - r e g i o n s i z e
2005-04-16 15:20:36 -07:00
* /
2009-11-26 12:56:21 +00:00
ENTRY( v6 _ f l u s h _ k e r n _ d c a c h e _ a r e a )
add r1 , r0 , r1
2011-05-26 11:20:19 +01:00
bic r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E - 1
2005-04-16 15:20:36 -07:00
1 :
# ifdef H A R V A R D _ C A C H E
mcr p15 , 0 , r0 , c7 , c14 , 1 @ clean & invalidate D line
# else
mcr p15 , 0 , r0 , c7 , c15 , 1 @ clean & invalidate unified line
# endif
add r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E
cmp r0 , r1
blo 1 b
# ifdef H A R V A R D _ C A C H E
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4
# endif
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
/ *
* v6 _ d m a _ i n v _ r a n g e ( s t a r t ,e n d )
*
* Invalidate t h e d a t a c a c h e w i t h i n t h e s p e c i f i e d r e g i o n ; we will
* be p e r f o r m i n g a D M A o p e r a t i o n i n t h i s r e g i o n a n d w e w a n t t o
* purge o l d d a t a i n t h e c a c h e .
*
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
2009-11-26 16:24:19 +00:00
v6_dma_inv_range :
2010-12-14 00:03:16 +01:00
# ifdef C O N F I G _ D M A _ C A C H E _ R W F O
ldrb r2 , [ r0 ] @ read for ownership
strb r2 , [ r0 ] @ write for ownership
# endif
2005-04-16 15:20:36 -07:00
tst r0 , #D _ C A C H E _ L I N E _ S I Z E - 1
bic r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E - 1
# ifdef H A R V A R D _ C A C H E
mcrne p15 , 0 , r0 , c7 , c10 , 1 @ clean D line
# else
mcrne p15 , 0 , r0 , c7 , c11 , 1 @ clean unified line
# endif
tst r1 , #D _ C A C H E _ L I N E _ S I Z E - 1
2010-12-14 00:03:16 +01:00
# ifdef C O N F I G _ D M A _ C A C H E _ R W F O
2019-02-18 00:57:38 +01:00
ldrbne r2 , [ r1 , #- 1 ] @ read for ownership
strbne r2 , [ r1 , #- 1 ] @ write for ownership
2010-12-14 00:03:16 +01:00
# endif
2005-04-16 15:20:36 -07:00
bic r1 , r1 , #D _ C A C H E _ L I N E _ S I Z E - 1
# ifdef H A R V A R D _ C A C H E
mcrne p15 , 0 , r1 , c7 , c14 , 1 @ clean & invalidate D line
# else
mcrne p15 , 0 , r1 , c7 , c15 , 1 @ clean & invalidate unified line
# endif
1 :
# ifdef H A R V A R D _ C A C H E
mcr p15 , 0 , r0 , c7 , c6 , 1 @ invalidate D line
# else
mcr p15 , 0 , r0 , c7 , c7 , 1 @ invalidate unified line
# endif
add r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E
cmp r0 , r1
2010-12-14 00:03:16 +01:00
# ifdef C O N F I G _ D M A _ C A C H E _ R W F O
ldrlo r2 , [ r0 ] @ read for ownership
strlo r2 , [ r0 ] @ write for ownership
# endif
2005-04-16 15:20:36 -07:00
blo 1 b
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
/ *
* v6 _ d m a _ c l e a n _ r a n g e ( s t a r t ,e n d )
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
2009-11-26 16:24:19 +00:00
v6_dma_clean_range :
2005-04-16 15:20:36 -07:00
bic r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E - 1
1 :
2010-06-21 15:10:07 +01:00
# ifdef C O N F I G _ D M A _ C A C H E _ R W F O
2010-05-07 16:26:24 +01:00
ldr r2 , [ r0 ] @ read for ownership
# endif
2005-04-16 15:20:36 -07:00
# ifdef H A R V A R D _ C A C H E
mcr p15 , 0 , r0 , c7 , c10 , 1 @ clean D line
# else
mcr p15 , 0 , r0 , c7 , c11 , 1 @ clean unified line
# endif
add r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E
cmp r0 , r1
blo 1 b
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
/ *
* v6 _ d m a _ f l u s h _ r a n g e ( s t a r t ,e n d )
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
ENTRY( v6 _ d m a _ f l u s h _ r a n g e )
2010-06-21 15:10:07 +01:00
# ifdef C O N F I G _ D M A _ C A C H E _ R W F O
2010-12-14 00:03:16 +01:00
ldrb r2 , [ r0 ] @ read for ownership
strb r2 , [ r0 ] @ write for ownership
2010-05-07 16:26:24 +01:00
# endif
2010-12-14 00:03:16 +01:00
bic r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E - 1
1 :
2005-04-16 15:20:36 -07:00
# ifdef H A R V A R D _ C A C H E
mcr p15 , 0 , r0 , c7 , c14 , 1 @ clean & invalidate D line
# else
mcr p15 , 0 , r0 , c7 , c15 , 1 @ clean & invalidate line
# endif
add r0 , r0 , #D _ C A C H E _ L I N E _ S I Z E
cmp r0 , r1
2010-12-14 00:03:16 +01:00
# ifdef C O N F I G _ D M A _ C A C H E _ R W F O
2019-02-18 00:57:38 +01:00
ldrblo r2 , [ r0 ] @ read for ownership
strblo r2 , [ r0 ] @ write for ownership
2010-12-14 00:03:16 +01:00
# endif
2005-04-16 15:20:36 -07:00
blo 1 b
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
2009-11-26 16:19:58 +00:00
/ *
* dma_ m a p _ a r e a ( s t a r t , s i z e , d i r )
* - start - k e r n e l v i r t u a l s t a r t a d d r e s s
* - size - s i z e o f r e g i o n
* - dir - D M A d i r e c t i o n
* /
ENTRY( v6 _ d m a _ m a p _ a r e a )
add r1 , r1 , r0
2009-10-31 16:52:16 +00:00
teq r2 , #D M A _ F R O M _ D E V I C E
beq v6 _ d m a _ i n v _ r a n g e
2010-06-21 15:10:07 +01:00
# ifndef C O N F I G _ D M A _ C A C H E _ R W F O
b v6 _ d m a _ c l e a n _ r a n g e
# else
2010-05-07 16:26:24 +01:00
teq r2 , #D M A _ T O _ D E V I C E
beq v6 _ d m a _ c l e a n _ r a n g e
b v6 _ d m a _ f l u s h _ r a n g e
2010-06-21 15:10:07 +01:00
# endif
2009-11-26 16:19:58 +00:00
ENDPROC( v6 _ d m a _ m a p _ a r e a )
/ *
* dma_ u n m a p _ a r e a ( s t a r t , s i z e , d i r )
* - start - k e r n e l v i r t u a l s t a r t a d d r e s s
* - size - s i z e o f r e g i o n
* - dir - D M A d i r e c t i o n
* /
ENTRY( v6 _ d m a _ u n m a p _ a r e a )
2010-06-21 15:10:07 +01:00
# ifndef C O N F I G _ D M A _ C A C H E _ R W F O
add r1 , r1 , r0
teq r2 , #D M A _ T O _ D E V I C E
bne v6 _ d m a _ i n v _ r a n g e
# endif
2014-06-30 16:29:12 +01:00
ret l r
2009-11-26 16:19:58 +00:00
ENDPROC( v6 _ d m a _ u n m a p _ a r e a )
2012-09-06 18:35:13 +05:30
.globl v6_flush_kern_cache_louis
.equ v6 _ f l u s h _ k e r n _ c a c h e _ l o u i s , v6 _ f l u s h _ k e r n _ c a c h e _ a l l
2005-04-16 15:20:36 -07:00
_ _ INITDATA
2011-06-23 17:16:04 +01:00
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_ c a c h e _ f u n c t i o n s v6