2019-06-04 11:11:38 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2007-05-03 16:31:38 +04:00
/ *
* PowerPC 6 4 - b i t s w s u s p i m p l e m e n t a t i o n
*
* Copyright 2 0 0 6 J o h a n n e s B e r g < j o h a n n e s @sipsolutions.net>
* /
# include < l i n u x / t h r e a d s . h >
# include < a s m / p r o c e s s o r . h >
# include < a s m / p a g e . h >
# include < a s m / c p u t a b l e . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / p p c _ a s m . h >
# include < a s m / a s m - o f f s e t s . h >
2018-07-05 19:25:01 +03:00
# include < a s m / f e a t u r e - f i x u p s . h >
2007-05-03 16:31:38 +04:00
/ *
* Structure f o r s t o r i n g C P U r e g i s t e r s o n t h e s a v e a r e a .
* /
# define S L _ r1 0 x00 / * s t a c k p o i n t e r * /
# define S L _ P C 0 x08
# define S L _ M S R 0 x10
# define S L _ S D R 1 0 x18
# define S L _ X E R 0 x20
# define S L _ T B 0 x40
# define S L _ r2 0 x48
# define S L _ C R 0 x50
# define S L _ L R 0 x58
# define S L _ r12 0 x60
# define S L _ r13 0 x68
# define S L _ r14 0 x70
# define S L _ r15 0 x78
# define S L _ r16 0 x80
# define S L _ r17 0 x88
# define S L _ r18 0 x90
# define S L _ r19 0 x98
# define S L _ r20 0 x a0
# define S L _ r21 0 x a8
# define S L _ r22 0 x b0
# define S L _ r23 0 x b8
# define S L _ r24 0 x c0
# define S L _ r25 0 x c8
# define S L _ r26 0 x d0
# define S L _ r27 0 x d8
# define S L _ r28 0 x e 0
# define S L _ r29 0 x e 8
# define S L _ r30 0 x f0
# define S L _ r31 0 x f8
2013-08-08 06:06:45 +04:00
# define S L _ S P R G 1 0 x10 0
# define S L _ T C R 0 x10 8
# define S L _ S I Z E S L _ T C R + 8
2007-05-03 16:31:38 +04:00
/ * these m a c r o s r e l y o n t h e s a v e a r e a b e i n g
* pointed t o b y r11 * /
2013-08-08 06:06:45 +04:00
# define S A V E _ S P R ( r e g i s t e r ) \
mfspr r0 , S P R N _ ## r e g i s t e r ; \
std r0 , S L _ ## r e g i s t e r ( r 11 )
# define R E S T O R E _ S P R ( r e g i s t e r ) \
ld r0 , S L _ ## r e g i s t e r ( r 11 ) ;\
mtspr S P R N _ ## r e g i s t e r , r 0
2007-05-03 16:31:38 +04:00
# define S A V E _ S P E C I A L ( s p e c i a l ) \
mf## s p e c i a l r 0 ;\
std r0 , S L _ ## s p e c i a l ( r 11 )
# define R E S T O R E _ S P E C I A L ( s p e c i a l ) \
ld r0 , S L _ ## s p e c i a l ( r 11 ) ;\
mt## s p e c i a l r 0
# define S A V E _ R E G I S T E R ( r e g ) \
std r e g , S L _ ## r e g ( r 11 )
# define R E S T O R E _ R E G I S T E R ( r e g ) \
ld r e g , S L _ ## r e g ( r 11 )
/* space for storing cpu state */
.section .data
.align 5
swsusp_save_area :
.space SL_SIZE
.section .text
.align 5
_ GLOBAL( s w s u s p _ a r c h _ s u s p e n d )
2022-09-26 06:40:54 +03:00
LOAD_ R E G _ A D D R ( r11 , s w s u s p _ s a v e _ a r e a )
2007-05-03 16:31:38 +04:00
SAVE_ S P E C I A L ( L R )
SAVE_ R E G I S T E R ( r1 )
SAVE_ S P E C I A L ( C R )
SAVE_ S P E C I A L ( T B )
SAVE_ R E G I S T E R ( r2 )
SAVE_ R E G I S T E R ( r12 )
SAVE_ R E G I S T E R ( r13 )
SAVE_ R E G I S T E R ( r14 )
SAVE_ R E G I S T E R ( r15 )
SAVE_ R E G I S T E R ( r16 )
SAVE_ R E G I S T E R ( r17 )
SAVE_ R E G I S T E R ( r18 )
SAVE_ R E G I S T E R ( r19 )
SAVE_ R E G I S T E R ( r20 )
SAVE_ R E G I S T E R ( r21 )
SAVE_ R E G I S T E R ( r22 )
SAVE_ R E G I S T E R ( r23 )
SAVE_ R E G I S T E R ( r24 )
SAVE_ R E G I S T E R ( r25 )
SAVE_ R E G I S T E R ( r26 )
SAVE_ R E G I S T E R ( r27 )
SAVE_ R E G I S T E R ( r28 )
SAVE_ R E G I S T E R ( r29 )
SAVE_ R E G I S T E R ( r30 )
SAVE_ R E G I S T E R ( r31 )
SAVE_ S P E C I A L ( M S R )
SAVE_ S P E C I A L ( X E R )
2013-08-08 06:06:45 +04:00
# ifdef C O N F I G _ P P C _ B O O K 3 S _ 6 4
2013-10-30 06:25:14 +04:00
BEGIN_ F W _ F T R _ S E C T I O N
2013-08-08 06:06:45 +04:00
SAVE_ S P E C I A L ( S D R 1 )
2013-10-30 06:25:14 +04:00
END_ F W _ F T R _ S E C T I O N _ I F C L R ( F W _ F E A T U R E _ L P A R )
2013-08-08 06:06:45 +04:00
# else
SAVE_ S P R ( T C R )
/* Save SPRG1, SPRG1 be used save paca */
SAVE_ S P R ( S P R G 1 )
# endif
2007-05-03 16:31:38 +04:00
/ * we p u s h t h e s t a c k u p 1 2 8 b y t e s b u t d o n ' t s t o r e t h e
* stack p o i n t e r o n t h e s t a c k l i k e a r e a l s t a c k f r a m e * /
addi r1 ,r1 ,- 1 2 8
bl s w s u s p _ s a v e
/* restore LR */
2022-09-26 06:40:54 +03:00
LOAD_ R E G _ A D D R ( r11 , s w s u s p _ s a v e _ a r e a )
2007-05-03 16:31:38 +04:00
RESTORE_ S P E C I A L ( L R )
addi r1 ,r1 ,1 2 8
blr
/* Resume code */
_ GLOBAL( s w s u s p _ a r c h _ r e s u m e )
/* Stop pending alitvec streams and memory accesses */
BEGIN_ F T R _ S E C T I O N
2021-12-21 08:59:03 +03:00
PPC_ D S S A L L
2007-05-03 16:31:38 +04:00
END_ F T R _ S E C T I O N _ I F S E T ( C P U _ F T R _ A L T I V E C )
sync
2022-09-26 06:40:54 +03:00
LOAD_ R E G _ A D D R ( r11 , r e s t o r e _ p b l i s t )
2007-05-03 16:31:38 +04:00
ld r12 ,0 ( r12 )
cmpdi r12 ,0
beq- n o t h i n g _ t o _ c o p y
2008-09-24 08:01:09 +04:00
li r15 ,P A G E _ S I Z E > > 3
2007-05-03 16:31:38 +04:00
copyloop :
ld r13 ,p b e _ a d d r e s s ( r12 )
ld r14 ,p b e _ o r i g _ a d d r e s s ( r12 )
mtctr r15
li r10 ,0
copy_page_loop :
ldx r0 ,r10 ,r13
stdx r0 ,r10 ,r14
addi r10 ,r10 ,8
bdnz c o p y _ p a g e _ l o o p
ld r12 ,p b e _ n e x t ( r12 )
cmpdi r12 ,0
bne+ c o p y l o o p
nothing_to_copy :
2013-08-08 06:06:45 +04:00
# ifdef C O N F I G _ P P C _ B O O K 3 S _ 6 4
2007-05-03 16:31:38 +04:00
/* flush caches */
lis r3 , 0 x10
mtctr r3
li r3 , 0
ori r3 , r3 , C O N F I G _ K E R N E L _ S T A R T > > 4 8
li r0 , 4 8
sld r3 , r3 , r0
li r0 , 0
1 :
2017-08-05 20:55:11 +03:00
dcbf 0 ,r3
2007-05-03 16:31:38 +04:00
addi r3 ,r3 ,0 x20
bdnz 1 b
sync
tlbia
2013-08-08 06:06:45 +04:00
# endif
2007-05-03 16:31:38 +04:00
2022-09-26 06:40:54 +03:00
LOAD_ R E G _ A D D R ( r11 , s w s u s p _ s a v e _ a r e a )
2007-05-03 16:31:38 +04:00
RESTORE_ S P E C I A L ( C R )
/* restore timebase */
/* load saved tb */
ld r1 , S L _ T B ( r11 )
/* get upper 32 bits of it */
srdi r2 , r1 , 3 2
/* clear tb lower to avoid wrap */
li r0 , 0
mttbl r0
/* set tb upper */
mttbu r2
/* set tb lower */
mttbl r1
/* restore registers */
RESTORE_ R E G I S T E R ( r1 )
RESTORE_ R E G I S T E R ( r2 )
RESTORE_ R E G I S T E R ( r12 )
RESTORE_ R E G I S T E R ( r13 )
RESTORE_ R E G I S T E R ( r14 )
RESTORE_ R E G I S T E R ( r15 )
RESTORE_ R E G I S T E R ( r16 )
RESTORE_ R E G I S T E R ( r17 )
RESTORE_ R E G I S T E R ( r18 )
RESTORE_ R E G I S T E R ( r19 )
RESTORE_ R E G I S T E R ( r20 )
RESTORE_ R E G I S T E R ( r21 )
RESTORE_ R E G I S T E R ( r22 )
RESTORE_ R E G I S T E R ( r23 )
RESTORE_ R E G I S T E R ( r24 )
RESTORE_ R E G I S T E R ( r25 )
RESTORE_ R E G I S T E R ( r26 )
RESTORE_ R E G I S T E R ( r27 )
RESTORE_ R E G I S T E R ( r28 )
RESTORE_ R E G I S T E R ( r29 )
RESTORE_ R E G I S T E R ( r30 )
RESTORE_ R E G I S T E R ( r31 )
2013-08-08 06:06:45 +04:00
# ifdef C O N F I G _ P P C _ B O O K 3 S _ 6 4
2007-05-03 16:31:38 +04:00
/* can't use RESTORE_SPECIAL(MSR) */
ld r0 , S L _ M S R ( r11 )
mtmsrd r0 , 0
2013-10-30 06:25:14 +04:00
BEGIN_ F W _ F T R _ S E C T I O N
2007-05-03 16:31:38 +04:00
RESTORE_ S P E C I A L ( S D R 1 )
2013-10-30 06:25:14 +04:00
END_ F W _ F T R _ S E C T I O N _ I F C L R ( F W _ F E A T U R E _ L P A R )
2013-08-08 06:06:45 +04:00
# else
/* Restore SPRG1, be used to save paca */
ld r0 , S L _ S P R G 1 ( r11 )
mtsprg 1 , r0
RESTORE_ S P E C I A L ( M S R )
/* Restore TCR and clear any pending bits in TSR. */
RESTORE_ S P R ( T C R )
lis r0 , ( T S R _ E N W | T S R _ W I S | T S R _ D I S | T S R _ F I S ) @h
mtspr S P R N _ T S R , r0
/* Kick decrementer */
li r0 , 1
mtdec r0
/* Invalidate all tlbs */
bl _ t l b i l _ a l l
# endif
2007-05-03 16:31:38 +04:00
RESTORE_ S P E C I A L ( X E R )
sync
addi r1 ,r1 ,- 1 2 8
2013-08-08 06:06:45 +04:00
# ifdef C O N F I G _ P P C _ B O O K 3 S _ 6 4
2018-10-02 17:27:58 +03:00
bl s l b _ f l u s h _ a n d _ r e s t o r e _ b o l t e d
2013-08-08 06:06:45 +04:00
# endif
2007-05-03 16:31:38 +04:00
bl d o _ a f t e r _ c o p y b a c k
addi r1 ,r1 ,1 2 8
2022-09-26 06:40:54 +03:00
LOAD_ R E G _ A D D R ( r11 , s w s u s p _ s a v e _ a r e a )
2007-05-03 16:31:38 +04:00
RESTORE_ S P E C I A L ( L R )
li r3 , 0
blr