diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-12-04 02:39:33 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 22:52:17 -0500 |
commit | 8c4f1f2958ff9d4a6760f3bdd0cfb7d2b9e12093 (patch) | |
tree | 3616f75215bc397725cd86708862d358d2e10d4c | |
parent | 398ab1fcb960ea0800f40a9c36355855e3e23389 (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.S | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/ras.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 18 | ||||
-rw-r--r-- | include/asm-powerpc/firmware.h | 6 |
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 | ||
556 | system_reset_fwnmi: | 557 | system_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 | ||
563 | machine_check_fwnmi: | 565 | machine_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 | ||
53 | static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; | 54 | static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; |
54 | static DEFINE_SPINLOCK(ras_log_buf_lock); | 55 | static DEFINE_SPINLOCK(ras_log_buf_lock); |
55 | 56 | ||
56 | char mce_data_buf[RTAS_ERROR_LOG_MAX] | 57 | char mce_data_buf[RTAS_ERROR_LOG_MAX]; |
57 | ; | ||
58 | /* This is true if we are using the firmware NMI handler (typically LPAR) */ | ||
59 | extern int fwnmi_active; | ||
60 | 58 | ||
61 | static int ras_get_sensor_state_token; | 59 | static int ras_get_sensor_state_token; |
62 | static int ras_check_exception_token; | 60 | static 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 | ||
79 | extern void find_udbg_vterm(void); | 79 | extern void find_udbg_vterm(void); |
80 | extern void system_reset_fwnmi(void); /* from head.S */ | ||
81 | extern void machine_check_fwnmi(void); /* from head.S */ | ||
82 | 80 | ||
83 | int fwnmi_active; /* TRUE if an FWNMI handler is present */ | 81 | int 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 | */ |
109 | static void __init fwnmi_init(void) | 106 | static 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 { | |||
98 | extern firmware_feature_t firmware_features_table[]; | 98 | extern firmware_feature_t firmware_features_table[]; |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | extern void system_reset_fwnmi(void); | ||
102 | extern void machine_check_fwnmi(void); | ||
103 | |||
104 | /* This is true if we are using the firmware NMI handler (typically LPAR) */ | ||
105 | extern 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 */ |