aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/head_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r--arch/powerpc/kernel/head_64.S153
1 files changed, 98 insertions, 55 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index e720729f3e55..8cdff5a1f3e2 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:
@@ -74,13 +72,11 @@
74 .text 72 .text
75 .globl _stext 73 .globl _stext
76_stext: 74_stext:
77#ifdef CONFIG_PPC_MULTIPLATFORM
78_GLOBAL(__start) 75_GLOBAL(__start)
79 /* NOP this out unconditionally */ 76 /* NOP this out unconditionally */
80BEGIN_FTR_SECTION 77BEGIN_FTR_SECTION
81 b .__start_initialization_multiplatform 78 b .__start_initialization_multiplatform
82END_FTR_SECTION(0, 1) 79END_FTR_SECTION(0, 1)
83#endif /* CONFIG_PPC_MULTIPLATFORM */
84 80
85 /* Catch branch to 0 in real mode */ 81 /* Catch branch to 0 in real mode */
86 trap 82 trap
@@ -308,7 +304,9 @@ exception_marker:
308 std r9,_LINK(r1); \ 304 std r9,_LINK(r1); \
309 mfctr r10; /* save CTR in stackframe */ \ 305 mfctr r10; /* save CTR in stackframe */ \
310 std r10,_CTR(r1); \ 306 std r10,_CTR(r1); \
307 lbz r10,PACASOFTIRQEN(r13); \
311 mfspr r11,SPRN_XER; /* save XER in stackframe */ \ 308 mfspr r11,SPRN_XER; /* save XER in stackframe */ \
309 std r10,SOFTE(r1); \
312 std r11,_XER(r1); \ 310 std r11,_XER(r1); \
313 li r9,(n)+1; \ 311 li r9,(n)+1; \
314 std r9,_TRAP(r1); /* set trap number */ \ 312 std r9,_TRAP(r1); /* set trap number */ \
@@ -343,6 +341,34 @@ label##_pSeries: \
343 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 341 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
344 342
345 343
344#define MASKABLE_EXCEPTION_PSERIES(n, label) \
345 . = n; \
346 .globl label##_pSeries; \
347label##_pSeries: \
348 HMT_MEDIUM; \
349 mtspr SPRN_SPRG1,r13; /* save r13 */ \
350 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
351 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
352 std r10,PACA_EXGEN+EX_R10(r13); \
353 lbz r10,PACASOFTIRQEN(r13); \
354 mfcr r9; \
355 cmpwi r10,0; \
356 beq masked_interrupt; \
357 mfspr r10,SPRN_SPRG1; \
358 std r10,PACA_EXGEN+EX_R13(r13); \
359 std r11,PACA_EXGEN+EX_R11(r13); \
360 std r12,PACA_EXGEN+EX_R12(r13); \
361 clrrdi r12,r13,32; /* get high part of &label */ \
362 mfmsr r10; \
363 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
364 LOAD_HANDLER(r12,label##_common) \
365 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
366 mtspr SPRN_SRR0,r12; \
367 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
368 mtspr SPRN_SRR1,r10; \
369 rfid; \
370 b . /* prevent speculative execution */
371
346#define STD_EXCEPTION_ISERIES(n, label, area) \ 372#define STD_EXCEPTION_ISERIES(n, label, area) \
347 .globl label##_iSeries; \ 373 .globl label##_iSeries; \
348label##_iSeries: \ 374label##_iSeries: \
@@ -358,40 +384,32 @@ label##_iSeries: \
358 HMT_MEDIUM; \ 384 HMT_MEDIUM; \
359 mtspr SPRN_SPRG1,r13; /* save r13 */ \ 385 mtspr SPRN_SPRG1,r13; /* save r13 */ \
360 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ 386 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
361 lbz r10,PACAPROCENABLED(r13); \ 387 lbz r10,PACASOFTIRQEN(r13); \
362 cmpwi 0,r10,0; \ 388 cmpwi 0,r10,0; \
363 beq- label##_iSeries_masked; \ 389 beq- label##_iSeries_masked; \
364 EXCEPTION_PROLOG_ISERIES_2; \ 390 EXCEPTION_PROLOG_ISERIES_2; \
365 b label##_common; \ 391 b label##_common; \
366 392
367#ifdef DO_SOFT_DISABLE 393#ifdef CONFIG_PPC_ISERIES
368#define DISABLE_INTS \ 394#define DISABLE_INTS \
369BEGIN_FW_FTR_SECTION; \
370 lbz r10,PACAPROCENABLED(r13); \
371 li r11,0; \ 395 li r11,0; \
372 std r10,SOFTE(r1); \ 396 stb r11,PACASOFTIRQEN(r13); \
397BEGIN_FW_FTR_SECTION; \
398 stb r11,PACAHARDIRQEN(r13); \
399END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
400BEGIN_FW_FTR_SECTION; \
373 mfmsr r10; \ 401 mfmsr r10; \
374 stb r11,PACAPROCENABLED(r13); \
375 ori r10,r10,MSR_EE; \ 402 ori r10,r10,MSR_EE; \
376 mtmsrd r10,1; \ 403 mtmsrd r10,1; \
377END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 404END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
378 405
379#define ENABLE_INTS \ 406#else
380BEGIN_FW_FTR_SECTION; \ 407#define DISABLE_INTS \
381 lbz r10,PACAPROCENABLED(r13); \ 408 li r11,0; \
382 mfmsr r11; \ 409 stb r11,PACASOFTIRQEN(r13); \
383 std r10,SOFTE(r1); \ 410 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 411
393#else /* hard enable/disable interrupts */ 412#endif /* CONFIG_PPC_ISERIES */
394#define DISABLE_INTS
395 413
396#define ENABLE_INTS \ 414#define ENABLE_INTS \
397 ld r12,_MSR(r1); \ 415 ld r12,_MSR(r1); \
@@ -399,8 +417,6 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
399 rlwimi r11,r12,0,MSR_EE; \ 417 rlwimi r11,r12,0,MSR_EE; \
400 mtmsrd r11,1 418 mtmsrd r11,1
401 419
402#endif
403
404#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ 420#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
405 .align 7; \ 421 .align 7; \
406 .globl label##_common; \ 422 .globl label##_common; \
@@ -541,11 +557,11 @@ instruction_access_slb_pSeries:
541 mfspr r12,SPRN_SRR1 /* and SRR1 */ 557 mfspr r12,SPRN_SRR1 /* and SRR1 */
542 b .slb_miss_realmode /* Rel. branch works in real mode */ 558 b .slb_miss_realmode /* Rel. branch works in real mode */
543 559
544 STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) 560 MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
545 STD_EXCEPTION_PSERIES(0x600, alignment) 561 STD_EXCEPTION_PSERIES(0x600, alignment)
546 STD_EXCEPTION_PSERIES(0x700, program_check) 562 STD_EXCEPTION_PSERIES(0x700, program_check)
547 STD_EXCEPTION_PSERIES(0x800, fp_unavailable) 563 STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
548 STD_EXCEPTION_PSERIES(0x900, decrementer) 564 MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
549 STD_EXCEPTION_PSERIES(0xa00, trap_0a) 565 STD_EXCEPTION_PSERIES(0xa00, trap_0a)
550 STD_EXCEPTION_PSERIES(0xb00, trap_0b) 566 STD_EXCEPTION_PSERIES(0xb00, trap_0b)
551 567
@@ -597,7 +613,24 @@ system_call_pSeries:
597/*** pSeries interrupt support ***/ 613/*** pSeries interrupt support ***/
598 614
599 /* moved from 0xf00 */ 615 /* moved from 0xf00 */
600 STD_EXCEPTION_PSERIES(., performance_monitor) 616 MASKABLE_EXCEPTION_PSERIES(., performance_monitor)
617
618/*
619 * An interrupt came in while soft-disabled; clear EE in SRR1,
620 * clear paca->hard_enabled and return.
621 */
622masked_interrupt:
623 stb r10,PACAHARDIRQEN(r13)
624 mtcrf 0x80,r9
625 ld r9,PACA_EXGEN+EX_R9(r13)
626 mfspr r10,SPRN_SRR1
627 rldicl r10,r10,48,1 /* clear MSR_EE */
628 rotldi r10,r10,16
629 mtspr SPRN_SRR1,r10
630 ld r10,PACA_EXGEN+EX_R10(r13)
631 mfspr r13,SPRN_SPRG1
632 rfid
633 b .
601 634
602 .align 7 635 .align 7
603do_stab_bolted_pSeries: 636do_stab_bolted_pSeries:
@@ -926,10 +959,18 @@ bad_stack:
926 * any task or sent any task a signal, you should use 959 * any task or sent any task a signal, you should use
927 * ret_from_except or ret_from_except_lite instead of this. 960 * ret_from_except or ret_from_except_lite instead of this.
928 */ 961 */
962fast_exc_return_irq: /* restores irq state too */
963 ld r3,SOFTE(r1)
964 ld r12,_MSR(r1)
965 stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
966 rldicl r4,r12,49,63 /* get MSR_EE to LSB */
967 stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
968 b 1f
969
929 .globl fast_exception_return 970 .globl fast_exception_return
930fast_exception_return: 971fast_exception_return:
931 ld r12,_MSR(r1) 972 ld r12,_MSR(r1)
932 ld r11,_NIP(r1) 9731: ld r11,_NIP(r1)
933 andi. r3,r12,MSR_RI /* check if RI is set */ 974 andi. r3,r12,MSR_RI /* check if RI is set */
934 beq- unrecov_fer 975 beq- unrecov_fer
935 976
@@ -952,7 +993,8 @@ fast_exception_return:
952 REST_8GPRS(2, r1) 993 REST_8GPRS(2, r1)
953 994
954 mfmsr r10 995 mfmsr r10
955 clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ 996 rldicl r10,r10,48,1 /* clear EE */
997 rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */
956 mtmsrd r10,1 998 mtmsrd r10,1
957 999
958 mtspr SPRN_SRR1,r12 1000 mtspr SPRN_SRR1,r12
@@ -1326,6 +1368,16 @@ BEGIN_FW_FTR_SECTION
1326 * interrupts if necessary. 1368 * interrupts if necessary.
1327 */ 1369 */
1328 beq 13f 1370 beq 13f
1371END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1372#endif
1373BEGIN_FW_FTR_SECTION
1374 /*
1375 * Here we have interrupts hard-disabled, so it is sufficient
1376 * to restore paca->{soft,hard}_enable and get out.
1377 */
1378 beq fast_exc_return_irq /* Return from exception on success */
1379END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1380
1329 /* For a hash failure, we don't bother re-enabling interrupts */ 1381 /* For a hash failure, we don't bother re-enabling interrupts */
1330 ble- 12f 1382 ble- 12f
1331 1383
@@ -1337,14 +1389,6 @@ BEGIN_FW_FTR_SECTION
1337 ld r3,SOFTE(r1) 1389 ld r3,SOFTE(r1)
1338 bl .local_irq_restore 1390 bl .local_irq_restore
1339 b 11f 1391 b 11f
1340END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1341#endif
1342BEGIN_FW_FTR_SECTION
1343 beq fast_exception_return /* Return from exception on success */
1344 ble- 12f /* Failure return from hash_page */
1345
1346 /* fall through */
1347END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1348 1392
1349/* Here we have a page fault that hash_page can't handle. */ 1393/* Here we have a page fault that hash_page can't handle. */
1350handle_page_fault: 1394handle_page_fault:
@@ -1362,6 +1406,8 @@ handle_page_fault:
1362 bl .bad_page_fault 1406 bl .bad_page_fault
1363 b .ret_from_except 1407 b .ret_from_except
1364 1408
140913: b .ret_from_except_lite
1410
1365/* We have a page fault that hash_page could handle but HV refused 1411/* We have a page fault that hash_page could handle but HV refused
1366 * the PTE insertion 1412 * the PTE insertion
1367 */ 1413 */
@@ -1371,8 +1417,6 @@ handle_page_fault:
1371 bl .low_hash_fault 1417 bl .low_hash_fault
1372 b .ret_from_except 1418 b .ret_from_except
1373 1419
137413: b .ret_from_except_lite
1375
1376 /* here we have a segment miss */ 1420 /* here we have a segment miss */
1377do_ste_alloc: 1421do_ste_alloc:
1378 bl .ste_allocate /* try to insert stab entry */ 1422 bl .ste_allocate /* try to insert stab entry */
@@ -1595,7 +1639,6 @@ _STATIC(__start_initialization_iSeries)
1595 b .start_here_common 1639 b .start_here_common
1596#endif /* CONFIG_PPC_ISERIES */ 1640#endif /* CONFIG_PPC_ISERIES */
1597 1641
1598#ifdef CONFIG_PPC_MULTIPLATFORM
1599 1642
1600_STATIC(__mmu_off) 1643_STATIC(__mmu_off)
1601 mfmsr r3 1644 mfmsr r3
@@ -1621,13 +1664,11 @@ _STATIC(__mmu_off)
1621 * 1664 *
1622 */ 1665 */
1623_GLOBAL(__start_initialization_multiplatform) 1666_GLOBAL(__start_initialization_multiplatform)
1624#ifdef CONFIG_PPC_MULTIPLATFORM
1625 /* 1667 /*
1626 * Are we booted from a PROM Of-type client-interface ? 1668 * Are we booted from a PROM Of-type client-interface ?
1627 */ 1669 */
1628 cmpldi cr0,r5,0 1670 cmpldi cr0,r5,0
1629 bne .__boot_from_prom /* yes -> prom */ 1671 bne .__boot_from_prom /* yes -> prom */
1630#endif
1631 1672
1632 /* Save parameters */ 1673 /* Save parameters */
1633 mr r31,r3 1674 mr r31,r3
@@ -1656,7 +1697,6 @@ _GLOBAL(__start_initialization_multiplatform)
1656 bl .__mmu_off 1697 bl .__mmu_off
1657 b .__after_prom_start 1698 b .__after_prom_start
1658 1699
1659#ifdef CONFIG_PPC_MULTIPLATFORM
1660_STATIC(__boot_from_prom) 1700_STATIC(__boot_from_prom)
1661 /* Save parameters */ 1701 /* Save parameters */
1662 mr r31,r3 1702 mr r31,r3
@@ -1696,7 +1736,6 @@ _STATIC(__boot_from_prom)
1696 bl .prom_init 1736 bl .prom_init
1697 /* We never return */ 1737 /* We never return */
1698 trap 1738 trap
1699#endif
1700 1739
1701/* 1740/*
1702 * At this point, r3 contains the physical address we are running at, 1741 * At this point, r3 contains the physical address we are running at,
@@ -1752,8 +1791,6 @@ _STATIC(__after_prom_start)
1752 bl .copy_and_flush /* copy the rest */ 1791 bl .copy_and_flush /* copy the rest */
1753 b .start_here_multiplatform 1792 b .start_here_multiplatform
1754 1793
1755#endif /* CONFIG_PPC_MULTIPLATFORM */
1756
1757/* 1794/*
1758 * Copy routine used to copy the kernel to start at physical address 0 1795 * Copy routine used to copy the kernel to start at physical address 0
1759 * and flush and invalidate the caches as needed. 1796 * and flush and invalidate the caches as needed.
@@ -1877,11 +1914,16 @@ _GLOBAL(__secondary_start)
1877 /* enable MMU and jump to start_secondary */ 1914 /* enable MMU and jump to start_secondary */
1878 LOAD_REG_ADDR(r3, .start_secondary_prolog) 1915 LOAD_REG_ADDR(r3, .start_secondary_prolog)
1879 LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) 1916 LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
1880#ifdef DO_SOFT_DISABLE 1917#ifdef CONFIG_PPC_ISERIES
1881BEGIN_FW_FTR_SECTION 1918BEGIN_FW_FTR_SECTION
1882 ori r4,r4,MSR_EE 1919 ori r4,r4,MSR_EE
1883END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 1920END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1884#endif 1921#endif
1922BEGIN_FW_FTR_SECTION
1923 stb r7,PACASOFTIRQEN(r13)
1924 stb r7,PACAHARDIRQEN(r13)
1925END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1926
1885 mtspr SPRN_SRR0,r3 1927 mtspr SPRN_SRR0,r3
1886 mtspr SPRN_SRR1,r4 1928 mtspr SPRN_SRR1,r4
1887 rfid 1929 rfid
@@ -1913,7 +1955,6 @@ _GLOBAL(enable_64b_mode)
1913 isync 1955 isync
1914 blr 1956 blr
1915 1957
1916#ifdef CONFIG_PPC_MULTIPLATFORM
1917/* 1958/*
1918 * This is where the main kernel code starts. 1959 * This is where the main kernel code starts.
1919 */ 1960 */
@@ -1977,7 +2018,6 @@ _STATIC(start_here_multiplatform)
1977 mtspr SPRN_SRR1,r4 2018 mtspr SPRN_SRR1,r4
1978 rfid 2019 rfid
1979 b . /* prevent speculative execution */ 2020 b . /* prevent speculative execution */
1980#endif /* CONFIG_PPC_MULTIPLATFORM */
1981 2021
1982 /* This is where all platforms converge execution */ 2022 /* This is where all platforms converge execution */
1983_STATIC(start_here_common) 2023_STATIC(start_here_common)
@@ -2005,15 +2045,18 @@ _STATIC(start_here_common)
2005 2045
2006 /* Load up the kernel context */ 2046 /* Load up the kernel context */
20075: 20475:
2008#ifdef DO_SOFT_DISABLE
2009BEGIN_FW_FTR_SECTION
2010 li r5,0 2048 li r5,0
2011 stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ 2049 stb r5,PACASOFTIRQEN(r13) /* Soft Disabled */
2050#ifdef CONFIG_PPC_ISERIES
2051BEGIN_FW_FTR_SECTION
2012 mfmsr r5 2052 mfmsr r5
2013 ori r5,r5,MSR_EE /* Hard Enabled */ 2053 ori r5,r5,MSR_EE /* Hard Enabled */
2014 mtmsrd r5 2054 mtmsrd r5
2015END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 2055END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
2016#endif 2056#endif
2057BEGIN_FW_FTR_SECTION
2058 stb r5,PACAHARDIRQEN(r13)
2059END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
2017 2060
2018 bl .start_kernel 2061 bl .start_kernel
2019 2062