aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2006-09-25 04:19:00 -0400
committerStephen Rothwell <sfr@canb.auug.org.au>2006-10-03 02:50:21 -0400
commit3f639ee8c52c187d8c95db430ac6f485bffbe5af (patch)
tree26299497413aba786f962960c4a3cf83aa81f42b /arch/powerpc/kernel
parentfc246c389db7b08b4a054e68c742c6598b02523c (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.S18
-rw-r--r--arch/powerpc/kernel/head_64.S28
-rw-r--r--arch/powerpc/kernel/misc_64.S46
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S8
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
91BEGIN_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)
99END_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
463restore: 462restore:
464#ifdef CONFIG_PPC_ISERIES 463#ifdef CONFIG_PPC_ISERIES
464BEGIN_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
4824: stb r5,PACAPROCENABLED(r13) 4824: stb r5,PACAPROCENABLED(r13)
483END_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
542BEGIN_FW_FTR_SECTION
541 ld r0,SOFTE(r1) 543 ld r0,SOFTE(r1)
542 cmpdi r0,0 544 cmpdi r0,0
543#else 545END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
544 andi. r0,r3,MSR_EE
545#endif 546#endif
547BEGIN_FW_FTR_SECTION
548 andi. r0,r3,MSR_EE
549END_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 */
5491: 5531:
550#ifdef CONFIG_PPC_ISERIES 554#ifdef CONFIG_PPC_ISERIES
555BEGIN_FW_FTR_SECTION
551 li r0,1 556 li r0,1
552 stb r0,PACAPROCENABLED(r13) 557 stb r0,PACAPROCENABLED(r13)
558END_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 \
369BEGIN_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; \
377END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
375 378
376#define ENABLE_INTS \ 379#define ENABLE_INTS \
380BEGIN_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; \
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); \
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
1084BEGIN_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 */
1087END_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
1102BEGIN_FW_FTR_SECTION
1090 mtspr SPRN_SRR0,r11 1103 mtspr SPRN_SRR0,r11
1091 mtspr SPRN_SRR1,r12 1104 mtspr SPRN_SRR1,r12
1105END_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
1318BEGIN_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 1339END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1340#endif
1341BEGIN_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 1346END_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
1881BEGIN_FW_FTR_SECTION
1864 ori r4,r4,MSR_EE 1882 ori r4,r4,MSR_EE
1883END_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 */
20015: 20215:
2002#ifdef DO_SOFT_DISABLE 2022#ifdef DO_SOFT_DISABLE
2023BEGIN_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
2029END_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 */
3441: 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 */
3623: stw r0,0(r8)
363BEGIN_FTR_SECTION
364 dcbst 0,r8 /* suboptimal, but simpler */
365 sync
366 icbi 0,r8
367END_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 : {