2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / a r m / k e r n e l / i w m m x t . S
*
* XScale i W M M X t ( C o n c a n ) c o n t e x t s w i t c h i n g a n d h a n d l i n g
*
* Initial c o d e :
* Copyright ( c ) 2 0 0 3 , I n t e l C o r p o r a t i o n
*
* Full l a z y s w i t c h i n g s u p p o r t , o p t i m i z a t i o n s a n d m o r e , b y N i c o l a s P i t r e
* Copyright ( c ) 2 0 0 3 - 2 0 0 4 , M o n t a V i s t a S o f t w a r e , I n c .
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / p t r a c e . h >
# include < a s m / t h r e a d _ i n f o . h >
2005-09-09 21:08:59 +02:00
# include < a s m / a s m - o f f s e t s . h >
2014-04-22 16:14:27 +01:00
# include < a s m / a s s e m b l e r . h >
2005-04-16 15:20:36 -07:00
2014-04-24 22:54:58 +01:00
# if d e f i n e d ( C O N F I G _ C P U _ P J 4 ) | | d e f i n e d ( C O N F I G _ C P U _ P J 4 B )
2010-11-24 11:54:25 +08:00
# define P J 4 ( c o d e . . . ) c o d e
# define X S C ( c o d e . . . )
2014-04-24 22:54:58 +01:00
# elif d e f i n e d ( C O N F I G _ C P U _ M O H A W K ) | | \
defined( C O N F I G _ C P U _ X S C 3 ) | | \
defined( C O N F I G _ C P U _ X S C A L E )
2010-11-24 11:54:25 +08:00
# define P J 4 ( c o d e . . . )
# define X S C ( c o d e . . . ) c o d e
2014-04-24 22:54:58 +01:00
# else
# error " U n s u p p o r t e d i W M M X t a r c h i t e c t u r e "
2010-11-24 11:54:25 +08:00
# endif
2005-04-16 15:20:36 -07:00
# define M M X _ W R 0 ( 0 x00 )
# define M M X _ W R 1 ( 0 x08 )
# define M M X _ W R 2 ( 0 x10 )
# define M M X _ W R 3 ( 0 x18 )
# define M M X _ W R 4 ( 0 x20 )
# define M M X _ W R 5 ( 0 x28 )
# define M M X _ W R 6 ( 0 x30 )
# define M M X _ W R 7 ( 0 x38 )
# define M M X _ W R 8 ( 0 x40 )
# define M M X _ W R 9 ( 0 x48 )
# define M M X _ W R 1 0 ( 0 x50 )
# define M M X _ W R 1 1 ( 0 x58 )
# define M M X _ W R 1 2 ( 0 x60 )
# define M M X _ W R 1 3 ( 0 x68 )
# define M M X _ W R 1 4 ( 0 x70 )
# define M M X _ W R 1 5 ( 0 x78 )
# define M M X _ W C S S F ( 0 x80 )
# define M M X _ W C A S F ( 0 x84 )
# define M M X _ W C G R 0 ( 0 x88 )
# define M M X _ W C G R 1 ( 0 x8 C )
# define M M X _ W C G R 2 ( 0 x90 )
# define M M X _ W C G R 3 ( 0 x94 )
# define M M X _ S I Z E ( 0 x98 )
.text
/ *
* Lazy s w i t c h i n g o f C o n c a n c o p r o c e s s o r c o n t e x t
*
* r1 0 = s t r u c t t h r e a d _ i n f o p o i n t e r
* r9 = r e t _ f r o m _ e x c e p t i o n
* lr = u n d e f i n e d i n s t r e x i t
*
2014-04-22 16:14:29 +01:00
* called f r o m p r e f e t c h e x c e p t i o n h a n d l e r w i t h i n t e r r u p t s e n a b l e d
2005-04-16 15:20:36 -07:00
* /
ENTRY( i w m m x t _ t a s k _ e n a b l e )
2014-04-22 16:14:27 +01:00
inc_ p r e e m p t _ c o u n t r10 , r3
2005-04-16 15:20:36 -07:00
2010-11-24 11:54:25 +08:00
XSC( m r c p15 , 0 , r2 , c15 , c1 , 0 )
PJ4 ( m r c p15 , 0 , r2 , c1 , c0 , 2 )
@ CP0 and CP1 accessible?
XSC( t s t r2 , #0x3 )
PJ4 ( t s t r2 , #0xf )
2014-04-22 16:14:27 +01:00
bne 4 f @ if so no business here
2010-11-24 11:54:25 +08:00
@ enable access to CP0 and CP1
XSC( o r r r2 , r2 , #0x3 )
XSC( m c r p15 , 0 , r2 , c15 , c1 , 0 )
PJ4 ( o r r r2 , r2 , #0xf )
PJ4 ( m c r p15 , 0 , r2 , c1 , c0 , 2 )
2005-04-16 15:20:36 -07:00
ldr r3 , =concan_owner
add r0 , r10 , #T I _ I W M M X T _ S T A T E @ g e t t a s k C o n c a n s a v e a r e a
ldr r2 , [ s p , #60 ] @ current task pc value
ldr r1 , [ r3 ] @ get current Concan owner
str r0 , [ r3 ] @ this task now owns Concan regs
sub r2 , r2 , #4 @ adjust pc back
str r2 , [ s p , #60 ]
mrc p15 , 0 , r2 , c2 , c0 , 0
mov r2 , r2 @ cpwait
ARM: 8100/1: Fix preemption disable in iwmmxt_task_enable()
commit 431a84b1a4f7d1a0085d5b91330c5053cc8e8b12
("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
introduced macros {inc,dec}_preempt_count to iwmmxt_task_enable
to make it run with preemption disabled.
Unfortunately, other functions in iwmmxt.S also use concan_{save,dump,load}
sections located in iwmmxt_task_enable() to deal with iWMMXt coprocessor.
This causes an unbalanced preempt_count due to excessive dec_preempt_count
and destroyed return addresses in callers of concan_ labels due to a register
collision:
Linux version 3.16.0-rc3-00062-gd92a333-dirty (jef@armhf) (gcc version 4.8.3 (Debian 4.8.3-4) ) #5 PREEMPT Thu Jul 3 19:46:39 CEST 2014
CPU: ARMv7 Processor [560f5815] revision 5 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
Machine model: SolidRun CuBox
...
PJ4 iWMMXt v2 coprocessor enabled.
...
Unable to handle kernel paging request at virtual address fffffffe
pgd = bb25c000
[fffffffe] *pgd=3bfde821, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000007 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 62 Comm: startpar Not tainted 3.16.0-rc3-00062-gd92a333-dirty #5
task: bb230b80 ti: bb256000 task.ti: bb256000
PC is at 0xfffffffe
LR is at iwmmxt_task_copy+0x44/0x4c
pc : [<fffffffe>] lr : [<800130ac>] psr: 40000033
sp : bb257de8 ip : 00000013 fp : bb257ea4
r10: bb256000 r9 : fffffdfe r8 : 76e898e6
r7 : bb257ec8 r6 : bb256000 r5 : 7ea12760 r4 : 000000a0
r3 : ffffffff r2 : 00000003 r1 : bb257df8 r0 : 00000000
Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
Control: 10c5387d Table: 3b25c019 DAC: 00000015
Process startpar (pid: 62, stack limit = 0xbb256248)
This patch fixes the issue by moving concan_{save,dump,load} into separate
code sections and make iwmmxt_task_enable() call them in the same way the
other functions use concan_ symbols. The test for valid ownership is moved
to concan_save and is safe for the other user of it, iwmmxt_task_disable().
The register collision is also resolved by moving concan_ symbols as
{inc,dec}_preempt_count are now local to iwmmxt_task_enable().
Fixes: 431a84b1a4f7 ("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-14 16:23:29 +01:00
bl c o n c a n _ s a v e
2005-04-16 15:20:36 -07:00
ARM: 8100/1: Fix preemption disable in iwmmxt_task_enable()
commit 431a84b1a4f7d1a0085d5b91330c5053cc8e8b12
("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
introduced macros {inc,dec}_preempt_count to iwmmxt_task_enable
to make it run with preemption disabled.
Unfortunately, other functions in iwmmxt.S also use concan_{save,dump,load}
sections located in iwmmxt_task_enable() to deal with iWMMXt coprocessor.
This causes an unbalanced preempt_count due to excessive dec_preempt_count
and destroyed return addresses in callers of concan_ labels due to a register
collision:
Linux version 3.16.0-rc3-00062-gd92a333-dirty (jef@armhf) (gcc version 4.8.3 (Debian 4.8.3-4) ) #5 PREEMPT Thu Jul 3 19:46:39 CEST 2014
CPU: ARMv7 Processor [560f5815] revision 5 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
Machine model: SolidRun CuBox
...
PJ4 iWMMXt v2 coprocessor enabled.
...
Unable to handle kernel paging request at virtual address fffffffe
pgd = bb25c000
[fffffffe] *pgd=3bfde821, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000007 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 62 Comm: startpar Not tainted 3.16.0-rc3-00062-gd92a333-dirty #5
task: bb230b80 ti: bb256000 task.ti: bb256000
PC is at 0xfffffffe
LR is at iwmmxt_task_copy+0x44/0x4c
pc : [<fffffffe>] lr : [<800130ac>] psr: 40000033
sp : bb257de8 ip : 00000013 fp : bb257ea4
r10: bb256000 r9 : fffffdfe r8 : 76e898e6
r7 : bb257ec8 r6 : bb256000 r5 : 7ea12760 r4 : 000000a0
r3 : ffffffff r2 : 00000003 r1 : bb257df8 r0 : 00000000
Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
Control: 10c5387d Table: 3b25c019 DAC: 00000015
Process startpar (pid: 62, stack limit = 0xbb256248)
This patch fixes the issue by moving concan_{save,dump,load} into separate
code sections and make iwmmxt_task_enable() call them in the same way the
other functions use concan_ symbols. The test for valid ownership is moved
to concan_save and is safe for the other user of it, iwmmxt_task_disable().
The register collision is also resolved by moving concan_ symbols as
{inc,dec}_preempt_count are now local to iwmmxt_task_enable().
Fixes: 431a84b1a4f7 ("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-14 16:23:29 +01:00
# ifdef C O N F I G _ P R E E M P T _ C O U N T
get_ t h r e a d _ i n f o r10
# endif
4 : dec_ p r e e m p t _ c o u n t r10 , r3
2014-08-05 10:27:13 +01:00
ret r9 @ normal exit from exception
2005-04-16 15:20:36 -07:00
concan_save :
ARM: 8100/1: Fix preemption disable in iwmmxt_task_enable()
commit 431a84b1a4f7d1a0085d5b91330c5053cc8e8b12
("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
introduced macros {inc,dec}_preempt_count to iwmmxt_task_enable
to make it run with preemption disabled.
Unfortunately, other functions in iwmmxt.S also use concan_{save,dump,load}
sections located in iwmmxt_task_enable() to deal with iWMMXt coprocessor.
This causes an unbalanced preempt_count due to excessive dec_preempt_count
and destroyed return addresses in callers of concan_ labels due to a register
collision:
Linux version 3.16.0-rc3-00062-gd92a333-dirty (jef@armhf) (gcc version 4.8.3 (Debian 4.8.3-4) ) #5 PREEMPT Thu Jul 3 19:46:39 CEST 2014
CPU: ARMv7 Processor [560f5815] revision 5 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
Machine model: SolidRun CuBox
...
PJ4 iWMMXt v2 coprocessor enabled.
...
Unable to handle kernel paging request at virtual address fffffffe
pgd = bb25c000
[fffffffe] *pgd=3bfde821, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000007 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 62 Comm: startpar Not tainted 3.16.0-rc3-00062-gd92a333-dirty #5
task: bb230b80 ti: bb256000 task.ti: bb256000
PC is at 0xfffffffe
LR is at iwmmxt_task_copy+0x44/0x4c
pc : [<fffffffe>] lr : [<800130ac>] psr: 40000033
sp : bb257de8 ip : 00000013 fp : bb257ea4
r10: bb256000 r9 : fffffdfe r8 : 76e898e6
r7 : bb257ec8 r6 : bb256000 r5 : 7ea12760 r4 : 000000a0
r3 : ffffffff r2 : 00000003 r1 : bb257df8 r0 : 00000000
Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
Control: 10c5387d Table: 3b25c019 DAC: 00000015
Process startpar (pid: 62, stack limit = 0xbb256248)
This patch fixes the issue by moving concan_{save,dump,load} into separate
code sections and make iwmmxt_task_enable() call them in the same way the
other functions use concan_ symbols. The test for valid ownership is moved
to concan_save and is safe for the other user of it, iwmmxt_task_disable().
The register collision is also resolved by moving concan_ symbols as
{inc,dec}_preempt_count are now local to iwmmxt_task_enable().
Fixes: 431a84b1a4f7 ("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-14 16:23:29 +01:00
teq r1 , #0 @ test for last ownership
beq c o n c a n _ l o a d @ no owner, skip save
2005-04-16 15:20:36 -07:00
tmrc r2 , w C o n
@ CUP? wCx
tst r2 , #0x1
beq 1 f
concan_dump :
wstrw w C S S F , [ r1 , #M M X _ W C S S F ]
wstrw w C A S F , [ r1 , #M M X _ W C A S F ]
wstrw w C G R 0 , [ r1 , #M M X _ W C G R 0 ]
wstrw w C G R 1 , [ r1 , #M M X _ W C G R 1 ]
wstrw w C G R 2 , [ r1 , #M M X _ W C G R 2 ]
wstrw w C G R 3 , [ r1 , #M M X _ W C G R 3 ]
1 : @ MUP? wRn
tst r2 , #0x2
beq 2 f
wstrd w R 0 , [ r1 , #M M X _ W R 0 ]
wstrd w R 1 , [ r1 , #M M X _ W R 1 ]
wstrd w R 2 , [ r1 , #M M X _ W R 2 ]
wstrd w R 3 , [ r1 , #M M X _ W R 3 ]
wstrd w R 4 , [ r1 , #M M X _ W R 4 ]
wstrd w R 5 , [ r1 , #M M X _ W R 5 ]
wstrd w R 6 , [ r1 , #M M X _ W R 6 ]
wstrd w R 7 , [ r1 , #M M X _ W R 7 ]
wstrd w R 8 , [ r1 , #M M X _ W R 8 ]
wstrd w R 9 , [ r1 , #M M X _ W R 9 ]
wstrd w R 1 0 , [ r1 , #M M X _ W R 10 ]
wstrd w R 1 1 , [ r1 , #M M X _ W R 11 ]
wstrd w R 1 2 , [ r1 , #M M X _ W R 12 ]
wstrd w R 1 3 , [ r1 , #M M X _ W R 13 ]
wstrd w R 1 4 , [ r1 , #M M X _ W R 14 ]
wstrd w R 1 5 , [ r1 , #M M X _ W R 15 ]
2 : teq r0 , #0 @ anything to load?
2014-08-05 10:27:13 +01:00
reteq l r @ if not, return
2005-04-16 15:20:36 -07:00
concan_load :
@ Load wRn
wldrd w R 0 , [ r0 , #M M X _ W R 0 ]
wldrd w R 1 , [ r0 , #M M X _ W R 1 ]
wldrd w R 2 , [ r0 , #M M X _ W R 2 ]
wldrd w R 3 , [ r0 , #M M X _ W R 3 ]
wldrd w R 4 , [ r0 , #M M X _ W R 4 ]
wldrd w R 5 , [ r0 , #M M X _ W R 5 ]
wldrd w R 6 , [ r0 , #M M X _ W R 6 ]
wldrd w R 7 , [ r0 , #M M X _ W R 7 ]
wldrd w R 8 , [ r0 , #M M X _ W R 8 ]
wldrd w R 9 , [ r0 , #M M X _ W R 9 ]
wldrd w R 1 0 , [ r0 , #M M X _ W R 10 ]
wldrd w R 1 1 , [ r0 , #M M X _ W R 11 ]
wldrd w R 1 2 , [ r0 , #M M X _ W R 12 ]
wldrd w R 1 3 , [ r0 , #M M X _ W R 13 ]
wldrd w R 1 4 , [ r0 , #M M X _ W R 14 ]
wldrd w R 1 5 , [ r0 , #M M X _ W R 15 ]
@ Load wCx
wldrw w C S S F , [ r0 , #M M X _ W C S S F ]
wldrw w C A S F , [ r0 , #M M X _ W C A S F ]
wldrw w C G R 0 , [ r0 , #M M X _ W C G R 0 ]
wldrw w C G R 1 , [ r0 , #M M X _ W C G R 1 ]
wldrw w C G R 2 , [ r0 , #M M X _ W C G R 2 ]
wldrw w C G R 3 , [ r0 , #M M X _ W C G R 3 ]
@ clear CUP/MUP (only if r1 != 0)
teq r1 , #0
mov r2 , #0
2014-08-05 10:27:13 +01:00
reteq l r
2014-04-22 16:14:27 +01:00
ARM: 8100/1: Fix preemption disable in iwmmxt_task_enable()
commit 431a84b1a4f7d1a0085d5b91330c5053cc8e8b12
("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
introduced macros {inc,dec}_preempt_count to iwmmxt_task_enable
to make it run with preemption disabled.
Unfortunately, other functions in iwmmxt.S also use concan_{save,dump,load}
sections located in iwmmxt_task_enable() to deal with iWMMXt coprocessor.
This causes an unbalanced preempt_count due to excessive dec_preempt_count
and destroyed return addresses in callers of concan_ labels due to a register
collision:
Linux version 3.16.0-rc3-00062-gd92a333-dirty (jef@armhf) (gcc version 4.8.3 (Debian 4.8.3-4) ) #5 PREEMPT Thu Jul 3 19:46:39 CEST 2014
CPU: ARMv7 Processor [560f5815] revision 5 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
Machine model: SolidRun CuBox
...
PJ4 iWMMXt v2 coprocessor enabled.
...
Unable to handle kernel paging request at virtual address fffffffe
pgd = bb25c000
[fffffffe] *pgd=3bfde821, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000007 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 62 Comm: startpar Not tainted 3.16.0-rc3-00062-gd92a333-dirty #5
task: bb230b80 ti: bb256000 task.ti: bb256000
PC is at 0xfffffffe
LR is at iwmmxt_task_copy+0x44/0x4c
pc : [<fffffffe>] lr : [<800130ac>] psr: 40000033
sp : bb257de8 ip : 00000013 fp : bb257ea4
r10: bb256000 r9 : fffffdfe r8 : 76e898e6
r7 : bb257ec8 r6 : bb256000 r5 : 7ea12760 r4 : 000000a0
r3 : ffffffff r2 : 00000003 r1 : bb257df8 r0 : 00000000
Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
Control: 10c5387d Table: 3b25c019 DAC: 00000015
Process startpar (pid: 62, stack limit = 0xbb256248)
This patch fixes the issue by moving concan_{save,dump,load} into separate
code sections and make iwmmxt_task_enable() call them in the same way the
other functions use concan_ symbols. The test for valid ownership is moved
to concan_save and is safe for the other user of it, iwmmxt_task_disable().
The register collision is also resolved by moving concan_ symbols as
{inc,dec}_preempt_count are now local to iwmmxt_task_enable().
Fixes: 431a84b1a4f7 ("ARM: 8034/1: Disable preemption in iwmmxt_task_enable()")
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-14 16:23:29 +01:00
tmcr w C o n , r2
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
/ *
* Back u p C o n c a n r e g s t o s a v e a r e a a n d d i s a b l e a c c e s s t o t h e m
* ( mainly f o r g d b o r s l e e p m o d e u s a g e )
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r o f t a r g e t t a s k o r N U L L f o r a n y
* /
ENTRY( i w m m x t _ t a s k _ d i s a b l e )
stmfd s p ! , { r4 , l r }
mrs i p , c p s r
orr r2 , i p , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , r2
ldr r3 , =concan_owner
add r2 , r0 , #T I _ I W M M X T _ S T A T E @ g e t t a s k C o n c a n s a v e a r e a
ldr r1 , [ r3 ] @ get current Concan owner
teq r1 , #0 @ any current owner?
beq 1 f @ no: quit
teq r0 , #0 @ any owner?
teqne r1 , r2 @ or specified one?
bne 1 f @ no: quit
2010-11-24 11:54:25 +08:00
@ enable access to CP0 and CP1
XSC( m r c p15 , 0 , r4 , c15 , c1 , 0 )
ARM: pxa: fix logic error in PJ4 iWMMXt handling
This got added in:
commit ef6c84454f8567d4968c210d7d194fb711ed3739
Author: Haojian Zhuang <haojian.zhuang@marvell.com>
Date: Wed Nov 24 11:54:25 2010 +0800
ARM: pxa: add iwmmx support for PJ4
which does:
- mrc p15, 0, r2, c15, c1, 0
- orr r2, r2, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r2, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r2, c15, c1, 0)
+ XSC(orr r2, r2, #0x3)
+ XSC(mcr p15, 0, r2, c15, c1, 0)
but then later does:
- mrc p15, 0, r4, c15, c1, 0
- orr r4, r4, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r4, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r4, c15, c1, 0)
+ XSC(orr r4, r4, #0xf)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
Signed-off-by: Lennert Buytenhek <buytenh@laptop.org>
Acked-by Haojian <haojian.zhuang@gmail.com>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
2011-08-11 09:56:06 +08:00
XSC( o r r r4 , r4 , #0x3 )
2010-11-24 11:54:25 +08:00
XSC( m c r p15 , 0 , r4 , c15 , c1 , 0 )
PJ4 ( m r c p15 , 0 , r4 , c1 , c0 , 2 )
ARM: pxa: fix logic error in PJ4 iWMMXt handling
This got added in:
commit ef6c84454f8567d4968c210d7d194fb711ed3739
Author: Haojian Zhuang <haojian.zhuang@marvell.com>
Date: Wed Nov 24 11:54:25 2010 +0800
ARM: pxa: add iwmmx support for PJ4
which does:
- mrc p15, 0, r2, c15, c1, 0
- orr r2, r2, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r2, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r2, c15, c1, 0)
+ XSC(orr r2, r2, #0x3)
+ XSC(mcr p15, 0, r2, c15, c1, 0)
but then later does:
- mrc p15, 0, r4, c15, c1, 0
- orr r4, r4, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r4, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r4, c15, c1, 0)
+ XSC(orr r4, r4, #0xf)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
Signed-off-by: Lennert Buytenhek <buytenh@laptop.org>
Acked-by Haojian <haojian.zhuang@gmail.com>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
2011-08-11 09:56:06 +08:00
PJ4 ( o r r r4 , r4 , #0xf )
2010-11-24 11:54:25 +08:00
PJ4 ( m c r p15 , 0 , r4 , c1 , c0 , 2 )
2005-04-16 15:20:36 -07:00
mov r0 , #0 @ nothing to load
str r0 , [ r3 ] @ no more current owner
mrc p15 , 0 , r2 , c2 , c0 , 0
mov r2 , r2 @ cpwait
bl c o n c a n _ s a v e
2010-11-24 11:54:25 +08:00
@ disable access to CP0 and CP1
XSC( b i c r4 , r4 , #0x3 )
XSC( m c r p15 , 0 , r4 , c15 , c1 , 0 )
PJ4 ( b i c r4 , r4 , #0xf )
PJ4 ( m c r p15 , 0 , r4 , c1 , c0 , 2 )
2005-04-16 15:20:36 -07:00
mrc p15 , 0 , r2 , c2 , c0 , 0
mov r2 , r2 @ cpwait
1 : msr c p s r _ c , i p @ restore interrupt mode
ldmfd s p ! , { r4 , p c }
/ *
* Copy C o n c a n s t a t e t o g i v e n m e m o r y a d d r e s s
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r o f t a r g e t t a s k
* r1 = m e m o r y a d d r e s s w h e r e t o s t o r e C o n c a n s t a t e
*
* this i s c a l l e d m a i n l y i n t h e c r e a t i o n o f s i g n a l s t a c k f r a m e s
* /
ENTRY( i w m m x t _ t a s k _ c o p y )
mrs i p , c p s r
orr r2 , i p , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , r2
ldr r3 , =concan_owner
add r2 , r0 , #T I _ I W M M X T _ S T A T E @ g e t t a s k C o n c a n s a v e a r e a
ldr r3 , [ r3 ] @ get current Concan owner
teq r2 , r3 @ does this task own it...
beq 1 f
@ current Concan values are in the task save area
msr c p s r _ c , i p @ restore interrupt mode
mov r0 , r1
mov r1 , r2
mov r2 , #M M X _ S I Z E
b m e m c p y
1 : @ this task owns Concan regs -- grab a copy from there
mov r0 , #0 @ nothing to load
mov r2 , #3 @ save all regs
mov r3 , l r @ preserve return address
bl c o n c a n _ d u m p
msr c p s r _ c , i p @ restore interrupt mode
2014-06-30 16:29:12 +01:00
ret r3
2005-04-16 15:20:36 -07:00
/ *
* Restore C o n c a n s t a t e f r o m g i v e n m e m o r y a d d r e s s
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r o f t a r g e t t a s k
* r1 = m e m o r y a d d r e s s w h e r e t o g e t C o n c a n s t a t e f r o m
*
* this i s u s e d t o r e s t o r e C o n c a n s t a t e w h e n u n w i n d i n g a s i g n a l s t a c k f r a m e
* /
ENTRY( i w m m x t _ t a s k _ r e s t o r e )
mrs i p , c p s r
orr r2 , i p , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , r2
ldr r3 , =concan_owner
add r2 , r0 , #T I _ I W M M X T _ S T A T E @ g e t t a s k C o n c a n s a v e a r e a
ldr r3 , [ r3 ] @ get current Concan owner
bic r2 , r2 , #0x7 @ 64-bit alignment
teq r2 , r3 @ does this task own it...
beq 1 f
@ this task doesn't own Concan regs -- use its save area
msr c p s r _ c , i p @ restore interrupt mode
mov r0 , r2
mov r2 , #M M X _ S I Z E
b m e m c p y
1 : @ this task owns Concan regs -- load them directly
mov r0 , r1
mov r1 , #0 @ don't clear CUP/MUP
mov r3 , l r @ preserve return address
bl c o n c a n _ l o a d
msr c p s r _ c , i p @ restore interrupt mode
2014-06-30 16:29:12 +01:00
ret r3
2005-04-16 15:20:36 -07:00
/ *
* Concan h a n d l i n g o n t a s k s w i t c h
*
2006-07-01 19:56:48 +01:00
* r0 = n e x t t h r e a d _ i n f o p o i n t e r
2005-04-16 15:20:36 -07:00
*
2006-07-01 19:56:48 +01:00
* Called o n l y f r o m t h e i w m m x t n o t i f i e r w i t h t a s k p r e e m p t i o n d i s a b l e d .
2005-04-16 15:20:36 -07:00
* /
ENTRY( i w m m x t _ t a s k _ s w i t c h )
2010-11-24 11:54:25 +08:00
XSC( m r c p15 , 0 , r1 , c15 , c1 , 0 )
PJ4 ( m r c p15 , 0 , r1 , c1 , c0 , 2 )
@ CP0 and CP1 accessible?
XSC( t s t r1 , #0x3 )
PJ4 ( t s t r1 , #0xf )
2005-04-16 15:20:36 -07:00
bne 1 f @ yes: block them for next task
2006-07-01 19:56:48 +01:00
ldr r2 , =concan_owner
add r3 , r0 , #T I _ I W M M X T _ S T A T E @ g e t n e x t t a s k C o n c a n s a v e a r e a
ldr r2 , [ r2 ] @ get current Concan owner
teq r2 , r3 @ next task owns it?
2014-06-30 16:29:12 +01:00
retne l r @ no: leave Concan disabled
2005-04-16 15:20:36 -07:00
ARM: pxa: fix logic error in PJ4 iWMMXt handling
This got added in:
commit ef6c84454f8567d4968c210d7d194fb711ed3739
Author: Haojian Zhuang <haojian.zhuang@marvell.com>
Date: Wed Nov 24 11:54:25 2010 +0800
ARM: pxa: add iwmmx support for PJ4
which does:
- mrc p15, 0, r2, c15, c1, 0
- orr r2, r2, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r2, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r2, c15, c1, 0)
+ XSC(orr r2, r2, #0x3)
+ XSC(mcr p15, 0, r2, c15, c1, 0)
but then later does:
- mrc p15, 0, r4, c15, c1, 0
- orr r4, r4, #0x3 @ enable access to CP0 and CP1
- mcr p15, 0, r4, c15, c1, 0
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r4, c15, c1, 0)
+ XSC(orr r4, r4, #0xf)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
Signed-off-by: Lennert Buytenhek <buytenh@laptop.org>
Acked-by Haojian <haojian.zhuang@gmail.com>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
2011-08-11 09:56:06 +08:00
1 : @ flip Concan access
2010-11-24 11:54:25 +08:00
XSC( e o r r1 , r1 , #0x3 )
XSC( m c r p15 , 0 , r1 , c15 , c1 , 0 )
PJ4 ( e o r r1 , r1 , #0xf )
PJ4 ( m c r p15 , 0 , r1 , c1 , c0 , 2 )
2005-04-16 15:20:36 -07:00
2006-07-01 19:56:48 +01:00
mrc p15 , 0 , r1 , c2 , c0 , 0
sub p c , l r , r1 , l s r #32 @ cpwait and return
2005-04-16 15:20:36 -07:00
/ *
* Remove C o n c a n o w n e r s h i p o f g i v e n t a s k
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r
* /
ENTRY( i w m m x t _ t a s k _ r e l e a s e )
mrs r2 , c p s r
orr i p , r2 , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , i p
ldr r3 , =concan_owner
add r0 , r0 , #T I _ I W M M X T _ S T A T E @ g e t t a s k C o n c a n s a v e a r e a
ldr r1 , [ r3 ] @ get current Concan owner
eors r0 , r0 , r1 @ if equal...
streq r0 , [ r3 ] @ then clear ownership
msr c p s r _ c , r2 @ restore interrupts
2014-06-30 16:29:12 +01:00
ret l r
2005-04-16 15:20:36 -07:00
.data
concan_owner :
.word 0