diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2006-09-25 04:19:00 -0400 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2006-10-03 02:50:21 -0400 |
commit | 3f639ee8c52c187d8c95db430ac6f485bffbe5af (patch) | |
tree | 26299497413aba786f962960c4a3cf83aa81f42b /arch/powerpc/kernel | |
parent | fc246c389db7b08b4a054e68c742c6598b02523c (diff) |
[POWERPC] implement BEGIN/END_FW_FTR_SECTION
and use it an all the obvious places in assembler code.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 18 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 28 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 46 | ||||
-rw-r--r-- | arch/powerpc/kernel/vmlinux.lds.S | 8 |
4 files changed, 91 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2cd872b5283b..748e74fcf541 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -27,10 +27,7 @@ | |||
27 | #include <asm/ppc_asm.h> | 27 | #include <asm/ppc_asm.h> |
28 | #include <asm/asm-offsets.h> | 28 | #include <asm/asm-offsets.h> |
29 | #include <asm/cputable.h> | 29 | #include <asm/cputable.h> |
30 | 30 | #include <asm/firmware.h> | |
31 | #ifdef CONFIG_PPC_ISERIES | ||
32 | #define DO_SOFT_DISABLE | ||
33 | #endif | ||
34 | 31 | ||
35 | /* | 32 | /* |
36 | * System calls. | 33 | * System calls. |
@@ -91,6 +88,7 @@ system_call_common: | |||
91 | ld r11,exception_marker@toc(r2) | 88 | ld r11,exception_marker@toc(r2) |
92 | std r11,-16(r9) /* "regshere" marker */ | 89 | std r11,-16(r9) /* "regshere" marker */ |
93 | #ifdef CONFIG_PPC_ISERIES | 90 | #ifdef CONFIG_PPC_ISERIES |
91 | BEGIN_FW_FTR_SECTION | ||
94 | /* Hack for handling interrupts when soft-enabling on iSeries */ | 92 | /* Hack for handling interrupts when soft-enabling on iSeries */ |
95 | cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ | 93 | cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ |
96 | andi. r10,r12,MSR_PR /* from kernel */ | 94 | andi. r10,r12,MSR_PR /* from kernel */ |
@@ -98,6 +96,7 @@ system_call_common: | |||
98 | beq hardware_interrupt_entry | 96 | beq hardware_interrupt_entry |
99 | lbz r10,PACAPROCENABLED(r13) | 97 | lbz r10,PACAPROCENABLED(r13) |
100 | std r10,SOFTE(r1) | 98 | std r10,SOFTE(r1) |
99 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
101 | #endif | 100 | #endif |
102 | mfmsr r11 | 101 | mfmsr r11 |
103 | ori r11,r11,MSR_EE | 102 | ori r11,r11,MSR_EE |
@@ -462,6 +461,7 @@ _GLOBAL(ret_from_except_lite) | |||
462 | 461 | ||
463 | restore: | 462 | restore: |
464 | #ifdef CONFIG_PPC_ISERIES | 463 | #ifdef CONFIG_PPC_ISERIES |
464 | BEGIN_FW_FTR_SECTION | ||
465 | ld r5,SOFTE(r1) | 465 | ld r5,SOFTE(r1) |
466 | cmpdi 0,r5,0 | 466 | cmpdi 0,r5,0 |
467 | beq 4f | 467 | beq 4f |
@@ -480,6 +480,7 @@ restore: | |||
480 | b .ret_from_except_lite /* loop back and handle more */ | 480 | b .ret_from_except_lite /* loop back and handle more */ |
481 | 481 | ||
482 | 4: stb r5,PACAPROCENABLED(r13) | 482 | 4: stb r5,PACAPROCENABLED(r13) |
483 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
483 | #endif | 484 | #endif |
484 | 485 | ||
485 | ld r3,_MSR(r1) | 486 | ld r3,_MSR(r1) |
@@ -538,18 +539,23 @@ do_work: | |||
538 | lwz r8,TI_PREEMPT(r9) | 539 | lwz r8,TI_PREEMPT(r9) |
539 | cmpwi cr1,r8,0 | 540 | cmpwi cr1,r8,0 |
540 | #ifdef CONFIG_PPC_ISERIES | 541 | #ifdef CONFIG_PPC_ISERIES |
542 | BEGIN_FW_FTR_SECTION | ||
541 | ld r0,SOFTE(r1) | 543 | ld r0,SOFTE(r1) |
542 | cmpdi r0,0 | 544 | cmpdi r0,0 |
543 | #else | 545 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
544 | andi. r0,r3,MSR_EE | ||
545 | #endif | 546 | #endif |
547 | BEGIN_FW_FTR_SECTION | ||
548 | andi. r0,r3,MSR_EE | ||
549 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | ||
546 | crandc eq,cr1*4+eq,eq | 550 | crandc eq,cr1*4+eq,eq |
547 | bne restore | 551 | bne restore |
548 | /* here we are preempting the current task */ | 552 | /* here we are preempting the current task */ |
549 | 1: | 553 | 1: |
550 | #ifdef CONFIG_PPC_ISERIES | 554 | #ifdef CONFIG_PPC_ISERIES |
555 | BEGIN_FW_FTR_SECTION | ||
551 | li r0,1 | 556 | li r0,1 |
552 | stb r0,PACAPROCENABLED(r13) | 557 | stb r0,PACAPROCENABLED(r13) |
558 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
553 | #endif | 559 | #endif |
554 | ori r10,r10,MSR_EE | 560 | ori r10,r10,MSR_EE |
555 | mtmsrd r10,1 /* reenable interrupts */ | 561 | mtmsrd r10,1 /* reenable interrupts */ |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 3065b472b95d..645c7f10fb28 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/hvcall.h> | 33 | #include <asm/hvcall.h> |
34 | #include <asm/iseries/lpar_map.h> | 34 | #include <asm/iseries/lpar_map.h> |
35 | #include <asm/thread_info.h> | 35 | #include <asm/thread_info.h> |
36 | #include <asm/firmware.h> | ||
36 | 37 | ||
37 | #ifdef CONFIG_PPC_ISERIES | 38 | #ifdef CONFIG_PPC_ISERIES |
38 | #define DO_SOFT_DISABLE | 39 | #define DO_SOFT_DISABLE |
@@ -365,19 +366,28 @@ label##_iSeries: \ | |||
365 | 366 | ||
366 | #ifdef DO_SOFT_DISABLE | 367 | #ifdef DO_SOFT_DISABLE |
367 | #define DISABLE_INTS \ | 368 | #define DISABLE_INTS \ |
369 | BEGIN_FW_FTR_SECTION; \ | ||
368 | lbz r10,PACAPROCENABLED(r13); \ | 370 | lbz r10,PACAPROCENABLED(r13); \ |
369 | li r11,0; \ | 371 | li r11,0; \ |
370 | std r10,SOFTE(r1); \ | 372 | std r10,SOFTE(r1); \ |
371 | mfmsr r10; \ | 373 | mfmsr r10; \ |
372 | stb r11,PACAPROCENABLED(r13); \ | 374 | stb r11,PACAPROCENABLED(r13); \ |
373 | ori r10,r10,MSR_EE; \ | 375 | ori r10,r10,MSR_EE; \ |
374 | mtmsrd r10,1 | 376 | mtmsrd r10,1; \ |
377 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
375 | 378 | ||
376 | #define ENABLE_INTS \ | 379 | #define ENABLE_INTS \ |
380 | BEGIN_FW_FTR_SECTION; \ | ||
377 | lbz r10,PACAPROCENABLED(r13); \ | 381 | lbz r10,PACAPROCENABLED(r13); \ |
378 | mfmsr r11; \ | 382 | mfmsr r11; \ |
379 | std r10,SOFTE(r1); \ | 383 | std r10,SOFTE(r1); \ |
380 | ori r11,r11,MSR_EE; \ | 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); \ | ||
381 | mtmsrd r11,1 | 391 | mtmsrd r11,1 |
382 | 392 | ||
383 | #else /* hard enable/disable interrupts */ | 393 | #else /* hard enable/disable interrupts */ |
@@ -1071,8 +1081,10 @@ _GLOBAL(slb_miss_realmode) | |||
1071 | ld r3,PACA_EXSLB+EX_R3(r13) | 1081 | ld r3,PACA_EXSLB+EX_R3(r13) |
1072 | lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ | 1082 | lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ |
1073 | #ifdef CONFIG_PPC_ISERIES | 1083 | #ifdef CONFIG_PPC_ISERIES |
1084 | BEGIN_FW_FTR_SECTION | ||
1074 | ld r11,PACALPPACAPTR(r13) | 1085 | ld r11,PACALPPACAPTR(r13) |
1075 | ld r11,LPPACASRR0(r11) /* get SRR0 value */ | 1086 | ld r11,LPPACASRR0(r11) /* get SRR0 value */ |
1087 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
1076 | #endif /* CONFIG_PPC_ISERIES */ | 1088 | #endif /* CONFIG_PPC_ISERIES */ |
1077 | 1089 | ||
1078 | mtlr r10 | 1090 | mtlr r10 |
@@ -1087,8 +1099,10 @@ _GLOBAL(slb_miss_realmode) | |||
1087 | .machine pop | 1099 | .machine pop |
1088 | 1100 | ||
1089 | #ifdef CONFIG_PPC_ISERIES | 1101 | #ifdef CONFIG_PPC_ISERIES |
1102 | BEGIN_FW_FTR_SECTION | ||
1090 | mtspr SPRN_SRR0,r11 | 1103 | mtspr SPRN_SRR0,r11 |
1091 | mtspr SPRN_SRR1,r12 | 1104 | mtspr SPRN_SRR1,r12 |
1105 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
1092 | #endif /* CONFIG_PPC_ISERIES */ | 1106 | #endif /* CONFIG_PPC_ISERIES */ |
1093 | ld r9,PACA_EXSLB+EX_R9(r13) | 1107 | ld r9,PACA_EXSLB+EX_R9(r13) |
1094 | ld r10,PACA_EXSLB+EX_R10(r13) | 1108 | ld r10,PACA_EXSLB+EX_R10(r13) |
@@ -1301,6 +1315,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | |||
1301 | cmpdi r3,0 /* see if hash_page succeeded */ | 1315 | cmpdi r3,0 /* see if hash_page succeeded */ |
1302 | 1316 | ||
1303 | #ifdef DO_SOFT_DISABLE | 1317 | #ifdef DO_SOFT_DISABLE |
1318 | BEGIN_FW_FTR_SECTION | ||
1304 | /* | 1319 | /* |
1305 | * If we had interrupts soft-enabled at the point where the | 1320 | * If we had interrupts soft-enabled at the point where the |
1306 | * DSI/ISI occurred, and an interrupt came in during hash_page, | 1321 | * DSI/ISI occurred, and an interrupt came in during hash_page, |
@@ -1321,12 +1336,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | |||
1321 | ld r3,SOFTE(r1) | 1336 | ld r3,SOFTE(r1) |
1322 | bl .local_irq_restore | 1337 | bl .local_irq_restore |
1323 | b 11f | 1338 | b 11f |
1324 | #else | 1339 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
1340 | #endif | ||
1341 | BEGIN_FW_FTR_SECTION | ||
1325 | beq fast_exception_return /* Return from exception on success */ | 1342 | beq fast_exception_return /* Return from exception on success */ |
1326 | ble- 12f /* Failure return from hash_page */ | 1343 | ble- 12f /* Failure return from hash_page */ |
1327 | 1344 | ||
1328 | /* fall through */ | 1345 | /* fall through */ |
1329 | #endif | 1346 | END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) |
1330 | 1347 | ||
1331 | /* Here we have a page fault that hash_page can't handle. */ | 1348 | /* Here we have a page fault that hash_page can't handle. */ |
1332 | _GLOBAL(handle_page_fault) | 1349 | _GLOBAL(handle_page_fault) |
@@ -1861,7 +1878,9 @@ _GLOBAL(__secondary_start) | |||
1861 | LOAD_REG_ADDR(r3, .start_secondary_prolog) | 1878 | LOAD_REG_ADDR(r3, .start_secondary_prolog) |
1862 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) | 1879 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) |
1863 | #ifdef DO_SOFT_DISABLE | 1880 | #ifdef DO_SOFT_DISABLE |
1881 | BEGIN_FW_FTR_SECTION | ||
1864 | ori r4,r4,MSR_EE | 1882 | ori r4,r4,MSR_EE |
1883 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
1865 | #endif | 1884 | #endif |
1866 | mtspr SPRN_SRR0,r3 | 1885 | mtspr SPRN_SRR0,r3 |
1867 | mtspr SPRN_SRR1,r4 | 1886 | mtspr SPRN_SRR1,r4 |
@@ -1986,6 +2005,7 @@ _STATIC(start_here_common) | |||
1986 | */ | 2005 | */ |
1987 | li r3,0 | 2006 | li r3,0 |
1988 | bl .do_cpu_ftr_fixups | 2007 | bl .do_cpu_ftr_fixups |
2008 | bl .do_fw_ftr_fixups | ||
1989 | 2009 | ||
1990 | /* ptr to current */ | 2010 | /* ptr to current */ |
1991 | LOAD_REG_IMMEDIATE(r4, init_task) | 2011 | LOAD_REG_IMMEDIATE(r4, init_task) |
@@ -2000,11 +2020,13 @@ _STATIC(start_here_common) | |||
2000 | /* Load up the kernel context */ | 2020 | /* Load up the kernel context */ |
2001 | 5: | 2021 | 5: |
2002 | #ifdef DO_SOFT_DISABLE | 2022 | #ifdef DO_SOFT_DISABLE |
2023 | BEGIN_FW_FTR_SECTION | ||
2003 | li r5,0 | 2024 | li r5,0 |
2004 | stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ | 2025 | stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ |
2005 | mfmsr r5 | 2026 | mfmsr r5 |
2006 | ori r5,r5,MSR_EE /* Hard Enabled */ | 2027 | ori r5,r5,MSR_EE /* Hard Enabled */ |
2007 | mtmsrd r5 | 2028 | mtmsrd r5 |
2029 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | ||
2008 | #endif | 2030 | #endif |
2009 | 2031 | ||
2010 | bl .start_kernel | 2032 | bl .start_kernel |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e3ed21cd3d94..465a7641cd0f 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -325,6 +325,52 @@ _GLOBAL(do_cpu_ftr_fixups) | |||
325 | isync | 325 | isync |
326 | b 1b | 326 | b 1b |
327 | 327 | ||
328 | /* | ||
329 | * do_fw_ftr_fixups - goes through the list of firmware feature fixups | ||
330 | * and writes nop's over sections of code that don't apply for this firmware. | ||
331 | * r3 = data offset (not changed) | ||
332 | */ | ||
333 | _GLOBAL(do_fw_ftr_fixups) | ||
334 | /* Get firmware features */ | ||
335 | LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features) | ||
336 | sub r6,r6,r3 | ||
337 | ld r4,0(r6) | ||
338 | /* Get the fixup table */ | ||
339 | LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup) | ||
340 | sub r6,r6,r3 | ||
341 | LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup) | ||
342 | sub r7,r7,r3 | ||
343 | /* Do the fixup */ | ||
344 | 1: cmpld r6,r7 | ||
345 | bgelr | ||
346 | addi r6,r6,32 | ||
347 | ld r8,-32(r6) /* mask */ | ||
348 | and r8,r8,r4 | ||
349 | ld r9,-24(r6) /* value */ | ||
350 | cmpld r8,r9 | ||
351 | beq 1b | ||
352 | ld r8,-16(r6) /* section begin */ | ||
353 | ld r9,-8(r6) /* section end */ | ||
354 | subf. r9,r8,r9 | ||
355 | beq 1b | ||
356 | /* write nops over the section of code */ | ||
357 | /* todo: if large section, add a branch at the start of it */ | ||
358 | srwi r9,r9,2 | ||
359 | mtctr r9 | ||
360 | sub r8,r8,r3 | ||
361 | lis r0,0x60000000@h /* nop */ | ||
362 | 3: stw r0,0(r8) | ||
363 | BEGIN_FTR_SECTION | ||
364 | dcbst 0,r8 /* suboptimal, but simpler */ | ||
365 | sync | ||
366 | icbi 0,r8 | ||
367 | END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE) | ||
368 | addi r8,r8,4 | ||
369 | bdnz 3b | ||
370 | sync /* additional sync needed on g4 */ | ||
371 | isync | ||
372 | b 1b | ||
373 | |||
328 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) | 374 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) |
329 | /* | 375 | /* |
330 | * Do an IO access in real mode | 376 | * Do an IO access in real mode |
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 02665a02130d..cb0e8d46c3e8 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -132,6 +132,14 @@ SECTIONS | |||
132 | *(__ftr_fixup) | 132 | *(__ftr_fixup) |
133 | __stop___ftr_fixup = .; | 133 | __stop___ftr_fixup = .; |
134 | } | 134 | } |
135 | #ifdef CONFIG_PPC64 | ||
136 | . = ALIGN(8); | ||
137 | __fw_ftr_fixup : { | ||
138 | __start___fw_ftr_fixup = .; | ||
139 | *(__fw_ftr_fixup) | ||
140 | __stop___fw_ftr_fixup = .; | ||
141 | } | ||
142 | #endif | ||
135 | 143 | ||
136 | . = ALIGN(PAGE_SIZE); | 144 | . = ALIGN(PAGE_SIZE); |
137 | .init.ramfs : { | 145 | .init.ramfs : { |