1
2
3
4
5
6
7
8
9
10
11#include <linux/threads.h>
12#include <asm/processor.h>
13#include <asm/page.h>
14#include <asm/cputable.h>
15#include <asm/thread_info.h>
16#include <asm/ppc_asm.h>
17#include <asm/asm-offsets.h>
18#include <asm/ppc-opcode.h>
19#include <asm/hw_irq.h>
20#include <asm/kvm_book3s_asm.h>
21#include <asm/opal.h>
22#include <asm/cpuidle.h>
23#include <asm/book3s/64/mmu-hash.h>
24#include <asm/mmu.h>
25
26#undef DEBUG
27
28
29
30
31
32#define _SDR1 GPR3
33#define _RPR GPR4
34#define _SPURR GPR5
35#define _PURR GPR6
36#define _TSCR GPR7
37#define _DSCR GPR8
38#define _AMOR GPR9
39#define _WORT GPR10
40#define _WORC GPR11
41#define _PTCR GPR12
42
43#define PSSCR_EC_ESL_MASK_SHIFTED (PSSCR_EC | PSSCR_ESL) >> 16
44
45 .text
46
47
48
49
50
51save_sprs_to_stack:
52
53
54
55
56BEGIN_FTR_SECTION
57 mfspr r3,SPRN_PTCR
58 std r3,_PTCR(r1)
59
60
61
62
63FTR_SECTION_ELSE
64 mfspr r3,SPRN_SDR1
65 std r3,_SDR1(r1)
66ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
67 mfspr r3,SPRN_RPR
68 std r3,_RPR(r1)
69 mfspr r3,SPRN_SPURR
70 std r3,_SPURR(r1)
71 mfspr r3,SPRN_PURR
72 std r3,_PURR(r1)
73 mfspr r3,SPRN_TSCR
74 std r3,_TSCR(r1)
75 mfspr r3,SPRN_DSCR
76 std r3,_DSCR(r1)
77 mfspr r3,SPRN_AMOR
78 std r3,_AMOR(r1)
79 mfspr r3,SPRN_WORT
80 std r3,_WORT(r1)
81 mfspr r3,SPRN_WORC
82 std r3,_WORC(r1)
83
84 blr
85
86
87
88
89
90
91
92
93
94core_idle_lock_held:
95 HMT_LOW
963: lwz r15,0(r14)
97 andi. r15,r15,PNV_CORE_IDLE_LOCK_BIT
98 bne 3b
99 HMT_MEDIUM
100 lwarx r15,0,r14
101 andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
102 bne core_idle_lock_held
103 blr
104
105
106
107
108
109
110
111
112
113
114
115
116_GLOBAL(pnv_powersave_common)
117
118
119
120
121
122
123
124 mflr r0
125 std r0,16(r1)
126 stdu r1,-INT_FRAME_SIZE(r1)
127 std r0,_LINK(r1)
128 std r0,_NIP(r1)
129
130
131 mfmsr r9
132 rldicl r9,r9,48,1
133 rotldi r9,r9,16
134 mtmsrd r9,1
135
136
137 lbz r0,PACAIRQHAPPENED(r13)
138 andi. r0,r0,~PACA_IRQ_HARD_DIS@l
139 beq 1f
140 cmpwi cr0,r4,0
141 beq 1f
142 addi r1,r1,INT_FRAME_SIZE
143 ld r0,16(r1)
144 li r3,0
145 mtlr r0
146 blr
147
1481:
149
150
151
152 li r0,PACA_IRQ_HARD_DIS
153 stb r0,PACAIRQHAPPENED(r13)
154
155
156 li r0,0
157 stb r0,PACA_NAPSTATELOST(r13)
158
159
160 SAVE_GPR(2, r1)
161 SAVE_NVGPRS(r1)
162 mfcr r4
163 std r4,_CCR(r1)
164 std r9,_MSR(r1)
165 std r1,PACAR1(r13)
166
167
168
169
170
171
172
173 LOAD_REG_IMMEDIATE(r7, MSR_IDLE)
174 li r6, MSR_RI
175 andc r6, r9, r6
176 mtmsrd r6, 1
177 mtspr SPRN_SRR0, r5
178 mtspr SPRN_SRR1, r7
179 rfid
180
181 .globl pnv_enter_arch207_idle_mode
182pnv_enter_arch207_idle_mode:
183#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
184
185 li r4,KVM_HWTHREAD_IN_IDLE
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 stb r4,HSTATE_HWTHREAD_STATE(r13)
202#endif
203 stb r3,PACA_THREAD_IDLE_STATE(r13)
204 cmpwi cr3,r3,PNV_THREAD_SLEEP
205 bge cr3,2f
206 IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)
207
2082:
209
210 lbz r7,PACA_THREAD_MASK(r13)
211 ld r14,PACA_CORE_IDLE_STATE_PTR(r13)
212lwarx_loop1:
213 lwarx r15,0,r14
214
215 andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
216 bnel core_idle_lock_held
217
218 andc r15,r15,r7
219
220 andi. r15,r15,PNV_CORE_IDLE_THREAD_BITS
221
222
223
224
225
226
227
228
229
230.global pnv_fastsleep_workaround_at_entry
231pnv_fastsleep_workaround_at_entry:
232 beq fastsleep_workaround_at_entry
233
234 stwcx. r15,0,r14
235 bne- lwarx_loop1
236 isync
237
238common_enter:
239 bgt cr3,enter_winkle
240 IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
241
242fastsleep_workaround_at_entry:
243 ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
244 stwcx. r15,0,r14
245 bne- lwarx_loop1
246 isync
247
248
249 li r3,1
250 li r4,1
251 bl opal_config_cpu_idle_state
252
253
254 li r0,0
255 lwsync
256 stw r0,0(r14)
257 b common_enter
258
259enter_winkle:
260 bl save_sprs_to_stack
261
262 IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE)
263
264
265
266
267power_enter_stop:
268#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
269
270 li r4,KVM_HWTHREAD_IN_IDLE
271
272 stb r4,HSTATE_HWTHREAD_STATE(r13)
273#endif
274
275
276
277 andis. r4,r3,PSSCR_EC_ESL_MASK_SHIFTED
278 clrldi r3,r3,60
279 bne .Lhandle_esl_ec_set
280 IDLE_STATE_ENTER_SEQ(PPC_STOP)
281 li r3,0
282 b pnv_wakeup_noloss
283
284.Lhandle_esl_ec_set:
285
286
287
288 LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state)
289 ld r4,ADDROFF(pnv_first_deep_stop_state)(r5)
290 cmpd r3,r4
291 bge .Lhandle_deep_stop
292 IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP)
293.Lhandle_deep_stop:
294
295
296
297
298
299 lbz r7,PACA_THREAD_MASK(r13)
300 ld r14,PACA_CORE_IDLE_STATE_PTR(r13)
301
302lwarx_loop_stop:
303 lwarx r15,0,r14
304 andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
305 bnel core_idle_lock_held
306 andc r15,r15,r7
307
308 stwcx. r15,0,r14
309 bne- lwarx_loop_stop
310 isync
311
312 bl save_sprs_to_stack
313
314 IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP)
315
316_GLOBAL(power7_idle)
317
318 LOAD_REG_ADDRBASE(r3,powersave_nap)
319 lwz r4,ADDROFF(powersave_nap)(r3)
320 cmpwi 0,r4,0
321 beqlr
322 li r3, 1
323
324
325_GLOBAL(power7_nap)
326 mr r4,r3
327 li r3,PNV_THREAD_NAP
328 LOAD_REG_ADDR(r5, pnv_enter_arch207_idle_mode)
329 b pnv_powersave_common
330
331
332_GLOBAL(power7_sleep)
333 li r3,PNV_THREAD_SLEEP
334 li r4,1
335 LOAD_REG_ADDR(r5, pnv_enter_arch207_idle_mode)
336 b pnv_powersave_common
337
338
339_GLOBAL(power7_winkle)
340 li r3,PNV_THREAD_WINKLE
341 li r4,1
342 LOAD_REG_ADDR(r5, pnv_enter_arch207_idle_mode)
343 b pnv_powersave_common
344
345
346#define CHECK_HMI_INTERRUPT \
347 mfspr r0,SPRN_SRR1; \
348BEGIN_FTR_SECTION_NESTED(66); \
349 rlwinm r0,r0,45-31,0xf; \
350FTR_SECTION_ELSE_NESTED(66); \
351 rlwinm r0,r0,45-31,0xe; \
352ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \
353 cmpwi r0,0xa; \
354 bne 20f; \
355 \
356 ld r2,PACATOC(r13); \
357 ld r1,PACAR1(r13); \
358 std r3,ORIG_GPR3(r1); \
359 li r3,0; \
360 bl hmi_exception_realmode; \
361 nop; \
362 ld r3,ORIG_GPR3(r1); \
36320: nop;
364
365
366
367
368
369_GLOBAL(power9_idle_stop)
370 mfspr r5,SPRN_PSSCR
371 andc r5,r5,r4
372 or r3,r3,r5
373 mtspr SPRN_PSSCR,r3
374 LOAD_REG_ADDR(r5,power_enter_stop)
375 li r4,1
376 b pnv_powersave_common
377
378
379
380
381
382
383
384
385
386_GLOBAL(pnv_restore_hyp_resource)
387BEGIN_FTR_SECTION
388 ld r2,PACATOC(r13);
389
390
391
392
393 LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state)
394 ld r4,ADDROFF(pnv_first_deep_stop_state)(r5)
395
396 mfspr r5,SPRN_PSSCR
397
398
399
400
401 rldicl r5,r5,4,60
402 cmpd cr4,r5,r4
403 bge cr4,pnv_wakeup_tb_loss
404
405
406
407
408 blr
409
410END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
411
412
413
414
415
416
417 clrldi r5,r13,63
418 clrrdi r13,r13,1
419
420
421 ld r2,PACATOC(r13);
422 cmpwi cr4,r5,1
423 mtspr SPRN_HSPRG0,r13
424
425 lbz r0,PACA_THREAD_IDLE_STATE(r13)
426 cmpwi cr2,r0,PNV_THREAD_NAP
427 bgt cr2,pnv_wakeup_tb_loss
428
429
430
431
432
433
434 bgt cr3,.
435
436 blr
437
438
439
440
441
442
443
444
445
446
447
448
449_GLOBAL(pnv_wakeup_tb_loss)
450 ld r1,PACAR1(r13)
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 li r0,1
466 stb r0,PACA_NAPSTATELOST(r13)
467
468
469
470
471
472
473
474
475
476 mflr r17
477 mfspr r16,SPRN_SRR1
478BEGIN_FTR_SECTION
479 CHECK_HMI_INTERRUPT
480END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
481
482 lbz r7,PACA_THREAD_MASK(r13)
483 ld r14,PACA_CORE_IDLE_STATE_PTR(r13)
484lwarx_loop2:
485 lwarx r15,0,r14
486 andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
487
488
489
490
491
492
493
494
495 bnel core_idle_lock_held
496
497 cmpwi cr2,r15,0
498
499
500
501
502
503
504
505
506 ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
507 stwcx. r15,0,r14
508 bne- lwarx_loop2
509 isync
510
511BEGIN_FTR_SECTION
512 lbz r4,PACA_SUBCORE_SIBLING_MASK(r13)
513 and r4,r4,r15
514 cmpwi r4,0
515
516 or r15,r15,r7
517 beq first_thread_in_subcore
518END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
519
520 or r15,r15,r7
521 beq cr2,first_thread_in_core
522
523
524 b clear_lock
525
526first_thread_in_subcore:
527
528
529
530
531 blt cr4,subcore_state_restored
532
533
534 ld r4,_SDR1(r1)
535 mtspr SPRN_SDR1,r4
536
537 ld r4,_RPR(r1)
538 mtspr SPRN_RPR,r4
539 ld r4,_AMOR(r1)
540 mtspr SPRN_AMOR,r4
541
542subcore_state_restored:
543
544
545
546
547 bne cr2,clear_lock
548
549first_thread_in_core:
550
551
552
553
554
555
556
557
558
559
560.global pnv_fastsleep_workaround_at_exit
561pnv_fastsleep_workaround_at_exit:
562 b fastsleep_workaround_at_exit
563
564timebase_resync:
565
566
567
568
569 ble cr3,clear_lock
570
571 bl opal_resync_timebase;
572
573
574
575
576 blt cr4,clear_lock
577
578
579
580
581
582
583BEGIN_FTR_SECTION
584 ld r4,_PTCR(r1)
585 mtspr SPRN_PTCR,r4
586 ld r4,_RPR(r1)
587 mtspr SPRN_RPR,r4
588END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
589
590 ld r4,_TSCR(r1)
591 mtspr SPRN_TSCR,r4
592 ld r4,_WORC(r1)
593 mtspr SPRN_WORC,r4
594
595clear_lock:
596 andi. r15,r15,PNV_CORE_IDLE_THREAD_BITS
597 lwsync
598 stw r15,0(r14)
599
600common_exit:
601
602
603
604
605
606
607 blt cr4,hypervisor_state_restored
608
609
610
611BEGIN_MMU_FTR_SECTION
612 b no_segments
613END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
614
615 ld r8,PACA_SLBSHADOWPTR(r13)
616
617 .rept SLB_NUM_BOLTED
618 li r3, SLBSHADOW_SAVEAREA
619 LDX_BE r5, r8, r3
620 addi r3, r3, 8
621 LDX_BE r6, r8, r3
622 andis. r7,r5,SLB_ESID_V@h
623 beq 1f
624 slbmte r6,r5
6251: addi r8,r8,16
626 .endr
627no_segments:
628
629
630
631 ld r4,_SPURR(r1)
632 mtspr SPRN_SPURR,r4
633 ld r4,_PURR(r1)
634 mtspr SPRN_PURR,r4
635 ld r4,_DSCR(r1)
636 mtspr SPRN_DSCR,r4
637 ld r4,_WORT(r1)
638 mtspr SPRN_WORT,r4
639
640
641 LOAD_REG_ADDR(r4, cur_cpu_spec)
642 ld r4,0(r4)
643 ld r12,CPU_SPEC_RESTORE(r4)
644#ifdef PPC64_ELF_ABI_v1
645 ld r12,0(r12)
646#endif
647 mtctr r12
648 bctrl
649
650hypervisor_state_restored:
651
652 mtspr SPRN_SRR1,r16
653 mtlr r17
654 blr
655
656
657fastsleep_workaround_at_exit:
658 li r3,1
659 li r4,0
660 bl opal_config_cpu_idle_state
661 b timebase_resync
662
663
664
665
666
667_GLOBAL(pnv_wakeup_loss)
668 ld r1,PACAR1(r13)
669BEGIN_FTR_SECTION
670 CHECK_HMI_INTERRUPT
671END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
672 REST_NVGPRS(r1)
673 REST_GPR(2, r1)
674 ld r6,_CCR(r1)
675 ld r4,_MSR(r1)
676 ld r5,_NIP(r1)
677 addi r1,r1,INT_FRAME_SIZE
678 mtcr r6
679 mtspr SPRN_SRR1,r4
680 mtspr SPRN_SRR0,r5
681 rfid
682
683
684
685
686
687_GLOBAL(pnv_wakeup_noloss)
688 lbz r0,PACA_NAPSTATELOST(r13)
689 cmpwi r0,0
690 bne pnv_wakeup_loss
691BEGIN_FTR_SECTION
692 CHECK_HMI_INTERRUPT
693END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
694 ld r1,PACAR1(r13)
695 ld r6,_CCR(r1)
696 ld r4,_MSR(r1)
697 ld r5,_NIP(r1)
698 addi r1,r1,INT_FRAME_SIZE
699 mtcr r6
700 mtspr SPRN_SRR1,r4
701 mtspr SPRN_SRR0,r5
702 rfid
703