aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-08-29 21:40:24 -0400
committerPaul Mackerras <paulus@samba.org>2008-09-15 14:08:08 -0400
commit1f6a93e4c35e75d547b51f56ba8139ab1a91628c (patch)
treec755528c7f299fa407b3eda77a3e08af78b0b25c /arch/powerpc/include
parent9a95516740c924675d52c472d7d170c62eab176c (diff)
powerpc: Make it possible to move the interrupt handlers away from the kernel
This changes the way that the exception prologs transfer control to the handlers in 64-bit kernels with the aim of making it possible to have the prologs separate from the main body of the kernel. Now, instead of computing the address of the handler by taking the top 32 bits of the paca address (to get the 0xc0000000........ part) and ORing in something in the bottom 16 bits, we get the base address of the kernel by doing a load from the paca and add an offset. This also replaces an mfmsr and an ori to compute the MSR value for the handler with a load from the paca. That makes it unnecessary to have a separate version of EXCEPTION_PROLOG_PSERIES that forces 64-bit mode. We can no longer use a direct branches in the exception prolog code, which means that the SLB miss handlers can't branch directly to .slb_miss_realmode any more. Instead we have to compute the address and do an indirect branch. This is conditional on CONFIG_RELOCATABLE; for non-relocatable kernels we use a direct branch as before. (A later change will allow CONFIG_RELOCATABLE to be set on 64-bit powerpc.) Since the secondary CPUs on pSeries start execution in the first 0x100 bytes of real memory and then have to get to wherever the kernel is, we can't use a direct branch to get there. Instead this changes __secondary_hold_spinloop from a flag to a function pointer. When it is set to a non-NULL value, the secondary CPUs jump to the function pointed to by that value. Finally this eliminates one code difference between 32-bit and 64-bit by making __secondary_hold be the text address of the secondary CPU spinloop rather than a function descriptor for it. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r--arch/powerpc/include/asm/exception.h42
-rw-r--r--arch/powerpc/include/asm/paca.h2
2 files changed, 7 insertions, 37 deletions
diff --git a/arch/powerpc/include/asm/exception.h b/arch/powerpc/include/asm/exception.h
index 329148b5acc6..d3d4534e3c74 100644
--- a/arch/powerpc/include/asm/exception.h
+++ b/arch/powerpc/include/asm/exception.h
@@ -53,14 +53,8 @@
53 * low halfword of the address, but for Kdump we need the whole low 53 * low halfword of the address, but for Kdump we need the whole low
54 * word. 54 * word.
55 */ 55 */
56#ifdef CONFIG_CRASH_DUMP
57#define LOAD_HANDLER(reg, label) \ 56#define LOAD_HANDLER(reg, label) \
58 oris reg,reg,(label)@h; /* virt addr of handler ... */ \ 57 addi reg,reg,(label)-_stext; /* virt addr of handler ... */
59 ori reg,reg,(label)@l; /* .. and the rest */
60#else
61#define LOAD_HANDLER(reg, label) \
62 ori reg,reg,(label)@l; /* virt addr of handler ... */
63#endif
64 58
65#define EXCEPTION_PROLOG_1(area) \ 59#define EXCEPTION_PROLOG_1(area) \
66 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ 60 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
@@ -72,37 +66,12 @@
72 std r9,area+EX_R13(r13); \ 66 std r9,area+EX_R13(r13); \
73 mfcr r9 67 mfcr r9
74 68
75/*
76 * Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode.
77 * The firmware calls the registered system_reset_fwnmi and
78 * machine_check_fwnmi handlers in 32bit mode if the cpu happens to run
79 * a 32bit application at the time of the event.
80 * This firmware bug is present on POWER4 and JS20.
81 */
82#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label) \
83 EXCEPTION_PROLOG_1(area); \
84 clrrdi r12,r13,32; /* get high part of &label */ \
85 mfmsr r10; \
86 /* force 64bit mode */ \
87 li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \
88 rldimi r10,r11,61,0; /* insert into top 3 bits */ \
89 /* done 64bit mode */ \
90 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
91 LOAD_HANDLER(r12,label) \
92 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
93 mtspr SPRN_SRR0,r12; \
94 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
95 mtspr SPRN_SRR1,r10; \
96 rfid; \
97 b . /* prevent speculative execution */
98
99#define EXCEPTION_PROLOG_PSERIES(area, label) \ 69#define EXCEPTION_PROLOG_PSERIES(area, label) \
100 EXCEPTION_PROLOG_1(area); \ 70 EXCEPTION_PROLOG_1(area); \
101 clrrdi r12,r13,32; /* get high part of &label */ \ 71 ld r12,PACAKBASE(r13); /* get high part of &label */ \
102 mfmsr r10; \ 72 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
103 mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 73 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
104 LOAD_HANDLER(r12,label) \ 74 LOAD_HANDLER(r12,label) \
105 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
106 mtspr SPRN_SRR0,r12; \ 75 mtspr SPRN_SRR0,r12; \
107 mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 76 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
108 mtspr SPRN_SRR1,r10; \ 77 mtspr SPRN_SRR1,r10; \
@@ -210,11 +179,10 @@ label##_pSeries: \
210 std r10,PACA_EXGEN+EX_R13(r13); \ 179 std r10,PACA_EXGEN+EX_R13(r13); \
211 std r11,PACA_EXGEN+EX_R11(r13); \ 180 std r11,PACA_EXGEN+EX_R11(r13); \
212 std r12,PACA_EXGEN+EX_R12(r13); \ 181 std r12,PACA_EXGEN+EX_R12(r13); \
213 clrrdi r12,r13,32; /* get high part of &label */ \ 182 ld r12,PACAKBASE(r13); /* get high part of &label */ \
214 mfmsr r10; \ 183 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
215 mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 184 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
216 LOAD_HANDLER(r12,label##_common) \ 185 LOAD_HANDLER(r12,label##_common) \
217 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
218 mtspr SPRN_SRR0,r12; \ 186 mtspr SPRN_SRR0,r12; \
219 mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 187 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
220 mtspr SPRN_SRR1,r10; \ 188 mtspr SPRN_SRR1,r10; \
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 6493a395508b..082b3aedf145 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -62,6 +62,8 @@ struct paca_struct {
62 u16 paca_index; /* Logical processor number */ 62 u16 paca_index; /* Logical processor number */
63 63
64 u64 kernel_toc; /* Kernel TOC address */ 64 u64 kernel_toc; /* Kernel TOC address */
65 u64 kernelbase; /* Base address of kernel */
66 u64 kernel_msr; /* MSR while running in kernel */
65 u64 stab_real; /* Absolute address of segment table */ 67 u64 stab_real; /* Absolute address of segment table */
66 u64 stab_addr; /* Virtual address of segment table */ 68 u64 stab_addr; /* Virtual address of segment table */
67 void *emergency_sp; /* pointer to emergency stack */ 69 void *emergency_sp; /* pointer to emergency stack */