aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-12-04 02:39:33 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:52:17 -0500
commit8c4f1f2958ff9d4a6760f3bdd0cfb7d2b9e12093 (patch)
tree3616f75215bc397725cd86708862d358d2e10d4c
parent398ab1fcb960ea0800f40a9c36355855e3e23389 (diff)
[PATCH] powerpc: Create a trampoline for the fwnmi vectors
The fwnmi vectors can be anywhere < 32 MB, so we need to use a trampoline for them. The kdump kernel will register the trampoline addresses, which will then jump up to the real code above 32 MB. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/head_64.S2
-rw-r--r--arch/powerpc/platforms/pseries/ras.c6
-rw-r--r--arch/powerpc/platforms/pseries/setup.c18
-rw-r--r--include/asm-powerpc/firmware.h6
4 files changed, 20 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 65aedc938a6e..f4194f5fd2e5 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -553,6 +553,7 @@ slb_miss_user_pseries:
553 * Vectors for the FWNMI option. Share common code. 553 * Vectors for the FWNMI option. Share common code.
554 */ 554 */
555 .globl system_reset_fwnmi 555 .globl system_reset_fwnmi
556 .align 7
556system_reset_fwnmi: 557system_reset_fwnmi:
557 HMT_MEDIUM 558 HMT_MEDIUM
558 mtspr SPRN_SPRG1,r13 /* save r13 */ 559 mtspr SPRN_SPRG1,r13 /* save r13 */
@@ -560,6 +561,7 @@ system_reset_fwnmi:
560 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) 561 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
561 562
562 .globl machine_check_fwnmi 563 .globl machine_check_fwnmi
564 .align 7
563machine_check_fwnmi: 565machine_check_fwnmi:
564 HMT_MEDIUM 566 HMT_MEDIUM
565 mtspr SPRN_SPRG1,r13 /* save r13 */ 567 mtspr SPRN_SPRG1,r13 /* save r13 */
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index fbd214d68b07..49b305f9c152 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -49,14 +49,12 @@
49#include <asm/machdep.h> 49#include <asm/machdep.h>
50#include <asm/rtas.h> 50#include <asm/rtas.h>
51#include <asm/udbg.h> 51#include <asm/udbg.h>
52#include <asm/firmware.h>
52 53
53static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; 54static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
54static DEFINE_SPINLOCK(ras_log_buf_lock); 55static DEFINE_SPINLOCK(ras_log_buf_lock);
55 56
56char mce_data_buf[RTAS_ERROR_LOG_MAX] 57char mce_data_buf[RTAS_ERROR_LOG_MAX];
57;
58/* This is true if we are using the firmware NMI handler (typically LPAR) */
59extern int fwnmi_active;
60 58
61static int ras_get_sensor_state_token; 59static int ras_get_sensor_state_token;
62static int ras_check_exception_token; 60static int ras_check_exception_token;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8828dc378c3e..d678f228fc0f 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -77,8 +77,6 @@
77#endif 77#endif
78 78
79extern void find_udbg_vterm(void); 79extern void find_udbg_vterm(void);
80extern void system_reset_fwnmi(void); /* from head.S */
81extern void machine_check_fwnmi(void); /* from head.S */
82 80
83int fwnmi_active; /* TRUE if an FWNMI handler is present */ 81int fwnmi_active; /* TRUE if an FWNMI handler is present */
84 82
@@ -104,18 +102,22 @@ void pSeries_show_cpuinfo(struct seq_file *m)
104 102
105/* Initialize firmware assisted non-maskable interrupts if 103/* Initialize firmware assisted non-maskable interrupts if
106 * the firmware supports this feature. 104 * the firmware supports this feature.
107 *
108 */ 105 */
109static void __init fwnmi_init(void) 106static void __init fwnmi_init(void)
110{ 107{
111 int ret; 108 unsigned long system_reset_addr, machine_check_addr;
109
112 int ibm_nmi_register = rtas_token("ibm,nmi-register"); 110 int ibm_nmi_register = rtas_token("ibm,nmi-register");
113 if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) 111 if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
114 return; 112 return;
115 ret = rtas_call(ibm_nmi_register, 2, 1, NULL, 113
116 __pa((unsigned long)system_reset_fwnmi), 114 /* If the kernel's not linked at zero we point the firmware at low
117 __pa((unsigned long)machine_check_fwnmi)); 115 * addresses anyway, and use a trampoline to get to the real code. */
118 if (ret == 0) 116 system_reset_addr = __pa(system_reset_fwnmi) - PHYSICAL_START;
117 machine_check_addr = __pa(machine_check_fwnmi) - PHYSICAL_START;
118
119 if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr,
120 machine_check_addr))
119 fwnmi_active = 1; 121 fwnmi_active = 1;
120} 122}
121 123
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index 12fabbcb04f0..f804b34cf06a 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -98,6 +98,12 @@ typedef struct {
98extern firmware_feature_t firmware_features_table[]; 98extern firmware_feature_t firmware_features_table[];
99#endif 99#endif
100 100
101extern void system_reset_fwnmi(void);
102extern void machine_check_fwnmi(void);
103
104/* This is true if we are using the firmware NMI handler (typically LPAR) */
105extern int fwnmi_active;
106
101#endif /* __ASSEMBLY__ */ 107#endif /* __ASSEMBLY__ */
102#endif /* __KERNEL__ */ 108#endif /* __KERNEL__ */
103#endif /* __ASM_POWERPC_FIRMWARE_H */ 109#endif /* __ASM_POWERPC_FIRMWARE_H */