diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/crash.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 39 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 110 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_power4.S | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 24 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 4 |
8 files changed, 135 insertions, 61 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d06f378597bb..e96521530d21 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -118,7 +118,8 @@ int main(void) | |||
118 | DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); | 118 | DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); |
119 | DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); | 119 | DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); |
120 | DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); | 120 | DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); |
121 | DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled)); | 121 | DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); |
122 | DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); | ||
122 | DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); | 123 | DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); |
123 | DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); | 124 | DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); |
124 | DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); | 125 | DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 1af41f7616dc..89b03c8da9d2 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -111,7 +111,7 @@ void crash_ipi_callback(struct pt_regs *regs) | |||
111 | if (!cpu_online(cpu)) | 111 | if (!cpu_online(cpu)) |
112 | return; | 112 | return; |
113 | 113 | ||
114 | local_irq_disable(); | 114 | hard_irq_disable(); |
115 | if (!cpu_isset(cpu, cpus_in_crash)) | 115 | if (!cpu_isset(cpu, cpus_in_crash)) |
116 | crash_save_this_cpu(regs, cpu); | 116 | crash_save_this_cpu(regs, cpu); |
117 | cpu_set(cpu, cpus_in_crash); | 117 | cpu_set(cpu, cpus_in_crash); |
@@ -289,7 +289,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
289 | * an SMP system. | 289 | * an SMP system. |
290 | * The kernel is broken so disable interrupts. | 290 | * The kernel is broken so disable interrupts. |
291 | */ | 291 | */ |
292 | local_irq_disable(); | 292 | hard_irq_disable(); |
293 | 293 | ||
294 | for_each_irq(irq) { | 294 | for_each_irq(irq) { |
295 | struct irq_desc *desc = irq_desc + irq; | 295 | struct irq_desc *desc = irq_desc + irq; |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 748e74fcf541..efda48741b29 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -87,6 +87,10 @@ system_call_common: | |||
87 | addi r9,r1,STACK_FRAME_OVERHEAD | 87 | addi r9,r1,STACK_FRAME_OVERHEAD |
88 | ld r11,exception_marker@toc(r2) | 88 | ld r11,exception_marker@toc(r2) |
89 | std r11,-16(r9) /* "regshere" marker */ | 89 | std r11,-16(r9) /* "regshere" marker */ |
90 | li r10,1 | ||
91 | stb r10,PACASOFTIRQEN(r13) | ||
92 | stb r10,PACAHARDIRQEN(r13) | ||
93 | std r10,SOFTE(r1) | ||
90 | #ifdef CONFIG_PPC_ISERIES | 94 | #ifdef CONFIG_PPC_ISERIES |
91 | BEGIN_FW_FTR_SECTION | 95 | BEGIN_FW_FTR_SECTION |
92 | /* Hack for handling interrupts when soft-enabling on iSeries */ | 96 | /* Hack for handling interrupts when soft-enabling on iSeries */ |
@@ -94,8 +98,6 @@ BEGIN_FW_FTR_SECTION | |||
94 | andi. r10,r12,MSR_PR /* from kernel */ | 98 | andi. r10,r12,MSR_PR /* from kernel */ |
95 | crand 4*cr0+eq,4*cr1+eq,4*cr0+eq | 99 | crand 4*cr0+eq,4*cr1+eq,4*cr0+eq |
96 | beq hardware_interrupt_entry | 100 | beq hardware_interrupt_entry |
97 | lbz r10,PACAPROCENABLED(r13) | ||
98 | std r10,SOFTE(r1) | ||
99 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 101 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
100 | #endif | 102 | #endif |
101 | mfmsr r11 | 103 | mfmsr r11 |
@@ -460,9 +462,9 @@ _GLOBAL(ret_from_except_lite) | |||
460 | #endif | 462 | #endif |
461 | 463 | ||
462 | restore: | 464 | restore: |
465 | ld r5,SOFTE(r1) | ||
463 | #ifdef CONFIG_PPC_ISERIES | 466 | #ifdef CONFIG_PPC_ISERIES |
464 | BEGIN_FW_FTR_SECTION | 467 | BEGIN_FW_FTR_SECTION |
465 | ld r5,SOFTE(r1) | ||
466 | cmpdi 0,r5,0 | 468 | cmpdi 0,r5,0 |
467 | beq 4f | 469 | beq 4f |
468 | /* Check for pending interrupts (iSeries) */ | 470 | /* Check for pending interrupts (iSeries) */ |
@@ -472,16 +474,16 @@ BEGIN_FW_FTR_SECTION | |||
472 | beq+ 4f /* skip do_IRQ if no interrupts */ | 474 | beq+ 4f /* skip do_IRQ if no interrupts */ |
473 | 475 | ||
474 | li r3,0 | 476 | li r3,0 |
475 | stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */ | 477 | stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */ |
476 | ori r10,r10,MSR_EE | 478 | ori r10,r10,MSR_EE |
477 | mtmsrd r10 /* hard-enable again */ | 479 | mtmsrd r10 /* hard-enable again */ |
478 | addi r3,r1,STACK_FRAME_OVERHEAD | 480 | addi r3,r1,STACK_FRAME_OVERHEAD |
479 | bl .do_IRQ | 481 | bl .do_IRQ |
480 | b .ret_from_except_lite /* loop back and handle more */ | 482 | b .ret_from_except_lite /* loop back and handle more */ |
481 | 483 | 4: | |
482 | 4: stb r5,PACAPROCENABLED(r13) | ||
483 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 484 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
484 | #endif | 485 | #endif |
486 | stb r5,PACASOFTIRQEN(r13) | ||
485 | 487 | ||
486 | ld r3,_MSR(r1) | 488 | ld r3,_MSR(r1) |
487 | andi. r0,r3,MSR_RI | 489 | andi. r0,r3,MSR_RI |
@@ -538,25 +540,15 @@ do_work: | |||
538 | /* Check that preempt_count() == 0 and interrupts are enabled */ | 540 | /* Check that preempt_count() == 0 and interrupts are enabled */ |
539 | lwz r8,TI_PREEMPT(r9) | 541 | lwz r8,TI_PREEMPT(r9) |
540 | cmpwi cr1,r8,0 | 542 | cmpwi cr1,r8,0 |
541 | #ifdef CONFIG_PPC_ISERIES | ||
542 | BEGIN_FW_FTR_SECTION | ||
543 | ld r0,SOFTE(r1) | 543 | ld r0,SOFTE(r1) |
544 | cmpdi r0,0 | 544 | cmpdi r0,0 |
545 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
546 | #endif | ||
547 | BEGIN_FW_FTR_SECTION | ||
548 | andi. r0,r3,MSR_EE | ||
549 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | ||
550 | crandc eq,cr1*4+eq,eq | 545 | crandc eq,cr1*4+eq,eq |
551 | bne restore | 546 | bne restore |
552 | /* here we are preempting the current task */ | 547 | /* here we are preempting the current task */ |
553 | 1: | 548 | 1: |
554 | #ifdef CONFIG_PPC_ISERIES | ||
555 | BEGIN_FW_FTR_SECTION | ||
556 | li r0,1 | 549 | li r0,1 |
557 | stb r0,PACAPROCENABLED(r13) | 550 | stb r0,PACASOFTIRQEN(r13) |
558 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 551 | stb r0,PACAHARDIRQEN(r13) |
559 | #endif | ||
560 | ori r10,r10,MSR_EE | 552 | ori r10,r10,MSR_EE |
561 | mtmsrd r10,1 /* reenable interrupts */ | 553 | mtmsrd r10,1 /* reenable interrupts */ |
562 | bl .preempt_schedule | 554 | bl .preempt_schedule |
@@ -639,8 +631,7 @@ _GLOBAL(enter_rtas) | |||
639 | /* There is no way it is acceptable to get here with interrupts enabled, | 631 | /* There is no way it is acceptable to get here with interrupts enabled, |
640 | * check it with the asm equivalent of WARN_ON | 632 | * check it with the asm equivalent of WARN_ON |
641 | */ | 633 | */ |
642 | mfmsr r6 | 634 | lbz r0,PACASOFTIRQEN(r13) |
643 | andi. r0,r6,MSR_EE | ||
644 | 1: tdnei r0,0 | 635 | 1: tdnei r0,0 |
645 | .section __bug_table,"a" | 636 | .section __bug_table,"a" |
646 | .llong 1b,__LINE__ + 0x1000000, 1f, 2f | 637 | .llong 1b,__LINE__ + 0x1000000, 1f, 2f |
@@ -649,7 +640,13 @@ _GLOBAL(enter_rtas) | |||
649 | 1: .asciz __FILE__ | 640 | 1: .asciz __FILE__ |
650 | 2: .asciz "enter_rtas" | 641 | 2: .asciz "enter_rtas" |
651 | .previous | 642 | .previous |
652 | 643 | ||
644 | /* Hard-disable interrupts */ | ||
645 | mfmsr r6 | ||
646 | rldicl r7,r6,48,1 | ||
647 | rotldi r7,r7,16 | ||
648 | mtmsrd r7,1 | ||
649 | |||
653 | /* Unfortunately, the stack pointer and the MSR are also clobbered, | 650 | /* Unfortunately, the stack pointer and the MSR are also clobbered, |
654 | * so they are saved in the PACA which allows us to restore | 651 | * so they are saved in the PACA which allows us to restore |
655 | * our original state after RTAS returns. | 652 | * our original state after RTAS returns. |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 645c7f10fb28..c93d9f35a121 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -35,9 +35,7 @@ | |||
35 | #include <asm/thread_info.h> | 35 | #include <asm/thread_info.h> |
36 | #include <asm/firmware.h> | 36 | #include <asm/firmware.h> |
37 | 37 | ||
38 | #ifdef CONFIG_PPC_ISERIES | ||
39 | #define DO_SOFT_DISABLE | 38 | #define DO_SOFT_DISABLE |
40 | #endif | ||
41 | 39 | ||
42 | /* | 40 | /* |
43 | * We layout physical memory as follows: | 41 | * We layout physical memory as follows: |
@@ -308,7 +306,9 @@ exception_marker: | |||
308 | std r9,_LINK(r1); \ | 306 | std r9,_LINK(r1); \ |
309 | mfctr r10; /* save CTR in stackframe */ \ | 307 | mfctr r10; /* save CTR in stackframe */ \ |
310 | std r10,_CTR(r1); \ | 308 | std r10,_CTR(r1); \ |
309 | lbz r10,PACASOFTIRQEN(r13); \ | ||
311 | mfspr r11,SPRN_XER; /* save XER in stackframe */ \ | 310 | mfspr r11,SPRN_XER; /* save XER in stackframe */ \ |
311 | std r10,SOFTE(r1); \ | ||
312 | std r11,_XER(r1); \ | 312 | std r11,_XER(r1); \ |
313 | li r9,(n)+1; \ | 313 | li r9,(n)+1; \ |
314 | std r9,_TRAP(r1); /* set trap number */ \ | 314 | std r9,_TRAP(r1); /* set trap number */ \ |
@@ -343,6 +343,34 @@ label##_pSeries: \ | |||
343 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) | 343 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) |
344 | 344 | ||
345 | 345 | ||
346 | #define MASKABLE_EXCEPTION_PSERIES(n, label) \ | ||
347 | . = n; \ | ||
348 | .globl label##_pSeries; \ | ||
349 | label##_pSeries: \ | ||
350 | HMT_MEDIUM; \ | ||
351 | mtspr SPRN_SPRG1,r13; /* save r13 */ \ | ||
352 | mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ | ||
353 | std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ | ||
354 | std r10,PACA_EXGEN+EX_R10(r13); \ | ||
355 | lbz r10,PACASOFTIRQEN(r13); \ | ||
356 | mfcr r9; \ | ||
357 | cmpwi r10,0; \ | ||
358 | beq masked_interrupt; \ | ||
359 | mfspr r10,SPRN_SPRG1; \ | ||
360 | std r10,PACA_EXGEN+EX_R13(r13); \ | ||
361 | std r11,PACA_EXGEN+EX_R11(r13); \ | ||
362 | std r12,PACA_EXGEN+EX_R12(r13); \ | ||
363 | clrrdi r12,r13,32; /* get high part of &label */ \ | ||
364 | mfmsr r10; \ | ||
365 | mfspr r11,SPRN_SRR0; /* save SRR0 */ \ | ||
366 | LOAD_HANDLER(r12,label##_common) \ | ||
367 | ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ | ||
368 | mtspr SPRN_SRR0,r12; \ | ||
369 | mfspr r12,SPRN_SRR1; /* and SRR1 */ \ | ||
370 | mtspr SPRN_SRR1,r10; \ | ||
371 | rfid; \ | ||
372 | b . /* prevent speculative execution */ | ||
373 | |||
346 | #define STD_EXCEPTION_ISERIES(n, label, area) \ | 374 | #define STD_EXCEPTION_ISERIES(n, label, area) \ |
347 | .globl label##_iSeries; \ | 375 | .globl label##_iSeries; \ |
348 | label##_iSeries: \ | 376 | label##_iSeries: \ |
@@ -358,40 +386,32 @@ label##_iSeries: \ | |||
358 | HMT_MEDIUM; \ | 386 | HMT_MEDIUM; \ |
359 | mtspr SPRN_SPRG1,r13; /* save r13 */ \ | 387 | mtspr SPRN_SPRG1,r13; /* save r13 */ \ |
360 | EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ | 388 | EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ |
361 | lbz r10,PACAPROCENABLED(r13); \ | 389 | lbz r10,PACASOFTIRQEN(r13); \ |
362 | cmpwi 0,r10,0; \ | 390 | cmpwi 0,r10,0; \ |
363 | beq- label##_iSeries_masked; \ | 391 | beq- label##_iSeries_masked; \ |
364 | EXCEPTION_PROLOG_ISERIES_2; \ | 392 | EXCEPTION_PROLOG_ISERIES_2; \ |
365 | b label##_common; \ | 393 | b label##_common; \ |
366 | 394 | ||
367 | #ifdef DO_SOFT_DISABLE | 395 | #ifdef CONFIG_PPC_ISERIES |
368 | #define DISABLE_INTS \ | 396 | #define DISABLE_INTS \ |
369 | BEGIN_FW_FTR_SECTION; \ | ||
370 | lbz r10,PACAPROCENABLED(r13); \ | ||
371 | li r11,0; \ | 397 | li r11,0; \ |
372 | std r10,SOFTE(r1); \ | 398 | stb r11,PACASOFTIRQEN(r13); \ |
399 | BEGIN_FW_FTR_SECTION; \ | ||
400 | stb r11,PACAHARDIRQEN(r13); \ | ||
401 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ | ||
402 | BEGIN_FW_FTR_SECTION; \ | ||
373 | mfmsr r10; \ | 403 | mfmsr r10; \ |
374 | stb r11,PACAPROCENABLED(r13); \ | ||
375 | ori r10,r10,MSR_EE; \ | 404 | ori r10,r10,MSR_EE; \ |
376 | mtmsrd r10,1; \ | 405 | mtmsrd r10,1; \ |
377 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 406 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
378 | 407 | ||
379 | #define ENABLE_INTS \ | 408 | #else |
380 | BEGIN_FW_FTR_SECTION; \ | 409 | #define DISABLE_INTS \ |
381 | lbz r10,PACAPROCENABLED(r13); \ | 410 | li r11,0; \ |
382 | mfmsr r11; \ | 411 | stb r11,PACASOFTIRQEN(r13); \ |
383 | std r10,SOFTE(r1); \ | 412 | stb r11,PACAHARDIRQEN(r13) |
384 | ori r11,r11,MSR_EE; \ | ||
385 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \ | ||
386 | BEGIN_FW_FTR_SECTION; \ | ||
387 | ld r12,_MSR(r1); \ | ||
388 | mfmsr r11; \ | ||
389 | rlwimi r11,r12,0,MSR_EE; \ | ||
390 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ | ||
391 | mtmsrd r11,1 | ||
392 | 413 | ||
393 | #else /* hard enable/disable interrupts */ | 414 | #endif /* CONFIG_PPC_ISERIES */ |
394 | #define DISABLE_INTS | ||
395 | 415 | ||
396 | #define ENABLE_INTS \ | 416 | #define ENABLE_INTS \ |
397 | ld r12,_MSR(r1); \ | 417 | ld r12,_MSR(r1); \ |
@@ -399,8 +419,6 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ | |||
399 | rlwimi r11,r12,0,MSR_EE; \ | 419 | rlwimi r11,r12,0,MSR_EE; \ |
400 | mtmsrd r11,1 | 420 | mtmsrd r11,1 |
401 | 421 | ||
402 | #endif | ||
403 | |||
404 | #define STD_EXCEPTION_COMMON(trap, label, hdlr) \ | 422 | #define STD_EXCEPTION_COMMON(trap, label, hdlr) \ |
405 | .align 7; \ | 423 | .align 7; \ |
406 | .globl label##_common; \ | 424 | .globl label##_common; \ |
@@ -541,11 +559,11 @@ instruction_access_slb_pSeries: | |||
541 | mfspr r12,SPRN_SRR1 /* and SRR1 */ | 559 | mfspr r12,SPRN_SRR1 /* and SRR1 */ |
542 | b .slb_miss_realmode /* Rel. branch works in real mode */ | 560 | b .slb_miss_realmode /* Rel. branch works in real mode */ |
543 | 561 | ||
544 | STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) | 562 | MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt) |
545 | STD_EXCEPTION_PSERIES(0x600, alignment) | 563 | STD_EXCEPTION_PSERIES(0x600, alignment) |
546 | STD_EXCEPTION_PSERIES(0x700, program_check) | 564 | STD_EXCEPTION_PSERIES(0x700, program_check) |
547 | STD_EXCEPTION_PSERIES(0x800, fp_unavailable) | 565 | STD_EXCEPTION_PSERIES(0x800, fp_unavailable) |
548 | STD_EXCEPTION_PSERIES(0x900, decrementer) | 566 | MASKABLE_EXCEPTION_PSERIES(0x900, decrementer) |
549 | STD_EXCEPTION_PSERIES(0xa00, trap_0a) | 567 | STD_EXCEPTION_PSERIES(0xa00, trap_0a) |
550 | STD_EXCEPTION_PSERIES(0xb00, trap_0b) | 568 | STD_EXCEPTION_PSERIES(0xb00, trap_0b) |
551 | 569 | ||
@@ -597,7 +615,24 @@ system_call_pSeries: | |||
597 | /*** pSeries interrupt support ***/ | 615 | /*** pSeries interrupt support ***/ |
598 | 616 | ||
599 | /* moved from 0xf00 */ | 617 | /* moved from 0xf00 */ |
600 | STD_EXCEPTION_PSERIES(., performance_monitor) | 618 | MASKABLE_EXCEPTION_PSERIES(., performance_monitor) |
619 | |||
620 | /* | ||
621 | * An interrupt came in while soft-disabled; clear EE in SRR1, | ||
622 | * clear paca->hard_enabled and return. | ||
623 | */ | ||
624 | masked_interrupt: | ||
625 | stb r10,PACAHARDIRQEN(r13) | ||
626 | mtcrf 0x80,r9 | ||
627 | ld r9,PACA_EXGEN+EX_R9(r13) | ||
628 | mfspr r10,SPRN_SRR1 | ||
629 | rldicl r10,r10,48,1 /* clear MSR_EE */ | ||
630 | rotldi r10,r10,16 | ||
631 | mtspr SPRN_SRR1,r10 | ||
632 | ld r10,PACA_EXGEN+EX_R10(r13) | ||
633 | mfspr r13,SPRN_SPRG1 | ||
634 | rfid | ||
635 | b . | ||
601 | 636 | ||
602 | .align 7 | 637 | .align 7 |
603 | _GLOBAL(do_stab_bolted_pSeries) | 638 | _GLOBAL(do_stab_bolted_pSeries) |
@@ -952,7 +987,8 @@ fast_exception_return: | |||
952 | REST_8GPRS(2, r1) | 987 | REST_8GPRS(2, r1) |
953 | 988 | ||
954 | mfmsr r10 | 989 | mfmsr r10 |
955 | clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ | 990 | rldicl r10,r10,48,1 /* clear EE */ |
991 | rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */ | ||
956 | mtmsrd r10,1 | 992 | mtmsrd r10,1 |
957 | 993 | ||
958 | mtspr SPRN_SRR1,r12 | 994 | mtspr SPRN_SRR1,r12 |
@@ -1877,11 +1913,16 @@ _GLOBAL(__secondary_start) | |||
1877 | /* enable MMU and jump to start_secondary */ | 1913 | /* enable MMU and jump to start_secondary */ |
1878 | LOAD_REG_ADDR(r3, .start_secondary_prolog) | 1914 | LOAD_REG_ADDR(r3, .start_secondary_prolog) |
1879 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) | 1915 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) |
1880 | #ifdef DO_SOFT_DISABLE | 1916 | #ifdef CONFIG_PPC_ISERIES |
1881 | BEGIN_FW_FTR_SECTION | 1917 | BEGIN_FW_FTR_SECTION |
1882 | ori r4,r4,MSR_EE | 1918 | ori r4,r4,MSR_EE |
1883 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 1919 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
1884 | #endif | 1920 | #endif |
1921 | BEGIN_FW_FTR_SECTION | ||
1922 | stb r7,PACASOFTIRQEN(r13) | ||
1923 | stb r7,PACAHARDIRQEN(r13) | ||
1924 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | ||
1925 | |||
1885 | mtspr SPRN_SRR0,r3 | 1926 | mtspr SPRN_SRR0,r3 |
1886 | mtspr SPRN_SRR1,r4 | 1927 | mtspr SPRN_SRR1,r4 |
1887 | rfid | 1928 | rfid |
@@ -2019,15 +2060,18 @@ _STATIC(start_here_common) | |||
2019 | 2060 | ||
2020 | /* Load up the kernel context */ | 2061 | /* Load up the kernel context */ |
2021 | 5: | 2062 | 5: |
2022 | #ifdef DO_SOFT_DISABLE | ||
2023 | BEGIN_FW_FTR_SECTION | ||
2024 | li r5,0 | 2063 | li r5,0 |
2025 | stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ | 2064 | stb r5,PACASOFTIRQEN(r13) /* Soft Disabled */ |
2065 | #ifdef CONFIG_PPC_ISERIES | ||
2066 | BEGIN_FW_FTR_SECTION | ||
2026 | mfmsr r5 | 2067 | mfmsr r5 |
2027 | ori r5,r5,MSR_EE /* Hard Enabled */ | 2068 | ori r5,r5,MSR_EE /* Hard Enabled */ |
2028 | mtmsrd r5 | 2069 | mtmsrd r5 |
2029 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 2070 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
2030 | #endif | 2071 | #endif |
2072 | BEGIN_FW_FTR_SECTION | ||
2073 | stb r5,PACAHARDIRQEN(r13) | ||
2074 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | ||
2031 | 2075 | ||
2032 | bl .start_kernel | 2076 | bl .start_kernel |
2033 | 2077 | ||
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 30de81da7b40..ba3195478600 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -30,6 +30,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) | |||
30 | beqlr | 30 | beqlr |
31 | 31 | ||
32 | /* Go to NAP now */ | 32 | /* Go to NAP now */ |
33 | mfmsr r7 | ||
34 | rldicl r0,r7,48,1 | ||
35 | rotldi r0,r0,16 | ||
36 | mtmsrd r0,1 /* hard-disable interrupts */ | ||
37 | li r0,1 | ||
38 | stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */ | ||
39 | stb r0,PACAHARDIRQEN(r13) | ||
33 | BEGIN_FTR_SECTION | 40 | BEGIN_FTR_SECTION |
34 | DSSALL | 41 | DSSALL |
35 | sync | 42 | sync |
@@ -38,7 +45,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
38 | ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | 45 | ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ |
39 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | 46 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ |
40 | std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | 47 | std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ |
41 | mfmsr r7 | ||
42 | ori r7,r7,MSR_EE | 48 | ori r7,r7,MSR_EE |
43 | oris r7,r7,MSR_POW@h | 49 | oris r7,r7,MSR_POW@h |
44 | 1: sync | 50 | 1: sync |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5e37bf14ef2d..67b21a008f6e 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -64,8 +64,9 @@ | |||
64 | #include <asm/ptrace.h> | 64 | #include <asm/ptrace.h> |
65 | #include <asm/machdep.h> | 65 | #include <asm/machdep.h> |
66 | #include <asm/udbg.h> | 66 | #include <asm/udbg.h> |
67 | #ifdef CONFIG_PPC_ISERIES | 67 | #ifdef CONFIG_PPC64 |
68 | #include <asm/paca.h> | 68 | #include <asm/paca.h> |
69 | #include <asm/firmware.h> | ||
69 | #endif | 70 | #endif |
70 | 71 | ||
71 | int __irq_offset_value; | 72 | int __irq_offset_value; |
@@ -95,6 +96,27 @@ extern atomic_t ipi_sent; | |||
95 | EXPORT_SYMBOL(irq_desc); | 96 | EXPORT_SYMBOL(irq_desc); |
96 | 97 | ||
97 | int distribute_irqs = 1; | 98 | int distribute_irqs = 1; |
99 | |||
100 | void local_irq_restore(unsigned long en) | ||
101 | { | ||
102 | get_paca()->soft_enabled = en; | ||
103 | if (!en) | ||
104 | return; | ||
105 | |||
106 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
107 | if (get_paca()->lppaca_ptr->int_dword.any_int) | ||
108 | iseries_handle_interrupts(); | ||
109 | return; | ||
110 | } | ||
111 | |||
112 | if (get_paca()->hard_enabled) | ||
113 | return; | ||
114 | /* need to hard-enable interrupts here */ | ||
115 | get_paca()->hard_enabled = en; | ||
116 | if ((int)mfspr(SPRN_DEC) < 0) | ||
117 | mtspr(SPRN_DEC, 1); | ||
118 | hard_irq_enable(); | ||
119 | } | ||
98 | #endif /* CONFIG_PPC64 */ | 120 | #endif /* CONFIG_PPC64 */ |
99 | 121 | ||
100 | int show_interrupts(struct seq_file *p, void *v) | 122 | int show_interrupts(struct seq_file *p, void *v) |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 807193a3c784..9179f0739ea2 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -49,6 +49,10 @@ | |||
49 | #include <asm/commproc.h> | 49 | #include <asm/commproc.h> |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #ifdef CONFIG_PPC64 | ||
53 | EXPORT_SYMBOL(local_irq_restore); | ||
54 | #endif | ||
55 | |||
52 | #ifdef CONFIG_PPC32 | 56 | #ifdef CONFIG_PPC32 |
53 | extern void transfer_to_handler(void); | 57 | extern void transfer_to_handler(void); |
54 | extern void do_IRQ(struct pt_regs *regs); | 58 | extern void do_IRQ(struct pt_regs *regs); |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 4b2e32eab9dc..b1b0cda3f748 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -223,8 +223,8 @@ void early_setup_secondary(void) | |||
223 | { | 223 | { |
224 | struct paca_struct *lpaca = get_paca(); | 224 | struct paca_struct *lpaca = get_paca(); |
225 | 225 | ||
226 | /* Mark enabled in PACA */ | 226 | /* Mark interrupts enabled in PACA */ |
227 | lpaca->proc_enabled = 0; | 227 | lpaca->soft_enabled = 0; |
228 | 228 | ||
229 | /* Initialize hash table for that CPU */ | 229 | /* Initialize hash table for that CPU */ |
230 | htab_initialize_secondary(); | 230 | htab_initialize_secondary(); |