aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/head_64.S
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-10-04 02:47:49 -0400
committerPaul Mackerras <paulus@samba.org>2006-10-16 02:31:36 -0400
commitd04c56f73c30a5e593202ecfcf25ed43d42363a2 (patch)
treebec1208293c904b73f12dd9179ebf8e88dbdb085 /arch/powerpc/kernel/head_64.S
parent284a940675a64df253e3dffc60b09bb4bbb149e4 (diff)
[POWERPC] Lazy interrupt disabling for 64-bit machines
This implements a lazy strategy for disabling interrupts. This means that local_irq_disable() et al. just clear the 'interrupts are enabled' flag in the paca. If an interrupt comes along, the interrupt entry code notices that interrupts are supposed to be disabled, and clears the EE bit in SRR1, clears the 'interrupts are hard-enabled' flag in the paca, and returns. This means that interrupts only actually get disabled in the processor when an interrupt comes along. When interrupts are enabled by local_irq_enable() et al., the code sets the interrupts-enabled flag in the paca, and then checks whether interrupts got hard-disabled. If so, it also sets the EE bit in the MSR to hard-enable the interrupts. This has the potential to improve performance, and also makes it easier to make a kernel that can boot on iSeries and on other 64-bit machines, since this lazy-disable strategy is very similar to the soft-disable strategy that iSeries already uses. This version renames paca->proc_enabled to paca->soft_enabled, and changes a couple of soft-disables in the kexec code to hard-disables, which should fix the crash that Michael Ellerman saw. This doesn't yet use a reserved CR field for the soft_enabled and hard_enabled flags. This applies on top of Stephen Rothwell's patches to make it possible to build a combined iSeries/other kernel. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r--arch/powerpc/kernel/head_64.S110
1 files changed, 77 insertions, 33 deletions
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; \
349label##_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; \
348label##_iSeries: \ 376label##_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 \
369BEGIN_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); \
399BEGIN_FW_FTR_SECTION; \
400 stb r11,PACAHARDIRQEN(r13); \
401END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
402BEGIN_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; \
377END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 406END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
378 407
379#define ENABLE_INTS \ 408#else
380BEGIN_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; \
385END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
386BEGIN_FW_FTR_SECTION; \
387 ld r12,_MSR(r1); \
388 mfmsr r11; \
389 rlwimi r11,r12,0,MSR_EE; \
390END_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 */
624masked_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
1881BEGIN_FW_FTR_SECTION 1917BEGIN_FW_FTR_SECTION
1882 ori r4,r4,MSR_EE 1918 ori r4,r4,MSR_EE
1883END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 1919END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1884#endif 1920#endif
1921BEGIN_FW_FTR_SECTION
1922 stb r7,PACASOFTIRQEN(r13)
1923 stb r7,PACAHARDIRQEN(r13)
1924END_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 */
20215: 20625:
2022#ifdef DO_SOFT_DISABLE
2023BEGIN_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
2066BEGIN_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
2029END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 2070END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
2030#endif 2071#endif
2072BEGIN_FW_FTR_SECTION
2073 stb r5,PACAHARDIRQEN(r13)
2074END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
2031 2075
2032 bl .start_kernel 2076 bl .start_kernel
2033 2077