2009-06-16 10:30:52 +02:00
/ *
* S3 9 0 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 I B M C o r p . 2 0 0 9
*
* Author( s ) : H a n s - J o a c h i m P i c h t < h a n s @linux.vnet.ibm.com>
* Michael H o l z h e u < h o l z h e u @linux.vnet.ibm.com>
* /
2011-07-24 10:48:19 +02:00
# include < l i n u x / l i n k a g e . h >
2009-06-16 10:30:52 +02:00
# include < a s m / p a g e . h >
# include < a s m / p t r a c e . h >
2009-09-22 22:58:53 +02:00
# include < a s m / t h r e a d _ i n f o . h >
2009-06-16 10:30:52 +02:00
# include < a s m / a s m - o f f s e t s . h >
/ *
* Save r e g i s t e r c o n t e x t i n a b s o l u t e 0 l o w c o r e a n d c a l l s w s u s p _ s a v e ( ) t o
* create i n - m e m o r y k e r n e l i m a g e . T h e c o n t e x t i s s a v e d i n t h e d e s i g n a t e d
* " store s t a t u s " m e m o r y l o c a t i o n s ( s e e P O P ) .
* We r e t u r n f r o m t h i s f u n c t i o n t w i c e . T h e f i r s t t i m e d u r i n g t h e s u s p e n d t o
* disk p r o c e s s . T h e s e c o n d t i m e v i a t h e s w s u s p _ a r c h _ r e s u m e ( ) f u n c t i o n
* ( see b e l o w ) i n t h e r e s u m e p r o c e s s .
* This f u n c t i o n r u n s w i t h d i s a b l e d i n t e r r u p t s .
* /
.section .text
2011-07-24 10:48:19 +02:00
ENTRY( s w s u s p _ a r c h _ s u s p e n d )
2009-06-16 10:30:52 +02:00
stmg % r6 ,% r15 ,_ _ S F _ G P R S ( % r15 )
lgr % r1 ,% r15
aghi % r15 ,- S T A C K _ F R A M E _ O V E R H E A D
stg % r1 ,_ _ S F _ B A C K C H A I N ( % r15 )
/* Deactivate DAT */
stnsm _ _ S F _ E M P T Y ( % r15 ) ,0 x f b
/* Store prefix register on stack */
stpx _ _ S F _ E M P T Y ( % r15 )
2009-07-24 12:39:49 +02:00
/* Save prefix register contents for lowcore */
llgf % r4 ,_ _ S F _ E M P T Y ( % r15 )
2009-06-16 10:30:52 +02:00
/* Get pointer to save area */
2009-07-24 12:39:49 +02:00
lghi % r1 ,0 x10 0 0
2009-06-16 10:30:52 +02:00
2009-09-22 22:58:53 +02:00
/* Save CPU address */
2009-10-06 10:34:12 +02:00
stap _ _ L C _ C P U _ A D D R E S S ( % r0 )
2009-09-22 22:58:53 +02:00
2009-06-16 10:30:52 +02:00
/* Store registers */
mvc 0 x31 8 ( 4 ,% r1 ) ,_ _ S F _ E M P T Y ( % r15 ) / * m o v e p r e f i x t o l o w c o r e * /
stfpc 0 x31 c ( % r1 ) / * s t o r e f p u c o n t r o l * /
std 0 ,0 x20 0 ( % r1 ) / * s t o r e f0 * /
std 1 ,0 x20 8 ( % r1 ) / * s t o r e f1 * /
std 2 ,0 x21 0 ( % r1 ) / * s t o r e f2 * /
std 3 ,0 x21 8 ( % r1 ) / * s t o r e f3 * /
std 4 ,0 x22 0 ( % r1 ) / * s t o r e f4 * /
std 5 ,0 x22 8 ( % r1 ) / * s t o r e f5 * /
std 6 ,0 x23 0 ( % r1 ) / * s t o r e f6 * /
std 7 ,0 x23 8 ( % r1 ) / * s t o r e f7 * /
std 8 ,0 x24 0 ( % r1 ) / * s t o r e f8 * /
std 9 ,0 x24 8 ( % r1 ) / * s t o r e f9 * /
std 1 0 ,0 x25 0 ( % r1 ) / * s t o r e f10 * /
std 1 1 ,0 x25 8 ( % r1 ) / * s t o r e f11 * /
std 1 2 ,0 x26 0 ( % r1 ) / * s t o r e f12 * /
std 1 3 ,0 x26 8 ( % r1 ) / * s t o r e f13 * /
std 1 4 ,0 x27 0 ( % r1 ) / * s t o r e f14 * /
std 1 5 ,0 x27 8 ( % r1 ) / * s t o r e f15 * /
stam % a0 ,% a15 ,0 x34 0 ( % r1 ) / * s t o r e a c c e s s r e g i s t e r s * /
stctg % c0 ,% c15 ,0 x38 0 ( % r1 ) / * s t o r e c o n t r o l r e g i s t e r s * /
stmg % r0 ,% r15 ,0 x28 0 ( % r1 ) / * s t o r e g e n e r a l r e g i s t e r s * /
stpt 0 x32 8 ( % r1 ) / * s t o r e t i m e r * /
2009-10-06 10:34:11 +02:00
stck _ _ S F _ E M P T Y ( % r15 ) / * s t o r e c l o c k * /
2009-06-16 10:30:52 +02:00
stckc 0 x33 0 ( % r1 ) / * s t o r e c l o c k c o m p a r a t o r * /
2009-10-06 10:34:11 +02:00
/* Update cputime accounting before going to sleep */
lg % r0 ,_ _ L C _ L A S T _ U P D A T E _ T I M E R
slg % r0 ,0 x32 8 ( % r1 )
alg % r0 ,_ _ L C _ S Y S T E M _ T I M E R
stg % r0 ,_ _ L C _ S Y S T E M _ T I M E R
mvc _ _ L C _ L A S T _ U P D A T E _ T I M E R ( 8 ) ,0 x32 8 ( % r1 )
lg % r0 ,_ _ L C _ L A S T _ U P D A T E _ C L O C K
slg % r0 ,_ _ S F _ E M P T Y ( % r15 )
alg % r0 ,_ _ L C _ S T E A L _ T I M E R
stg % r0 ,_ _ L C _ S T E A L _ T I M E R
mvc _ _ L C _ L A S T _ U P D A T E _ C L O C K ( 8 ) ,_ _ S F _ E M P T Y ( % r15 )
2009-06-16 10:30:52 +02:00
/* Activate DAT */
stosm _ _ S F _ E M P T Y ( % r15 ) ,0 x04
/* Set prefix page to zero */
xc _ _ S F _ E M P T Y ( 4 ,% r15 ) ,_ _ S F _ E M P T Y ( % r15 )
spx _ _ S F _ E M P T Y ( % r15 )
2009-07-24 12:39:49 +02:00
lghi % r2 ,0
lghi % r3 ,2 * P A G E _ S I Z E
lghi % r5 ,2 * P A G E _ S I Z E
1 : mvcle % r2 ,% r4 ,0
jo 1 b
2009-06-16 10:30:52 +02:00
/* Save image */
brasl % r14 ,s w s u s p _ s a v e
/* Restore prefix register and return */
lghi % r1 ,0 x10 0 0
spx 0 x31 8 ( % r1 )
lmg % r6 ,% r15 ,S T A C K _ F R A M E _ O V E R H E A D + _ _ S F _ G P R S ( % r15 )
lghi % r2 ,0
br % r14
/ *
* Restore s a v e d m e m o r y i m a g e t o c o r r e c t p l a c e a n d r e s t o r e r e g i s t e r c o n t e x t .
* Then w e r e t u r n t o t h e f u n c t i o n t h a t c a l l e d s w s u s p _ a r c h _ s u s p e n d ( ) .
* swsusp_ a r c h _ r e s u m e ( ) r u n s w i t h d i s a b l e d i n t e r r u p t s .
* /
2011-07-24 10:48:19 +02:00
ENTRY( s w s u s p _ a r c h _ r e s u m e )
2009-06-16 10:30:52 +02:00
stmg % r6 ,% r15 ,_ _ S F _ G P R S ( % r15 )
lgr % r1 ,% r15
aghi % r15 ,- S T A C K _ F R A M E _ O V E R H E A D
stg % r1 ,_ _ S F _ B A C K C H A I N ( % r15 )
2009-09-22 22:58:44 +02:00
/* Make all free pages stable */
lghi % r2 ,1
brasl % r14 ,a r c h _ s e t _ p a g e _ s t a t e s
2009-09-22 22:58:53 +02:00
2009-06-16 10:30:52 +02:00
/* Deactivate DAT */
stnsm _ _ S F _ E M P T Y ( % r15 ) ,0 x f b
/* Set prefix page to zero */
xc _ _ S F _ E M P T Y ( 4 ,% r15 ) ,_ _ S F _ E M P T Y ( % r15 )
spx _ _ S F _ E M P T Y ( % r15 )
/* Restore saved image */
larl % r1 ,r e s t o r e _ p b l i s t
lg % r1 ,0 ( % r1 )
ltgr % r1 ,% r1
jz 2 f
0 :
lg % r2 ,8 ( % r1 )
lg % r4 ,0 ( % r1 )
2011-08-17 20:42:24 +02:00
iske % r0 ,% r4
2009-06-16 10:30:52 +02:00
lghi % r3 ,P A G E _ S I Z E
lghi % r5 ,P A G E _ S I Z E
1 :
mvcle % r2 ,% r4 ,0
jo 1 b
2011-08-17 20:42:24 +02:00
lg % r2 ,8 ( % r1 )
sske % r0 ,% r2
2009-06-16 10:30:52 +02:00
lg % r1 ,1 6 ( % r1 )
ltgr % r1 ,% r1
jnz 0 b
2 :
ptlb / * f l u s h t l b * /
2009-09-22 22:58:45 +02:00
/* Reset System */
larl % r1 ,r e s t a r t _ e n t r y
2009-09-22 22:58:53 +02:00
larl % r2 ,. L r e s t a r t _ d i a g 3 0 8 _ p s w
2009-09-22 22:58:45 +02:00
og % r1 ,0 ( % r2 )
stg % r1 ,0 ( % r0 )
2009-09-22 22:58:53 +02:00
larl % r1 ,. L n e w _ p g m _ c h e c k _ p s w
2009-09-22 22:58:45 +02:00
epsw % r2 ,% r3
stm % r2 ,% r3 ,0 ( % r1 )
mvc _ _ L C _ P G M _ N E W _ P S W ( 1 6 ,% r0 ) ,0 ( % r1 )
lghi % r0 ,0
diag % r0 ,% r0 ,0 x30 8
restart_entry :
lhi % r1 ,1
sigp % r1 ,% r0 ,0 x12
sam6 4
2009-09-22 22:58:53 +02:00
larl % r1 ,. L n e w _ p g m _ c h e c k _ p s w
2009-09-22 22:58:45 +02:00
lpswe 0 ( % r1 )
pgm_check_entry :
2009-09-22 22:58:53 +02:00
/* Switch to original suspend CPU */
larl % r1 ,. L r e s u m e _ c p u / * R e s u m e C P U a d d r e s s : r2 * /
stap 0 ( % r1 )
llgh % r2 ,0 ( % r1 )
2009-10-06 10:34:12 +02:00
llgh % r1 ,_ _ L C _ C P U _ A D D R E S S ( % r0 ) / * S u s p e n d C P U a d d r e s s : r1 * /
2009-09-22 22:58:53 +02:00
cgr % r1 ,% r2
je r e s t o r e _ r e g i s t e r s / * r1 = r2 - > n o t h i n g t o d o * /
larl % r4 ,. L r e s t a r t _ s u s p e n d _ p s w / * S e t n e w r e s t a r t P S W * /
2010-02-26 22:37:33 +01:00
mvc _ _ L C _ R S T _ N E W _ P S W ( 1 6 ,% r0 ) ,0 ( % r4 )
2009-09-22 22:58:53 +02:00
3 :
sigp % r9 ,% r1 ,_ _ S I G P _ I N I T I A L _ C P U _ R E S E T
brc 8 ,4 f / * a c c e p t e d * /
brc 2 ,3 b / * b u s y , t r y a g a i n * /
/* Suspend CPU not available -> panic */
larl % r15 ,i n i t _ t h r e a d _ u n i o n
ahi % r15 ,1 < < ( P A G E _ S H I F T + T H R E A D _ O R D E R )
larl % r2 ,. L p a n i c _ s t r i n g
larl % r3 ,_ s c l p _ p r i n t _ e a r l y
lghi % r1 ,0
sam3 1
sigp % r1 ,% r0 ,0 x12
basr % r14 ,% r3
larl % r3 ,. L d i s a b l e d _ w a i t _ 3 1
lpsw 0 ( % r3 )
4 :
/* Switch to suspend CPU */
sigp % r9 ,% r1 ,_ _ S I G P _ R E S T A R T / * s t a r t s u s p e n d C P U * /
brc 2 ,4 b / * b u s y , t r y a g a i n * /
5 :
sigp % r9 ,% r2 ,_ _ S I G P _ S T O P / * s t o p r e s u m e ( c u r r e n t ) C P U * /
2009-10-29 15:04:13 +01:00
brc 2 ,5 b / * b u s y , t r y a g a i n * /
2009-09-22 22:58:53 +02:00
6 : j 6 b
restart_suspend :
larl % r1 ,. L r e s u m e _ c p u
llgh % r2 ,0 ( % r1 )
7 :
sigp % r9 ,% r2 ,_ _ S I G P _ S E N S E / * W a i t f o r r e s u m e C P U * /
2009-10-29 15:04:14 +01:00
brc 8 ,7 b / * a c c e p t e d , s t a t u s 0 , s t i l l r u n n i n g * /
2009-09-22 22:58:53 +02:00
brc 2 ,7 b / * b u s y , t r y a g a i n * /
tmll % r9 ,0 x40 / * T e s t i f r e s u m e C P U i s s t o p p e d * /
jz 7 b
restore_registers :
2009-06-16 10:30:52 +02:00
/* Restore registers */
2009-10-06 10:34:11 +02:00
lghi % r13 ,0 x10 0 0 / * % r1 = p o i n t e r t o s a v e a r e a * /
2009-06-16 10:30:52 +02:00
2009-10-06 10:34:11 +02:00
/* Ignore time spent in suspended state. */
llgf % r1 ,0 x31 8 ( % r13 )
stck _ _ L C _ L A S T _ U P D A T E _ C L O C K ( % r1 )
2009-06-16 10:30:52 +02:00
spt 0 x32 8 ( % r13 ) / * r e p r o g r a m t i m e r * /
/ / sckc 0 x33 0 ( % r13 ) / * s e t c l o c k c o m p a r a t o r * /
lctlg % c0 ,% c15 ,0 x38 0 ( % r13 ) / * l o a d c o n t r o l r e g i s t e r s * /
lam % a0 ,% a15 ,0 x34 0 ( % r13 ) / * l o a d a c c e s s r e g i s t e r s * /
lfpc 0 x31 c ( % r13 ) / * l o a d f p u c o n t r o l * /
ld 0 ,0 x20 0 ( % r13 ) / * l o a d f0 * /
ld 1 ,0 x20 8 ( % r13 ) / * l o a d f1 * /
ld 2 ,0 x21 0 ( % r13 ) / * l o a d f2 * /
ld 3 ,0 x21 8 ( % r13 ) / * l o a d f3 * /
ld 4 ,0 x22 0 ( % r13 ) / * l o a d f4 * /
ld 5 ,0 x22 8 ( % r13 ) / * l o a d f5 * /
ld 6 ,0 x23 0 ( % r13 ) / * l o a d f6 * /
ld 7 ,0 x23 8 ( % r13 ) / * l o a d f7 * /
ld 8 ,0 x24 0 ( % r13 ) / * l o a d f8 * /
ld 9 ,0 x24 8 ( % r13 ) / * l o a d f9 * /
ld 1 0 ,0 x25 0 ( % r13 ) / * l o a d f10 * /
ld 1 1 ,0 x25 8 ( % r13 ) / * l o a d f11 * /
ld 1 2 ,0 x26 0 ( % r13 ) / * l o a d f12 * /
ld 1 3 ,0 x26 8 ( % r13 ) / * l o a d f13 * /
ld 1 4 ,0 x27 0 ( % r13 ) / * l o a d f14 * /
ld 1 5 ,0 x27 8 ( % r13 ) / * l o a d f15 * /
/* Load old stack */
lg % r15 ,0 x2 f8 ( % r13 )
/* Restore prefix register */
spx 0 x31 8 ( % r13 )
/* Activate DAT */
stosm _ _ S F _ E M P T Y ( % r15 ) ,0 x04
2009-09-22 22:58:44 +02:00
/* Make all free pages unstable */
lghi % r2 ,0
brasl % r14 ,a r c h _ s e t _ p a g e _ s t a t e s
2010-04-22 17:17:04 +02:00
/* Reinitialize the channel subsystem */
brasl % r14 ,c h a n n e l _ s u b s y s t e m _ r e i n i t
2009-06-16 10:30:52 +02:00
/* Return 0 */
lmg % r6 ,% r15 ,S T A C K _ F R A M E _ O V E R H E A D + _ _ S F _ G P R S ( % r15 )
lghi % r2 ,0
br % r14
2009-09-22 22:58:45 +02:00
2010-02-20 01:03:52 +01:00
.section .data . .nosave , " aw" ,@progbits
2009-09-22 22:58:45 +02:00
.align 8
2009-09-22 22:58:53 +02:00
.Ldisabled_wait_31 :
.long 0 x0 0 0 a00 0 0 ,0 x00 0 0 0 0 0 0
.Lpanic_string :
.asciz " Resume n o t p o s s i b l e b e c a u s e s u s p e n d C P U i s n o l o n g e r a v a i l a b l e "
.align 8
.Lrestart_diag308_psw :
2009-09-22 22:58:45 +02:00
.long 0 x0 0 0 8 0 0 0 0 ,0 x80 0 0 0 0 0 0
2009-09-22 22:58:53 +02:00
.Lrestart_suspend_psw :
.quad 0 x0 0 0 0 0 0 0 1 8 0 0 0 0 0 0 0 ,r e s t a r t _ s u s p e n d
.Lnew_pgm_check_psw :
2009-09-22 22:58:45 +02:00
.quad 0 , pgm_ c h e c k _ e n t r y
2009-09-22 22:58:53 +02:00
.Lresume_cpu :
.byte 0 , 0