Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * PowerPC 64-bit swsusp implementation
0004  *
0005  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
0006  */
0007 
0008 #include <linux/threads.h>
0009 #include <asm/processor.h>
0010 #include <asm/page.h>
0011 #include <asm/cputable.h>
0012 #include <asm/thread_info.h>
0013 #include <asm/ppc_asm.h>
0014 #include <asm/asm-offsets.h>
0015 #include <asm/feature-fixups.h>
0016 
0017 /*
0018  * Structure for storing CPU registers on the save area.
0019  */
0020 #define SL_r1       0x00    /* stack pointer */
0021 #define SL_PC       0x08
0022 #define SL_MSR      0x10
0023 #define SL_SDR1     0x18
0024 #define SL_XER      0x20
0025 #define SL_TB       0x40
0026 #define SL_r2       0x48
0027 #define SL_CR       0x50
0028 #define SL_LR       0x58
0029 #define SL_r12      0x60
0030 #define SL_r13      0x68
0031 #define SL_r14      0x70
0032 #define SL_r15      0x78
0033 #define SL_r16      0x80
0034 #define SL_r17      0x88
0035 #define SL_r18      0x90
0036 #define SL_r19      0x98
0037 #define SL_r20      0xa0
0038 #define SL_r21      0xa8
0039 #define SL_r22      0xb0
0040 #define SL_r23      0xb8
0041 #define SL_r24      0xc0
0042 #define SL_r25      0xc8
0043 #define SL_r26      0xd0
0044 #define SL_r27      0xd8
0045 #define SL_r28      0xe0
0046 #define SL_r29      0xe8
0047 #define SL_r30      0xf0
0048 #define SL_r31      0xf8
0049 #define SL_SPRG1    0x100
0050 #define SL_TCR      0x108
0051 #define SL_SIZE     SL_TCR+8
0052 
0053 /* these macros rely on the save area being
0054  * pointed to by r11 */
0055 
0056 #define SAVE_SPR(register)      \
0057     mfspr   r0, SPRN_##register ;\
0058     std r0, SL_##register(r11)
0059 #define RESTORE_SPR(register)       \
0060     ld  r0, SL_##register(r11)  ;\
0061     mtspr   SPRN_##register, r0
0062 #define SAVE_SPECIAL(special)       \
0063     mf##special r0      ;\
0064     std r0, SL_##special(r11)
0065 #define RESTORE_SPECIAL(special)    \
0066     ld  r0, SL_##special(r11)   ;\
0067     mt##special r0
0068 #define SAVE_REGISTER(reg)      \
0069     std reg, SL_##reg(r11)
0070 #define RESTORE_REGISTER(reg)       \
0071     ld  reg, SL_##reg(r11)
0072 
0073 /* space for storing cpu state */
0074     .section .data
0075     .align  5
0076 swsusp_save_area:
0077     .space SL_SIZE
0078 
0079     .section ".toc","aw"
0080 swsusp_save_area_ptr:
0081     .tc swsusp_save_area[TC],swsusp_save_area
0082 restore_pblist_ptr:
0083     .tc restore_pblist[TC],restore_pblist
0084 
0085     .section .text
0086     .align  5
0087 _GLOBAL(swsusp_arch_suspend)
0088     ld  r11,swsusp_save_area_ptr@toc(r2)
0089     SAVE_SPECIAL(LR)
0090     SAVE_REGISTER(r1)
0091     SAVE_SPECIAL(CR)
0092     SAVE_SPECIAL(TB)
0093     SAVE_REGISTER(r2)
0094     SAVE_REGISTER(r12)
0095     SAVE_REGISTER(r13)
0096     SAVE_REGISTER(r14)
0097     SAVE_REGISTER(r15)
0098     SAVE_REGISTER(r16)
0099     SAVE_REGISTER(r17)
0100     SAVE_REGISTER(r18)
0101     SAVE_REGISTER(r19)
0102     SAVE_REGISTER(r20)
0103     SAVE_REGISTER(r21)
0104     SAVE_REGISTER(r22)
0105     SAVE_REGISTER(r23)
0106     SAVE_REGISTER(r24)
0107     SAVE_REGISTER(r25)
0108     SAVE_REGISTER(r26)
0109     SAVE_REGISTER(r27)
0110     SAVE_REGISTER(r28)
0111     SAVE_REGISTER(r29)
0112     SAVE_REGISTER(r30)
0113     SAVE_REGISTER(r31)
0114     SAVE_SPECIAL(MSR)
0115     SAVE_SPECIAL(XER)
0116 #ifdef CONFIG_PPC_BOOK3S_64
0117 BEGIN_FW_FTR_SECTION
0118     SAVE_SPECIAL(SDR1)
0119 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
0120 #else
0121     SAVE_SPR(TCR)
0122 
0123     /* Save SPRG1, SPRG1 be used save paca */
0124     SAVE_SPR(SPRG1)
0125 #endif
0126 
0127     /* we push the stack up 128 bytes but don't store the
0128      * stack pointer on the stack like a real stackframe */
0129     addi    r1,r1,-128
0130 
0131     bl swsusp_save
0132 
0133     /* restore LR */
0134     ld  r11,swsusp_save_area_ptr@toc(r2)
0135     RESTORE_SPECIAL(LR)
0136     addi    r1,r1,128
0137 
0138     blr
0139 
0140 /* Resume code */
0141 _GLOBAL(swsusp_arch_resume)
0142     /* Stop pending alitvec streams and memory accesses */
0143 BEGIN_FTR_SECTION
0144     PPC_DSSALL
0145 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
0146     sync
0147 
0148     ld  r12,restore_pblist_ptr@toc(r2)
0149     ld  r12,0(r12)
0150 
0151     cmpdi   r12,0
0152     beq-    nothing_to_copy
0153     li  r15,PAGE_SIZE>>3
0154 copyloop:
0155     ld  r13,pbe_address(r12)
0156     ld  r14,pbe_orig_address(r12)
0157 
0158     mtctr   r15
0159     li  r10,0
0160 copy_page_loop:
0161     ldx r0,r10,r13
0162     stdx    r0,r10,r14
0163     addi    r10,r10,8
0164     bdnz copy_page_loop
0165 
0166     ld  r12,pbe_next(r12)
0167     cmpdi   r12,0
0168     bne+    copyloop
0169 nothing_to_copy:
0170 
0171 #ifdef CONFIG_PPC_BOOK3S_64
0172     /* flush caches */
0173     lis r3, 0x10
0174     mtctr   r3
0175     li  r3, 0
0176     ori r3, r3, CONFIG_KERNEL_START>>48
0177     li  r0, 48
0178     sld r3, r3, r0
0179     li  r0, 0
0180 1:
0181     dcbf    0,r3
0182     addi    r3,r3,0x20
0183     bdnz    1b
0184 
0185     sync
0186 
0187     tlbia
0188 #endif
0189 
0190     ld  r11,swsusp_save_area_ptr@toc(r2)
0191 
0192     RESTORE_SPECIAL(CR)
0193 
0194     /* restore timebase */
0195     /* load saved tb */
0196     ld  r1, SL_TB(r11)
0197     /* get upper 32 bits of it */
0198     srdi    r2, r1, 32
0199     /* clear tb lower to avoid wrap */
0200     li  r0, 0
0201     mttbl   r0
0202     /* set tb upper */
0203     mttbu   r2
0204     /* set tb lower */
0205     mttbl   r1
0206 
0207     /* restore registers */
0208     RESTORE_REGISTER(r1)
0209     RESTORE_REGISTER(r2)
0210     RESTORE_REGISTER(r12)
0211     RESTORE_REGISTER(r13)
0212     RESTORE_REGISTER(r14)
0213     RESTORE_REGISTER(r15)
0214     RESTORE_REGISTER(r16)
0215     RESTORE_REGISTER(r17)
0216     RESTORE_REGISTER(r18)
0217     RESTORE_REGISTER(r19)
0218     RESTORE_REGISTER(r20)
0219     RESTORE_REGISTER(r21)
0220     RESTORE_REGISTER(r22)
0221     RESTORE_REGISTER(r23)
0222     RESTORE_REGISTER(r24)
0223     RESTORE_REGISTER(r25)
0224     RESTORE_REGISTER(r26)
0225     RESTORE_REGISTER(r27)
0226     RESTORE_REGISTER(r28)
0227     RESTORE_REGISTER(r29)
0228     RESTORE_REGISTER(r30)
0229     RESTORE_REGISTER(r31)
0230 
0231 #ifdef CONFIG_PPC_BOOK3S_64
0232     /* can't use RESTORE_SPECIAL(MSR) */
0233     ld  r0, SL_MSR(r11)
0234     mtmsrd  r0, 0
0235 BEGIN_FW_FTR_SECTION
0236     RESTORE_SPECIAL(SDR1)
0237 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
0238 #else
0239     /* Restore SPRG1, be used to save paca */
0240     ld  r0, SL_SPRG1(r11)
0241     mtsprg  1, r0
0242 
0243     RESTORE_SPECIAL(MSR)
0244 
0245     /* Restore TCR and clear any pending bits in TSR. */
0246     RESTORE_SPR(TCR)
0247     lis r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
0248     mtspr   SPRN_TSR, r0
0249 
0250     /* Kick decrementer */
0251     li  r0, 1
0252     mtdec   r0
0253 
0254     /* Invalidate all tlbs */
0255     bl  _tlbil_all
0256 #endif
0257     RESTORE_SPECIAL(XER)
0258 
0259     sync
0260 
0261     addi    r1,r1,-128
0262 #ifdef CONFIG_PPC_BOOK3S_64
0263     bl  slb_flush_and_restore_bolted
0264 #endif
0265     bl  do_after_copyback
0266     addi    r1,r1,128
0267 
0268     ld  r11,swsusp_save_area_ptr@toc(r2)
0269     RESTORE_SPECIAL(LR)
0270 
0271     li  r3, 0
0272     blr