diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 110 |
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; \ | ||
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 | ||