Commit 3f639ee8 authored by Stephen Rothwell's avatar Stephen Rothwell

[POWERPC] implement BEGIN/END_FW_FTR_SECTION

and use it an all the obvious places in assembler code.
Signed-off-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
parent fc246c38
...@@ -27,10 +27,7 @@ ...@@ -27,10 +27,7 @@
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/firmware.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
#endif
/* /*
* System calls. * System calls.
...@@ -91,6 +88,7 @@ system_call_common: ...@@ -91,6 +88,7 @@ system_call_common:
ld r11,exception_marker@toc(r2) ld r11,exception_marker@toc(r2)
std r11,-16(r9) /* "regshere" marker */ std r11,-16(r9) /* "regshere" marker */
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
/* Hack for handling interrupts when soft-enabling on iSeries */ /* Hack for handling interrupts when soft-enabling on iSeries */
cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ cmpdi cr1,r0,0x5555 /* syscall 0x5555 */
andi. r10,r12,MSR_PR /* from kernel */ andi. r10,r12,MSR_PR /* from kernel */
...@@ -98,6 +96,7 @@ system_call_common: ...@@ -98,6 +96,7 @@ system_call_common:
beq hardware_interrupt_entry beq hardware_interrupt_entry
lbz r10,PACAPROCENABLED(r13) lbz r10,PACAPROCENABLED(r13)
std r10,SOFTE(r1) std r10,SOFTE(r1)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
mfmsr r11 mfmsr r11
ori r11,r11,MSR_EE ori r11,r11,MSR_EE
...@@ -462,6 +461,7 @@ _GLOBAL(ret_from_except_lite) ...@@ -462,6 +461,7 @@ _GLOBAL(ret_from_except_lite)
restore: restore:
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
ld r5,SOFTE(r1) ld r5,SOFTE(r1)
cmpdi 0,r5,0 cmpdi 0,r5,0
beq 4f beq 4f
...@@ -480,6 +480,7 @@ restore: ...@@ -480,6 +480,7 @@ restore:
b .ret_from_except_lite /* loop back and handle more */ b .ret_from_except_lite /* loop back and handle more */
4: stb r5,PACAPROCENABLED(r13) 4: stb r5,PACAPROCENABLED(r13)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
ld r3,_MSR(r1) ld r3,_MSR(r1)
...@@ -538,18 +539,23 @@ do_work: ...@@ -538,18 +539,23 @@ do_work:
lwz r8,TI_PREEMPT(r9) lwz r8,TI_PREEMPT(r9)
cmpwi cr1,r8,0 cmpwi cr1,r8,0
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
ld r0,SOFTE(r1) ld r0,SOFTE(r1)
cmpdi r0,0 cmpdi r0,0
#else END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
andi. r0,r3,MSR_EE
#endif #endif
BEGIN_FW_FTR_SECTION
andi. r0,r3,MSR_EE
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
crandc eq,cr1*4+eq,eq crandc eq,cr1*4+eq,eq
bne restore bne restore
/* here we are preempting the current task */ /* here we are preempting the current task */
1: 1:
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
li r0,1 li r0,1
stb r0,PACAPROCENABLED(r13) stb r0,PACAPROCENABLED(r13)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
ori r10,r10,MSR_EE ori r10,r10,MSR_EE
mtmsrd r10,1 /* reenable interrupts */ mtmsrd r10,1 /* reenable interrupts */
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/hvcall.h> #include <asm/hvcall.h>
#include <asm/iseries/lpar_map.h> #include <asm/iseries/lpar_map.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/firmware.h>
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE #define DO_SOFT_DISABLE
...@@ -365,19 +366,28 @@ label##_iSeries: \ ...@@ -365,19 +366,28 @@ label##_iSeries: \
#ifdef DO_SOFT_DISABLE #ifdef DO_SOFT_DISABLE
#define DISABLE_INTS \ #define DISABLE_INTS \
BEGIN_FW_FTR_SECTION; \
lbz r10,PACAPROCENABLED(r13); \ lbz r10,PACAPROCENABLED(r13); \
li r11,0; \ li r11,0; \
std r10,SOFTE(r1); \ std r10,SOFTE(r1); \
mfmsr r10; \ mfmsr r10; \
stb r11,PACAPROCENABLED(r13); \ stb r11,PACAPROCENABLED(r13); \
ori r10,r10,MSR_EE; \ ori r10,r10,MSR_EE; \
mtmsrd r10,1 mtmsrd r10,1; \
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#define ENABLE_INTS \ #define ENABLE_INTS \
BEGIN_FW_FTR_SECTION; \
lbz r10,PACAPROCENABLED(r13); \ lbz r10,PACAPROCENABLED(r13); \
mfmsr r11; \ mfmsr r11; \
std r10,SOFTE(r1); \ std r10,SOFTE(r1); \
ori r11,r11,MSR_EE; \ ori r11,r11,MSR_EE; \
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
BEGIN_FW_FTR_SECTION; \
ld r12,_MSR(r1); \
mfmsr r11; \
rlwimi r11,r12,0,MSR_EE; \
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
mtmsrd r11,1 mtmsrd r11,1
#else /* hard enable/disable interrupts */ #else /* hard enable/disable interrupts */
...@@ -1071,8 +1081,10 @@ _GLOBAL(slb_miss_realmode) ...@@ -1071,8 +1081,10 @@ _GLOBAL(slb_miss_realmode)
ld r3,PACA_EXSLB+EX_R3(r13) ld r3,PACA_EXSLB+EX_R3(r13)
lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
ld r11,PACALPPACAPTR(r13) ld r11,PACALPPACAPTR(r13)
ld r11,LPPACASRR0(r11) /* get SRR0 value */ ld r11,LPPACASRR0(r11) /* get SRR0 value */
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
mtlr r10 mtlr r10
...@@ -1087,8 +1099,10 @@ _GLOBAL(slb_miss_realmode) ...@@ -1087,8 +1099,10 @@ _GLOBAL(slb_miss_realmode)
.machine pop .machine pop
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
mtspr SPRN_SRR0,r11 mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12 mtspr SPRN_SRR1,r12
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
ld r9,PACA_EXSLB+EX_R9(r13) ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13) ld r10,PACA_EXSLB+EX_R10(r13)
...@@ -1301,6 +1315,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) ...@@ -1301,6 +1315,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
cmpdi r3,0 /* see if hash_page succeeded */ cmpdi r3,0 /* see if hash_page succeeded */
#ifdef DO_SOFT_DISABLE #ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
/* /*
* If we had interrupts soft-enabled at the point where the * If we had interrupts soft-enabled at the point where the
* DSI/ISI occurred, and an interrupt came in during hash_page, * DSI/ISI occurred, and an interrupt came in during hash_page,
...@@ -1321,12 +1336,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) ...@@ -1321,12 +1336,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
ld r3,SOFTE(r1) ld r3,SOFTE(r1)
bl .local_irq_restore bl .local_irq_restore
b 11f b 11f
#else END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
BEGIN_FW_FTR_SECTION
beq fast_exception_return /* Return from exception on success */ beq fast_exception_return /* Return from exception on success */
ble- 12f /* Failure return from hash_page */ ble- 12f /* Failure return from hash_page */
/* fall through */ /* fall through */
#endif END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
/* Here we have a page fault that hash_page can't handle. */ /* Here we have a page fault that hash_page can't handle. */
_GLOBAL(handle_page_fault) _GLOBAL(handle_page_fault)
...@@ -1861,7 +1878,9 @@ _GLOBAL(__secondary_start) ...@@ -1861,7 +1878,9 @@ _GLOBAL(__secondary_start)
LOAD_REG_ADDR(r3, .start_secondary_prolog) LOAD_REG_ADDR(r3, .start_secondary_prolog)
LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
#ifdef DO_SOFT_DISABLE #ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
ori r4,r4,MSR_EE ori r4,r4,MSR_EE
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
mtspr SPRN_SRR0,r3 mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4 mtspr SPRN_SRR1,r4
...@@ -1986,6 +2005,7 @@ _STATIC(start_here_common) ...@@ -1986,6 +2005,7 @@ _STATIC(start_here_common)
*/ */
li r3,0 li r3,0
bl .do_cpu_ftr_fixups bl .do_cpu_ftr_fixups
bl .do_fw_ftr_fixups
/* ptr to current */ /* ptr to current */
LOAD_REG_IMMEDIATE(r4, init_task) LOAD_REG_IMMEDIATE(r4, init_task)
...@@ -2000,11 +2020,13 @@ _STATIC(start_here_common) ...@@ -2000,11 +2020,13 @@ _STATIC(start_here_common)
/* Load up the kernel context */ /* Load up the kernel context */
5: 5:
#ifdef DO_SOFT_DISABLE #ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
li r5,0 li r5,0
stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
mfmsr r5 mfmsr r5
ori r5,r5,MSR_EE /* Hard Enabled */ ori r5,r5,MSR_EE /* Hard Enabled */
mtmsrd r5 mtmsrd r5
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
bl .start_kernel bl .start_kernel
......
...@@ -325,6 +325,52 @@ _GLOBAL(do_cpu_ftr_fixups) ...@@ -325,6 +325,52 @@ _GLOBAL(do_cpu_ftr_fixups)
isync isync
b 1b b 1b
/*
* do_fw_ftr_fixups - goes through the list of firmware feature fixups
* and writes nop's over sections of code that don't apply for this firmware.
* r3 = data offset (not changed)
*/
_GLOBAL(do_fw_ftr_fixups)
/* Get firmware features */
LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
sub r6,r6,r3
ld r4,0(r6)
/* Get the fixup table */
LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
sub r6,r6,r3
LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
sub r7,r7,r3
/* Do the fixup */
1: cmpld r6,r7
bgelr
addi r6,r6,32
ld r8,-32(r6) /* mask */
and r8,r8,r4
ld r9,-24(r6) /* value */
cmpld r8,r9
beq 1b
ld r8,-16(r6) /* section begin */
ld r9,-8(r6) /* section end */
subf. r9,r8,r9
beq 1b
/* write nops over the section of code */
/* todo: if large section, add a branch at the start of it */
srwi r9,r9,2
mtctr r9
sub r8,r8,r3
lis r0,0x60000000@h /* nop */
3: stw r0,0(r8)
BEGIN_FTR_SECTION
dcbst 0,r8 /* suboptimal, but simpler */
sync
icbi 0,r8
END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
addi r8,r8,4
bdnz 3b
sync /* additional sync needed on g4 */
isync
b 1b
#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
/* /*
* Do an IO access in real mode * Do an IO access in real mode
......
...@@ -132,6 +132,14 @@ SECTIONS ...@@ -132,6 +132,14 @@ SECTIONS
*(__ftr_fixup) *(__ftr_fixup)
__stop___ftr_fixup = .; __stop___ftr_fixup = .;
} }
#ifdef CONFIG_PPC64
. = ALIGN(8);
__fw_ftr_fixup : {
__start___fw_ftr_fixup = .;
*(__fw_ftr_fixup)
__stop___fw_ftr_fixup = .;
}
#endif
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
.init.ramfs : { .init.ramfs : {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/mmu.h> #include <asm/mmu.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/firmware.h>
/* void slb_allocate_realmode(unsigned long ea); /* void slb_allocate_realmode(unsigned long ea);
* *
...@@ -183,6 +184,7 @@ slb_finish_load: ...@@ -183,6 +184,7 @@ slb_finish_load:
* dont have any LRU information to help us choose a slot. * dont have any LRU information to help us choose a slot.
*/ */
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
/* /*
* On iSeries, the "bolted" stack segment can be cast out on * On iSeries, the "bolted" stack segment can be cast out on
* shared processor switch so we need to check for a miss on * shared processor switch so we need to check for a miss on
...@@ -194,6 +196,7 @@ slb_finish_load: ...@@ -194,6 +196,7 @@ slb_finish_load:
li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */ li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */
cmpld r9,r3 cmpld r9,r3
beq 3f beq 3f
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
ld r10,PACASTABRR(r13) ld r10,PACASTABRR(r13)
......
...@@ -14,34 +14,36 @@ ...@@ -14,34 +14,36 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifndef __ASSEMBLY__ #include <asm/asm-compat.h>
/* firmware feature bitmask values */ /* firmware feature bitmask values */
#define FIRMWARE_MAX_FEATURES 63 #define FIRMWARE_MAX_FEATURES 63
#define FW_FEATURE_PFT (1UL<<0) #define FW_FEATURE_PFT ASM_CONST(0x0000000000000001)
#define FW_FEATURE_TCE (1UL<<1) #define FW_FEATURE_TCE ASM_CONST(0x0000000000000002)
#define FW_FEATURE_SPRG0 (1UL<<2) #define FW_FEATURE_SPRG0 ASM_CONST(0x0000000000000004)
#define FW_FEATURE_DABR (1UL<<3) #define FW_FEATURE_DABR ASM_CONST(0x0000000000000008)
#define FW_FEATURE_COPY (1UL<<4) #define FW_FEATURE_COPY ASM_CONST(0x0000000000000010)
#define FW_FEATURE_ASR (1UL<<5) #define FW_FEATURE_ASR ASM_CONST(0x0000000000000020)
#define FW_FEATURE_DEBUG (1UL<<6) #define FW_FEATURE_DEBUG ASM_CONST(0x0000000000000040)
#define FW_FEATURE_TERM (1UL<<7) #define FW_FEATURE_TERM ASM_CONST(0x0000000000000080)
#define FW_FEATURE_PERF (1UL<<8) #define FW_FEATURE_PERF ASM_CONST(0x0000000000000100)
#define FW_FEATURE_DUMP (1UL<<9) #define FW_FEATURE_DUMP ASM_CONST(0x0000000000000200)
#define FW_FEATURE_INTERRUPT (1UL<<10) #define FW_FEATURE_INTERRUPT ASM_CONST(0x0000000000000400)
#define FW_FEATURE_MIGRATE (1UL<<11) #define FW_FEATURE_MIGRATE ASM_CONST(0x0000000000000800)
#define FW_FEATURE_PERFMON (1UL<<12) #define FW_FEATURE_PERFMON ASM_CONST(0x0000000000001000)
#define FW_FEATURE_CRQ (1UL<<13) #define FW_FEATURE_CRQ ASM_CONST(0x0000000000002000)
#define FW_FEATURE_VIO (1UL<<14) #define FW_FEATURE_VIO ASM_CONST(0x0000000000004000)
#define FW_FEATURE_RDMA (1UL<<15) #define FW_FEATURE_RDMA ASM_CONST(0x0000000000008000)
#define FW_FEATURE_LLAN (1UL<<16) #define FW_FEATURE_LLAN ASM_CONST(0x0000000000010000)
#define FW_FEATURE_BULK (1UL<<17) #define FW_FEATURE_BULK ASM_CONST(0x0000000000020000)
#define FW_FEATURE_XDABR (1UL<<18) #define FW_FEATURE_XDABR ASM_CONST(0x0000000000040000)
#define FW_FEATURE_MULTITCE (1UL<<19) #define FW_FEATURE_MULTITCE ASM_CONST(0x0000000000080000)
#define FW_FEATURE_SPLPAR (1UL<<20) #define FW_FEATURE_SPLPAR ASM_CONST(0x0000000000100000)
#define FW_FEATURE_ISERIES (1UL<<21) #define FW_FEATURE_ISERIES ASM_CONST(0x0000000000200000)
#define FW_FEATURE_LPAR (1UL<<22) #define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000)
#ifndef __ASSEMBLY__
enum { enum {
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
...@@ -94,6 +96,23 @@ extern void machine_check_fwnmi(void); ...@@ -94,6 +96,23 @@ extern void machine_check_fwnmi(void);
/* This is true if we are using the firmware NMI handler (typically LPAR) */ /* This is true if we are using the firmware NMI handler (typically LPAR) */
extern int fwnmi_active; extern int fwnmi_active;
#else /* __ASSEMBLY__ */
#define BEGIN_FW_FTR_SECTION 96:
#define END_FW_FTR_SECTION(msk, val) \
97: \
.section __fw_ftr_fixup,"a"; \
.align 3; \
.llong msk; \
.llong val; \
.llong 96b; \
.llong 97b; \
.previous
#define END_FW_FTR_SECTION_IFSET(msk) END_FW_FTR_SECTION((msk), (msk))
#define END_FW_FTR_SECTION_IFCLR(msk) END_FW_FTR_SECTION((msk), 0)
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_FIRMWARE_H */ #endif /* __ASM_POWERPC_FIRMWARE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment