[PATCH] powerpc: Create a trampoline for the fwnmi vectors
authorMichael Ellerman <michael@ellerman.id.au>
Sun, 4 Dec 2005 07:39:33 +0000 (18:39 +1100)
committerPaul Mackerras <paulus@samba.org>
Mon, 9 Jan 2006 03:52:17 +0000 (14:52 +1100)
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>
arch/powerpc/kernel/head_64.S
arch/powerpc/platforms/pseries/ras.c
arch/powerpc/platforms/pseries/setup.c
include/asm-powerpc/firmware.h

index 65aedc938a6ea7ed93b8d2d45e4b4ab213311390..f4194f5fd2e5d5fa3376b6f0f5000a4f9ca7661d 100644 (file)
@@ -553,6 +553,7 @@ slb_miss_user_pseries:
  * Vectors for the FWNMI option.  Share common code.
  */
        .globl system_reset_fwnmi
+      .align 7
 system_reset_fwnmi:
        HMT_MEDIUM
        mtspr   SPRN_SPRG1,r13          /* save r13 */
@@ -560,6 +561,7 @@ system_reset_fwnmi:
        EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
 
        .globl machine_check_fwnmi
+      .align 7
 machine_check_fwnmi:
        HMT_MEDIUM
        mtspr   SPRN_SPRG1,r13          /* save r13 */
index fbd214d68b0717573ed443632bde26d055038345..49b305f9c152bcb940132ee5a18b2a19128980e6 100644 (file)
 #include <asm/machdep.h>
 #include <asm/rtas.h>
 #include <asm/udbg.h>
+#include <asm/firmware.h>
 
 static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
 static DEFINE_SPINLOCK(ras_log_buf_lock);
 
-char mce_data_buf[RTAS_ERROR_LOG_MAX]
-;
-/* This is true if we are using the firmware NMI handler (typically LPAR) */
-extern int fwnmi_active;
+char mce_data_buf[RTAS_ERROR_LOG_MAX];
 
 static int ras_get_sensor_state_token;
 static int ras_check_exception_token;
index 8828dc378c3e7b770e3e308659fca6cbad2cc6fb..d678f228fc0fb0dca2bcfd44a498268da648d3d9 100644 (file)
@@ -77,8 +77,6 @@
 #endif
 
 extern void find_udbg_vterm(void);
-extern void system_reset_fwnmi(void);  /* from head.S */
-extern void machine_check_fwnmi(void); /* from head.S */
 
 int fwnmi_active;  /* TRUE if an FWNMI handler is present */
 
@@ -104,18 +102,22 @@ void pSeries_show_cpuinfo(struct seq_file *m)
 
 /* Initialize firmware assisted non-maskable interrupts if
  * the firmware supports this feature.
- *
  */
 static void __init fwnmi_init(void)
 {
-       int ret;
+       unsigned long system_reset_addr, machine_check_addr;
+
        int ibm_nmi_register = rtas_token("ibm,nmi-register");
        if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
                return;
-       ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
-                       __pa((unsigned long)system_reset_fwnmi),
-                       __pa((unsigned long)machine_check_fwnmi));
-       if (ret == 0)
+
+       /* If the kernel's not linked at zero we point the firmware at low
+        * addresses anyway, and use a trampoline to get to the real code. */
+       system_reset_addr  = __pa(system_reset_fwnmi) - PHYSICAL_START;
+       machine_check_addr = __pa(machine_check_fwnmi) - PHYSICAL_START;
+
+       if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr,
+                               machine_check_addr))
                fwnmi_active = 1;
 }
 
index 12fabbcb04f04a7bcb7ec248c39fdbeedb0ea915..f804b34cf06a6f63136955e315407a456107ce44 100644 (file)
@@ -98,6 +98,12 @@ typedef struct {
 extern firmware_feature_t firmware_features_table[];
 #endif
 
+extern void system_reset_fwnmi(void);
+extern void machine_check_fwnmi(void);
+
+/* This is true if we are using the firmware NMI handler (typically LPAR) */
+extern int fwnmi_active;
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_FIRMWARE_H */