1/* Copyright 2013-2014 IBM Corp. 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 * implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <asm-utils.h> 18#include <asm-offsets.h> 19#include <processor.h> 20#include <stack.h> 21 22#define OLD_BINUTILS 1 23 24 .section ".text","ax" 25 .balign 0x10 26 27.global enable_machine_check 28enable_machine_check: 29 mflr %r0 30 bcl 20,31,$+4 310: mflr %r3 32 addi %r3,%r3,(1f - 0b) 33 mtspr SPR_HSRR0,%r3 34 mfmsr %r3 35 ori %r3,%r3,MSR_ME 36 mtspr SPR_HSRR1,%r3 37 hrfid 381: mtlr %r0 39 blr 40 41.global disable_machine_check 42disable_machine_check: 43 mflr %r0 44 bcl 20,31,$+4 450: mflr %r3 46 addi %r3,%r3,(1f - 0b) 47 mtspr SPR_HSRR0,%r3 48 mfmsr %r3 49 li %r4,MSR_ME 50 andc %r3,%r3,%r4 51 mtspr SPR_HSRR1,%r3 52 hrfid 531: mtlr %r0 54 blr 55 56 /* void set_hid0(unsigned long hid0) */ 57.global set_hid0 58set_hid0: 59 sync 60 mtspr SPR_HID0,%r3 61 mfspr %r3,SPR_HID0 62 mfspr %r3,SPR_HID0 63 mfspr %r3,SPR_HID0 64 mfspr %r3,SPR_HID0 65 mfspr %r3,SPR_HID0 66 mfspr %r3,SPR_HID0 67 isync 68 blr 69 70.global __trigger_attn 71__trigger_attn: 72 sync 73 isync 74 attn 75 blr 76 77#ifdef STACK_CHECK_ENABLED 78.global _mcount 79_mcount: 80 mr %r3,%r1 81 mflr %r4 82 b __mcount_stack_check 83#endif 84 85 .global cleanup_local_tlb 86cleanup_local_tlb: 87 /* Clean the TLB */ 88 li %r3,512 89 mtctr %r3 90 li %r4,0xc00 /* IS field = 0b11 */ 91 ptesync 921: tlbiel %r4 93 addi %r4,%r4,0x1000 94 bdnz 1b 95 ptesync 96 blr 97 98 .global cleanup_global_tlb 99cleanup_global_tlb: 100 101 /* Only supported on P9 for now */ 102 mfspr %r3,SPR_PVR 103 srdi %r3,%r3,16 104 cmpwi cr0,%r3,PVR_TYPE_P9 105 beq cr0,1f 106 cmpwi cr0,%r3,PVR_TYPE_P9P 107 beq cr0,1f 108 blr 109 110 /* Sync out previous updates */ 1111: ptesync 112 113#ifndef OLD_BINUTILS 114 .machine "power9" 115#endif 116 /* Lead RB with IS=11 */ 117 li %r3,3 118 sldi %r3,%r3,10 119 li %r0,0 120 121 /* Blow up radix partition scoped translations */ 122#ifdef OLD_BINUTILS 123 .long 0x7c0b1a64 124#else 125 tlbie %r3, %r0 /* rs */, 2 /* ric */, 1 /* prs */, 1 /* r */ 126#endif 127 eieio 128 tlbsync 129 ptesync 130#ifdef OLD_BINUTILS 131 .long 0x7c091a64 132#else 133 tlbie %r3, %r0 /* rs */, 2 /* ric */, 0 /* prs */, 1 /* r */ 134#endif 135 eieio 136 tlbsync 137 ptesync 138 139 /* Blow up hash partition scoped translations */ 140#ifdef OLD_BINUTILS 141 .long 0x7c0a1a64 142#else 143 tlbie %r3, %r0 /* rs */, 2 /* ric */, 1 /* prs */, 0 /* r */ 144#endif 145 eieio 146 tlbsync 147 ptesync 148#ifdef OLD_BINUTILS 149 .long 0x7c081a64 150#else 151 tlbie %r3, %r0 /* rs */, 2 /* ric */, 0 /* prs */, 0 /* r */ 152#endif 153 eieio 154 tlbsync 155 ptesync 156 157 blr 158 159 160/* Power management instructions */ 161#define PPC_INST_NAP .long 0x4c000364 162#define PPC_INST_SLEEP .long 0x4c0003a4 163#define PPC_INST_RVWINKLE .long 0x4c0003e4 164 165#define PPC_INST_STOP .long 0x4c0002e4 166 167#define SAVE_GPR(reg,sp) std %r##reg,STACK_GPR##reg(sp) 168#define REST_GPR(reg,sp) ld %r##reg,STACK_GPR##reg(sp) 169 170pm_save_regs: 171 SAVE_GPR(2,%r1) 172 SAVE_GPR(14,%r1) 173 SAVE_GPR(15,%r1) 174 SAVE_GPR(16,%r1) 175 SAVE_GPR(17,%r1) 176 SAVE_GPR(18,%r1) 177 SAVE_GPR(19,%r1) 178 SAVE_GPR(20,%r1) 179 SAVE_GPR(21,%r1) 180 SAVE_GPR(22,%r1) 181 SAVE_GPR(23,%r1) 182 SAVE_GPR(24,%r1) 183 SAVE_GPR(25,%r1) 184 SAVE_GPR(26,%r1) 185 SAVE_GPR(27,%r1) 186 SAVE_GPR(28,%r1) 187 SAVE_GPR(29,%r1) 188 SAVE_GPR(30,%r1) 189 SAVE_GPR(31,%r1) 190 mfcr %r4 191 mfxer %r5 192 mfspr %r6,SPR_HSPRG0 193 mfspr %r7,SPR_HSPRG1 194 stw %r4,STACK_CR(%r1) 195 stw %r5,STACK_XER(%r1) 196 std %r6,STACK_GPR0(%r1) 197 std %r7,STACK_GPR1(%r1) 198 blr 199 200.global enter_p8_pm_state 201enter_p8_pm_state: 202 /* Before entering map or rvwinkle, we create a stack frame 203 * and save our non-volatile registers. 204 * 205 * We also save these SPRs: 206 * 207 * - HSPRG0 in GPR0 slot 208 * - HSPRG1 in GPR1 slot 209 * 210 * - xxx TODO: HIDs 211 * - TODO: Mask MSR:ME during the process 212 * 213 * On entry, r3 indicates: 214 * 215 * 0 = nap 216 * 1 = rvwinkle 217 */ 218 mflr %r0 219 std %r0,16(%r1) 220 stdu %r1,-STACK_FRAMESIZE(%r1) 221 222 bl pm_save_regs 223 224 /* Save stack pointer in struct cpu_thread */ 225 std %r1,CPUTHREAD_SAVE_R1(%r13) 226 227 /* Winkle or nap ? */ 228 cmpli %cr0,0,%r3,0 229 bne 1f 230 231 /* nap sequence */ 232 ptesync 2330: ld %r0,CPUTHREAD_SAVE_R1(%r13) 234 cmpd cr0,%r0,%r0 235 bne 0b 236 PPC_INST_NAP 237 b . 238 239 /* rvwinkle sequence */ 2401: ptesync 2410: ld %r0,CPUTHREAD_SAVE_R1(%r13) 242 cmpd cr0,%r0,%r0 243 bne 0b 244 PPC_INST_RVWINKLE 245 b . 246 247.global enter_p9_pm_lite_state 248enter_p9_pm_lite_state: 249 mtspr SPR_PSSCR,%r3 250 PPC_INST_STOP 251 blr 252 253.global enter_p9_pm_state 254enter_p9_pm_state: 255 mflr %r0 256 std %r0,16(%r1) 257 stdu %r1,-STACK_FRAMESIZE(%r1) 258 259 bl pm_save_regs 260 261 /* Save stack pointer in struct cpu_thread */ 262 std %r1,CPUTHREAD_SAVE_R1(%r13) 263 264 mtspr SPR_PSSCR,%r3 265 PPC_INST_STOP 266 b . 267