0001
0002 #include <linux/errno.h>
0003 #include <linux/linkage.h>
0004 #include <asm/asm-offsets.h>
0005 #include <asm/assembler.h>
0006 #include <asm/smp.h>
0007
0008 .text
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 .macro compute_mpidr_hash dst, rs0, rs1, rs2, rs3, mpidr, mask
0040 and \mpidr, \mpidr, \mask // mask out MPIDR bits
0041 and \dst, \mpidr, #0xff // mask=aff0
0042 lsr \dst ,\dst, \rs0 // dst=aff0>>rs0
0043 and \mask, \mpidr, #0xff00 // mask = aff1
0044 lsr \mask ,\mask, \rs1
0045 orr \dst, \dst, \mask // dst|=(aff1>>rs1)
0046 and \mask, \mpidr, #0xff0000 // mask = aff2
0047 lsr \mask ,\mask, \rs2
0048 orr \dst, \dst, \mask // dst|=(aff2>>rs2)
0049 and \mask, \mpidr, #0xff00000000 // mask = aff3
0050 lsr \mask ,\mask, \rs3
0051 orr \dst, \dst, \mask // dst|=(aff3>>rs3)
0052 .endm
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 SYM_FUNC_START(__cpu_suspend_enter)
0066 stp x29, lr, [x0, #SLEEP_STACK_DATA_CALLEE_REGS]
0067 stp x19, x20, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+16]
0068 stp x21, x22, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+32]
0069 stp x23, x24, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+48]
0070 stp x25, x26, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+64]
0071 stp x27, x28, [x0,#SLEEP_STACK_DATA_CALLEE_REGS+80]
0072
0073
0074 mov x2, sp
0075 str x2, [x0, #SLEEP_STACK_DATA_SYSTEM_REGS + CPU_CTX_SP]
0076
0077
0078 ldr_l x1, sleep_save_stash
0079 mrs x7, mpidr_el1
0080 adr_l x9, mpidr_hash
0081 ldr x10, [x9, #MPIDR_HASH_MASK]
0082
0083
0084
0085
0086 ldp w3, w4, [x9, #MPIDR_HASH_SHIFTS]
0087 ldp w5, w6, [x9, #(MPIDR_HASH_SHIFTS + 8)]
0088 compute_mpidr_hash x8, x3, x4, x5, x6, x7, x10
0089 add x1, x1, x8, lsl #3
0090
0091 str x0, [x1]
0092 add x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
0093 stp x29, lr, [sp, #-16]!
0094 bl cpu_do_suspend
0095 ldp x29, lr, [sp], #16
0096 mov x0, #1
0097 ret
0098 SYM_FUNC_END(__cpu_suspend_enter)
0099
0100 .pushsection ".idmap.text", "awx"
0101 SYM_CODE_START(cpu_resume)
0102 bl init_kernel_el
0103 bl finalise_el2
0104 #if VA_BITS > 48
0105 ldr_l x0, vabits_actual
0106 #endif
0107 bl __cpu_setup
0108
0109 adrp x1, swapper_pg_dir
0110 adrp x2, idmap_pg_dir
0111 bl __enable_mmu
0112 ldr x8, =_cpu_resume
0113 br x8
0114 SYM_CODE_END(cpu_resume)
0115 .ltorg
0116 .popsection
0117
0118 SYM_FUNC_START(_cpu_resume)
0119 mrs x1, mpidr_el1
0120 adr_l x8, mpidr_hash // x8 = struct mpidr_hash virt address
0121
0122
0123 ldr x2, [x8, #MPIDR_HASH_MASK]
0124 ldp w3, w4, [x8, #MPIDR_HASH_SHIFTS]
0125 ldp w5, w6, [x8, #(MPIDR_HASH_SHIFTS + 8)]
0126 compute_mpidr_hash x7, x3, x4, x5, x6, x1, x2
0127
0128
0129 ldr_l x0, sleep_save_stash
0130 ldr x0, [x0, x7, lsl #3]
0131 add x29, x0, #SLEEP_STACK_DATA_CALLEE_REGS
0132 add x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
0133
0134 ldr x2, [x0, #CPU_CTX_SP]
0135 mov sp, x2
0136
0137
0138
0139 bl cpu_do_resume
0140
0141 #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
0142 mov x0, sp
0143 bl kasan_unpoison_task_stack_below
0144 #endif
0145
0146 ldp x19, x20, [x29, #16]
0147 ldp x21, x22, [x29, #32]
0148 ldp x23, x24, [x29, #48]
0149 ldp x25, x26, [x29, #64]
0150 ldp x27, x28, [x29, #80]
0151 ldp x29, lr, [x29]
0152 mov x0, #0
0153 ret
0154 SYM_FUNC_END(_cpu_resume)